From: David Malcolm Date: Mon, 19 Nov 2018 16:31:03 +0000 (+0000) Subject: Eliminate global state from -fsave-optimization-record X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=8d1af516844f94784d9a3a7ffc59f9ab3daa1f5d;p=gcc.git Eliminate global state from -fsave-optimization-record As work towards fixing PR tree-optimization/87025, this patch eliminates global state from optinfo-emit-json.cc in favor of adding an optional m_json_writer field to dump_context, replacing the m_forcibly_enable_optinfo flag. This allows for writing selftests for the interaction of the JSON-building code with the dumpfile.c code. In particular, the existing selftest that created optinfo instances now exercise the JSON-building code (although no JSON is actually written out). The patch also simplifies the layering by replacing optinfo::emit () with dump_context::emit_optinfo, so that dump_context has responsibility for keeping track of dump destinations. gcc/ChangeLog: PR tree-optimization/87025 * dump-context.h: Include "optinfo.h". (class optrecord_json_writer): New forward decl. (dump_context::forcibly_enable_optinfo_p): Delete. (dump_context::optinfo_enabled_p): New member function. (dump_context::optimization_records_enabled_p): New member function. (dump_context::set_json_writer): New member function. (dump_context::emit_optinfo): New member function. (dump_context::m_forcibly_enable_optinfo): Delete. (dump_context::m_json_writer): New member data. * dumpfile.c (dump_context::set_json_writer): New member function. (dump_context::finish_any_json_writer): New member function. (dump_context::end_scope): Replace call to optimization_records_maybe_pop_dump_scope with call to m_json_writer->pop_scope. (dump_context::optinfo_enabled_p): New member function. (dump_context::end_any_optinfo): Replace call to optinfo::emit with call to dump_context::emit_optinfo. (dump_context::emit_optinfo): New member function. (temp_dump_context::temp_dump_context): Replace m_forcibly_enable_optinfo with call to set_json_writer. (temp_dump_context::~temp_dump_context): Clean up any json writer. * optinfo-emit-json.cc (class optrecord_json_writer): Move to optinfo-emit-json.h (the_json_writer): Delete. (optimization_records_start): Delete. (optimization_records_finish): Delete. (optimization_records_enabled_p): Delete, in favor of dump_context::optimization_records_enabled_p. (optimization_records_maybe_record_optinfo): Delete. (optimization_records_maybe_pop_dump_scope): Delete. * optinfo-emit-json.h: Include "json.h". Delete forward decl of opt_pass. (optimization_records_start): Delete. (optimization_records_finish): Delete. (optimization_records_enabled_p): Delete. (optimization_records_maybe_record_optinfo): Delete. (optimization_records_maybe_pop_dump_scope): Delete. (class optrecord_json_writer): Move here from optinfo-emit-json.cc. * optinfo.cc (optinfo::emit_for_opt_problem): Replace call to optinfo::emit with call to dump_context::emit_optinfo. (optinfo::emit): Delete, in favor of dump_context::emit_optinfo. (optinfo_enabled_p): Delete, in favor of dump_context::optinfo_enabled_p. (optinfo_wants_inlining_info_p): Update for conversion o optimization_records_enabled_p to a member function of dump_context. * optinfo.h (optinfo_enabled_p): Delete, in favor of dump_context::optinfo_enabled_p. (optinfo::emit): Delete, in favor of dump_context::emit_optinfo. * toplev.c: Include "dump-context.h". (compile_file): Replace call to optimization_records_finish with dump_context::finish_any_json_writer. (do_compile): Replace call to optimization_records_start with conditionally creating a optrecord_json_writer for the dump_context. From-SVN: r266279 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d7db678d60d..28fb034ab56 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,64 @@ +2018-11-19 David Malcolm + + PR tree-optimization/87025 + * dump-context.h: Include "optinfo.h". + (class optrecord_json_writer): New forward decl. + (dump_context::forcibly_enable_optinfo_p): Delete. + (dump_context::optinfo_enabled_p): New member function. + (dump_context::optimization_records_enabled_p): New member + function. + (dump_context::set_json_writer): New member function. + (dump_context::emit_optinfo): New member function. + (dump_context::m_forcibly_enable_optinfo): Delete. + (dump_context::m_json_writer): New member data. + * dumpfile.c (dump_context::set_json_writer): New member function. + (dump_context::finish_any_json_writer): New member function. + (dump_context::end_scope): Replace call to + optimization_records_maybe_pop_dump_scope with call to + m_json_writer->pop_scope. + (dump_context::optinfo_enabled_p): New member function. + (dump_context::end_any_optinfo): Replace call to optinfo::emit with call + to dump_context::emit_optinfo. + (dump_context::emit_optinfo): New member function. + (temp_dump_context::temp_dump_context): Replace + m_forcibly_enable_optinfo with call to set_json_writer. + (temp_dump_context::~temp_dump_context): Clean up any json writer. + * optinfo-emit-json.cc (class optrecord_json_writer): Move to + optinfo-emit-json.h + (the_json_writer): Delete. + (optimization_records_start): Delete. + (optimization_records_finish): Delete. + (optimization_records_enabled_p): Delete, in favor of + dump_context::optimization_records_enabled_p. + (optimization_records_maybe_record_optinfo): Delete. + (optimization_records_maybe_pop_dump_scope): Delete. + * optinfo-emit-json.h: Include "json.h". Delete forward + decl of opt_pass. + (optimization_records_start): Delete. + (optimization_records_finish): Delete. + (optimization_records_enabled_p): Delete. + (optimization_records_maybe_record_optinfo): Delete. + (optimization_records_maybe_pop_dump_scope): Delete. + (class optrecord_json_writer): Move here from + optinfo-emit-json.cc. + * optinfo.cc (optinfo::emit_for_opt_problem): Replace call + to optinfo::emit with call to dump_context::emit_optinfo. + (optinfo::emit): Delete, in favor of dump_context::emit_optinfo. + (optinfo_enabled_p): Delete, in favor of + dump_context::optinfo_enabled_p. + (optinfo_wants_inlining_info_p): Update for conversion o + optimization_records_enabled_p to a member function of + dump_context. + * optinfo.h (optinfo_enabled_p): Delete, in favor of + dump_context::optinfo_enabled_p. + (optinfo::emit): Delete, in favor of dump_context::emit_optinfo. + * toplev.c: Include "dump-context.h". + (compile_file): Replace call to optimization_records_finish with + dump_context::finish_any_json_writer. + (do_compile): Replace call to optimization_records_start with + conditionally creating a optrecord_json_writer for the + dump_context. + 2018-11-19 Jakub Jelinek PR tree-optimization/88071 diff --git a/gcc/dump-context.h b/gcc/dump-context.h index ace139cdc09..2016ce700d2 100644 --- a/gcc/dump-context.h +++ b/gcc/dump-context.h @@ -25,7 +25,9 @@ along with GCC; see the file COPYING3. If not see #include "dumpfile.h" #include "pretty-print.h" #include "selftest.h" +#include "optinfo.h" +class optrecord_json_writer; namespace selftest { class temp_dump_context; } /* A class for handling the various dump_* calls. @@ -95,14 +97,21 @@ class dump_context void begin_scope (const char *name, const dump_location_t &loc); void end_scope (); - /* For use in selftests; if true then optinfo_enabled_p is true. */ - bool forcibly_enable_optinfo_p () const + /* Should optinfo instances be created? + All creation of optinfos should be guarded by this predicate. + Return true if any optinfo destinations are active. */ + bool optinfo_enabled_p () const; + + bool optimization_records_enabled_p () const { - return m_forcibly_enable_optinfo; + return m_json_writer != NULL; } + void set_json_writer (optrecord_json_writer *writer); + void finish_any_json_writer (); void end_any_optinfo (); + void emit_optinfo (const optinfo *info); void emit_item (optinfo_item *item, dump_flags_t dump_kind); bool apply_dump_filter_p (dump_flags_t dump_kind, dump_flags_t filter) const; @@ -111,9 +120,6 @@ class dump_context optinfo &ensure_pending_optinfo (); optinfo &begin_next_optinfo (const dump_location_t &loc); - /* For use in selftests; if true then optinfo_enabled_p is true. */ - bool m_forcibly_enable_optinfo; - /* The current nesting depth of dump scopes, for showing nesting via indentation). */ unsigned int m_scope_depth; @@ -122,6 +128,10 @@ class dump_context if any. */ optinfo *m_pending; + /* If -fsave-optimization-record is enabled, the heap-allocated JSON writer + instance, otherwise NULL. */ + optrecord_json_writer *m_json_writer; + /* For use in selftests: if non-NULL, then items are to be printed to this, using the given flags. */ pretty_printer *m_test_pp; diff --git a/gcc/dumpfile.c b/gcc/dumpfile.c index 86651df3aa2..014acf102fc 100644 --- a/gcc/dumpfile.c +++ b/gcc/dumpfile.c @@ -515,6 +515,28 @@ dump_context::~dump_context () delete m_pending; } +void +dump_context::set_json_writer (optrecord_json_writer *writer) +{ + delete m_json_writer; + m_json_writer = writer; +} + +/* Perform cleanup activity for -fsave-optimization-record. + Currently, the file is written out here in one go, before cleaning + up. */ + +void +dump_context::finish_any_json_writer () +{ + if (!m_json_writer) + return; + + m_json_writer->write (); + delete m_json_writer; + m_json_writer = NULL; +} + /* Update the "dumps_are_enabled" global; to be called whenever dump_file or alt_dump_file change, or when changing dump_context in selftests. */ @@ -1121,7 +1143,19 @@ dump_context::end_scope () { end_any_optinfo (); m_scope_depth--; - optimization_records_maybe_pop_dump_scope (); + + if (m_json_writer) + m_json_writer->pop_scope (); +} + +/* Should optinfo instances be created? + All creation of optinfos should be guarded by this predicate. + Return true if any optinfo destinations are active. */ + +bool +dump_context::optinfo_enabled_p () const +{ + return (optimization_records_enabled_p ()); } /* Return the optinfo currently being accumulated, creating one if @@ -1154,11 +1188,23 @@ void dump_context::end_any_optinfo () { if (m_pending) - m_pending->emit (); + emit_optinfo (m_pending); delete m_pending; m_pending = NULL; } +/* Emit the optinfo to all of the "non-immediate" destinations + (emission to "immediate" destinations is done by + dump_context::emit_item). */ + +void +dump_context::emit_optinfo (const optinfo *info) +{ + /* -fsave-optimization-record. */ + if (m_json_writer) + m_json_writer->add_record (info); +} + /* Emit ITEM to all item destinations (those that don't require consolidation into optinfo instances). */ @@ -2004,7 +2050,8 @@ temp_dump_context::temp_dump_context (bool forcibly_enable_optinfo, m_saved (&dump_context ().get ()) { dump_context::s_current = &m_context; - m_context.m_forcibly_enable_optinfo = forcibly_enable_optinfo; + if (forcibly_enable_optinfo) + m_context.set_json_writer (new optrecord_json_writer ()); /* Conditionally enable the test dump, so that we can verify both the dump_enabled_p and the !dump_enabled_p cases in selftests. */ if (forcibly_enable_dumping) @@ -2020,6 +2067,8 @@ temp_dump_context::temp_dump_context (bool forcibly_enable_optinfo, temp_dump_context::~temp_dump_context () { + m_context.set_json_writer (NULL); + dump_context::s_current = m_saved; dump_context::get ().refresh_dumps_are_enabled (); diff --git a/gcc/optinfo-emit-json.cc b/gcc/optinfo-emit-json.cc index 6d4502c5129..4fa6708600a 100644 --- a/gcc/optinfo-emit-json.cc +++ b/gcc/optinfo-emit-json.cc @@ -47,38 +47,6 @@ along with GCC; see the file COPYING3. If not see #include "dump-context.h" #include -/* A class for writing out optimization records in JSON format. */ - -class optrecord_json_writer -{ -public: - optrecord_json_writer (); - ~optrecord_json_writer (); - void write () const; - void add_record (const optinfo *optinfo); - void pop_scope (); - - void add_record (json::object *obj); - json::object *impl_location_to_json (dump_impl_location_t loc); - json::object *location_to_json (location_t loc); - json::object *profile_count_to_json (profile_count count); - json::string *get_id_value_for_pass (opt_pass *pass); - json::object *pass_to_json (opt_pass *pass); - json::value *inlining_chain_to_json (location_t loc); - json::object *optinfo_to_json (const optinfo *optinfo); - void add_pass_list (json::array *arr, opt_pass *pass); - -private: - /* The root value for the JSON file. - Currently the JSON values are stored in memory, and flushed when the - compiler exits. It would probably be better to simply write out - the JSON as we go. */ - json::array *m_root_tuple; - - /* The currently open scopes, for expressing nested optimization records. */ - auto_vec m_scopes; -}; - /* optrecord_json_writer's ctor. Populate the top-level parts of the in-memory JSON representation. */ @@ -471,75 +439,6 @@ optrecord_json_writer::add_pass_list (json::array *arr, opt_pass *pass) while (pass); } -/* File-level interface to rest of compiler (to avoid exposing - class optrecord_json_writer outside of this file). */ - -static optrecord_json_writer *the_json_writer; - -/* Perform startup activity for -fsave-optimization-record. */ - -void -optimization_records_start () -{ - /* Bail if recording not enabled. */ - if (!flag_save_optimization_record) - return; - - the_json_writer = new optrecord_json_writer (); -} - -/* Perform cleanup activity for -fsave-optimization-record. - - Currently, the file is written out here in one go, before cleaning - up. */ - -void -optimization_records_finish () -{ - /* Bail if recording not enabled. */ - if (!the_json_writer) - return; - - the_json_writer->write (); - - delete the_json_writer; - the_json_writer = NULL; -} - -/* Did the user request optimization records to be written out? */ - -bool -optimization_records_enabled_p () -{ - return the_json_writer != NULL; -} - -/* If optimization records were requested, then add a record for OPTINFO - to the queue of records to be written. */ - -void -optimization_records_maybe_record_optinfo (const optinfo *optinfo) -{ - /* Bail if recording not enabled. */ - if (!the_json_writer) - return; - - the_json_writer->add_record (optinfo); -} - -/* Handling for the end of a dump scope for the - optimization records sink. */ - -void -optimization_records_maybe_pop_dump_scope () -{ - /* Bail if recording not enabled. */ - if (!the_json_writer) - return; - - the_json_writer->pop_scope (); -} - #if CHECKING_P namespace selftest { diff --git a/gcc/optinfo-emit-json.h b/gcc/optinfo-emit-json.h index 3628d56e255..2185c08c1e3 100644 --- a/gcc/optinfo-emit-json.h +++ b/gcc/optinfo-emit-json.h @@ -21,16 +21,40 @@ along with GCC; see the file COPYING3. If not see #ifndef GCC_OPTINFO_EMIT_JSON_H #define GCC_OPTINFO_EMIT_JSON_H -class optinfo; -struct opt_pass; - -extern void optimization_records_start (); -extern void optimization_records_finish (); +#include "json.h" -extern bool optimization_records_enabled_p (); - -extern void optimization_records_maybe_record_optinfo (const optinfo *); -extern void optimization_records_maybe_pop_dump_scope (); +class optinfo; +/* A class for writing out optimization records in JSON format. */ + +class optrecord_json_writer +{ +public: + optrecord_json_writer (); + ~optrecord_json_writer (); + void write () const; + void add_record (const optinfo *optinfo); + void pop_scope (); + + void add_record (json::object *obj); + json::object *impl_location_to_json (dump_impl_location_t loc); + json::object *location_to_json (location_t loc); + json::object *profile_count_to_json (profile_count count); + json::string *get_id_value_for_pass (opt_pass *pass); + json::object *pass_to_json (opt_pass *pass); + json::value *inlining_chain_to_json (location_t loc); + json::object *optinfo_to_json (const optinfo *optinfo); + void add_pass_list (json::array *arr, opt_pass *pass); + + private: + /* The root value for the JSON file. + Currently the JSON values are stored in memory, and flushed when the + compiler exits. It would probably be better to simply write out + the JSON as we go. */ + json::array *m_root_tuple; + + /* The currently open scopes, for expressing nested optimization records. */ + auto_vec m_scopes; +}; #endif /* #ifndef GCC_OPTINFO_EMIT_JSON_H */ diff --git a/gcc/optinfo.cc b/gcc/optinfo.cc index de781a52125..f8e08dee72f 100644 --- a/gcc/optinfo.cc +++ b/gcc/optinfo.cc @@ -125,18 +125,7 @@ optinfo::emit_for_opt_problem () const dump_context::get ().emit_item (item, dump_kind); /* Re-emit to "non-immediate" destinations. */ - emit (); -} - -/* Emit the optinfo to all of the "non-immediate" destinations - (emission to "immediate" destinations is done by - dump_context::emit_item). */ - -void -optinfo::emit () const -{ - /* -fsave-optimization-record. */ - optimization_records_maybe_record_optinfo (this); + dump_context::get ().emit_optinfo (this); } /* Update the optinfo's kind based on DUMP_KIND. */ @@ -152,21 +141,11 @@ optinfo::handle_dump_file_kind (dump_flags_t dump_kind) m_kind = OPTINFO_KIND_NOTE; } -/* Should optinfo instances be created? - All creation of optinfos should be guarded by this predicate. - Return true if any optinfo destinations are active. */ - -bool optinfo_enabled_p () -{ - return (dump_context::get ().forcibly_enable_optinfo_p () - || optimization_records_enabled_p ()); -} - /* Return true if any of the active optinfo destinations make use of inlining information. (if true, then the information is preserved). */ bool optinfo_wants_inlining_info_p () { - return optimization_records_enabled_p (); + return dump_context::get ().optimization_records_enabled_p (); } diff --git a/gcc/optinfo.h b/gcc/optinfo.h index 99bd22c7538..4a678ff0aa6 100644 --- a/gcc/optinfo.h +++ b/gcc/optinfo.h @@ -68,12 +68,6 @@ along with GCC; see the file COPYING3. If not see struct opt_pass; class optinfo_item; -/* Should optinfo instances be created? - All creation of optinfos should be guarded by this predicate. - Return true if any optinfo destinations are active. */ - -extern bool optinfo_enabled_p (); - /* Return true if any of the active optinfo destinations make use of inlining information. (if true, then the information is preserved). */ @@ -130,8 +124,6 @@ class optinfo void emit_for_opt_problem () const; private: - void emit () const; - /* Pre-canned ways of manipulating the optinfo, for use by friend class dump_context. */ void handle_dump_file_kind (dump_flags_t); diff --git a/gcc/toplev.c b/gcc/toplev.c index 3fd4ec4565a..ab20cd98969 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -83,6 +83,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-pass.h" #include "dumpfile.h" #include "ipa-fnsummary.h" +#include "dump-context.h" #include "optinfo-emit-json.h" #if defined(DBX_DEBUGGING_INFO) || defined(XCOFF_DEBUGGING_INFO) @@ -488,7 +489,7 @@ compile_file (void) if (lang_hooks.decls.post_compilation_parsing_cleanups) lang_hooks.decls.post_compilation_parsing_cleanups (); - optimization_records_finish (); + dump_context::get ().finish_any_json_writer (); if (seen_error ()) return; @@ -2131,7 +2132,10 @@ do_compile () timevar_start (TV_PHASE_SETUP); - optimization_records_start (); + if (flag_save_optimization_record) + { + dump_context::get ().set_json_writer (new optrecord_json_writer ()); + } /* This must be run always, because it is needed to compute the FP predefined macros, such as __LDBL_MAX__, for targets using non