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
This commit is contained in:
parent
4fea820523
commit
8d1af51684
|
@ -1,3 +1,64 @@
|
|||
2018-11-19 David Malcolm <dmalcolm@redhat.com>
|
||||
|
||||
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 <jakub@redhat.com>
|
||||
|
||||
PR tree-optimization/88071
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 ();
|
||||
|
|
|
@ -47,38 +47,6 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "dump-context.h"
|
||||
#include <zlib.h>
|
||||
|
||||
/* 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<json::array *> 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 {
|
||||
|
|
|
@ -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
|
||||
|
||||
#include "json.h"
|
||||
|
||||
class optinfo;
|
||||
struct opt_pass;
|
||||
|
||||
extern void optimization_records_start ();
|
||||
extern void optimization_records_finish ();
|
||||
/* A class for writing out optimization records in JSON format. */
|
||||
|
||||
extern bool optimization_records_enabled_p ();
|
||||
class optrecord_json_writer
|
||||
{
|
||||
public:
|
||||
optrecord_json_writer ();
|
||||
~optrecord_json_writer ();
|
||||
void write () const;
|
||||
void add_record (const optinfo *optinfo);
|
||||
void pop_scope ();
|
||||
|
||||
extern void optimization_records_maybe_record_optinfo (const optinfo *);
|
||||
extern void optimization_records_maybe_pop_dump_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<json::array *> m_scopes;
|
||||
};
|
||||
|
||||
#endif /* #ifndef GCC_OPTINFO_EMIT_JSON_H */
|
||||
|
|
|
@ -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 ();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue