Commit 3edf64aa by David Malcolm Committed by David Malcolm

State cleanups from jit branch

gcc/ChangeLog:
	* cgraph.c (cgraph_c_finalize): New function.
	* cgraph.h (cgraph_c_finalize): New prototype.
	(cgraphunit_c_finalize): New prototype.
	* cgraphunit.c (first_analyzed): Move from analyze_functions
	to file-scope.
	(first_analyzed_var): Likewise.
	(analyze_functions): Move static variables into file-scope.
	(cgraphunit_c_finalize): New function.
	* diagnostic.c (diagnostic_finish): Free the memory for
	context->classify_diagnostic and context->printer, running the
	destructor for the latter.
	(bt_stop): Use toplev::main.
	* dwarf2out.c (dwarf2out_finalize): New function.
	* dwarf2out.h (dwarf2out_c_finalize): New prototype.
	* gcse.c (gcse_c_finalize): New function.
	* gcse.h (gcse_c_finalize): New prototype.
	* ggc-page.c (init_ggc): Make idempotent.
	* input.c (input_location): Initialize to UNKNOWN_LOCATION.
	* ipa-cp.c (ipa_cp_c_finalize): New function.
	* ipa-prop.h (ipa_cp_c_finalize): New prototype.
	* ipa-pure-const.c (function_insertion_hook_holder): Move to be
	a field of class pass_ipa_pure_const.
	(node_duplication_hook_holder): Likewise.
	(node_removal_hook_holder): Likewise.
	(register_hooks): Convert to method...
	(pass_ipa_pure_const::register_hooks): ...here, converting
	static variable init_p into...
	(pass_ipa_pure_const::init_p): ...new field.
	(pure_const_generate_summary): Update invocation of
	register_hooks to invoke as a method of current_pass.
	(pure_const_read_summary): Likewise.
	(propagate): Convert to...
	(pass_ipa_pure_const::execute): ...method.
	* ipa-reference.c (ipa_init): Move static bool init_p from here
	to...
	(ipa_init_p): New file-scope variable, so that it can be reset
	when repeatedly invoking the compiler within one process by...
	(ipa_reference_c_finalize): New function.
	* ipa-reference.h (ipa_reference_c_finalize): New.
	* main.c (main): Replace invocation of toplev_main with
	construction of a toplev instance, and call its "main" method.
	* params.c (global_init_params): Add an assert that
	params_finished is false.
	(params_c_finalize): New.
	* params.h (params_c_finalize): New.
	* passes.c (execute_ipa_summary_passes): Set "current_pass" before
	invoking generate_summary, for the benefit of pass_ipa_pure_const.
	(ipa_write_summaries_2): Assign "pass" to "current_pass" global
	before calling write_summary hook.
	(ipa_write_optimization_summaries_1): Likewise when calling
	write_optimization_summary hook.
	(ipa_read_summaries_1): Likewise for read_summary hook.
	(ipa_read_optimization_summaries_1): Likewise for
	read_optimization_summary hook.
	(execute_ipa_stmt_fixups): Likewise.
	* stringpool.c (init_stringpool): Clean up if we're called more
	than once.
	* timevar.c (timevar_init): Ignore repeated calls.
	* toplev.c: Include "dwarf2out.h", "ipa-reference.h", "gcse.h",
	"ipa-prop.h".
	(general_init): Reset "input_location" to UNKNOWN_LOCATION.
	(initialize_rtl): Move static local "initialized_once"
	into file scope, and rename to...
	(rtl_initialized): New variable.
	(do_compile): Move timevar initialization from here to
	toplev::start_timevars.
	(toplev::toplev, toplev::~toplev, toplev::start_timevars,
	toplev::finalize): New functions.
	(toplev_main): Rename to...
	(toplev::main): ...this.
	* toplev.h (class toplev): New class.

From-SVN: r216522
parent 50684f95
2014-10-21 David Malcolm <dmalcolm@redhat.com>
* cgraph.c (cgraph_c_finalize): New function.
* cgraph.h (cgraph_c_finalize): New prototype.
(cgraphunit_c_finalize): New prototype.
* cgraphunit.c (first_analyzed): Move from analyze_functions
to file-scope.
(first_analyzed_var): Likewise.
(analyze_functions): Move static variables into file-scope.
(cgraphunit_c_finalize): New function.
* diagnostic.c (diagnostic_finish): Free the memory for
context->classify_diagnostic and context->printer, running the
destructor for the latter.
(bt_stop): Use toplev::main.
* dwarf2out.c (dwarf2out_finalize): New function.
* dwarf2out.h (dwarf2out_c_finalize): New prototype.
* gcse.c (gcse_c_finalize): New function.
* gcse.h (gcse_c_finalize): New prototype.
* ggc-page.c (init_ggc): Make idempotent.
* input.c (input_location): Initialize to UNKNOWN_LOCATION.
* ipa-cp.c (ipa_cp_c_finalize): New function.
* ipa-prop.h (ipa_cp_c_finalize): New prototype.
* ipa-pure-const.c (function_insertion_hook_holder): Move to be
a field of class pass_ipa_pure_const.
(node_duplication_hook_holder): Likewise.
(node_removal_hook_holder): Likewise.
(register_hooks): Convert to method...
(pass_ipa_pure_const::register_hooks): ...here, converting
static variable init_p into...
(pass_ipa_pure_const::init_p): ...new field.
(pure_const_generate_summary): Update invocation of
register_hooks to invoke as a method of current_pass.
(pure_const_read_summary): Likewise.
(propagate): Convert to...
(pass_ipa_pure_const::execute): ...method.
* ipa-reference.c (ipa_init): Move static bool init_p from here
to...
(ipa_init_p): New file-scope variable, so that it can be reset
when repeatedly invoking the compiler within one process by...
(ipa_reference_c_finalize): New function.
* ipa-reference.h (ipa_reference_c_finalize): New.
* main.c (main): Replace invocation of toplev_main with
construction of a toplev instance, and call its "main" method.
* params.c (global_init_params): Add an assert that
params_finished is false.
(params_c_finalize): New.
* params.h (params_c_finalize): New.
* passes.c (execute_ipa_summary_passes): Set "current_pass" before
invoking generate_summary, for the benefit of pass_ipa_pure_const.
(ipa_write_summaries_2): Assign "pass" to "current_pass" global
before calling write_summary hook.
(ipa_write_optimization_summaries_1): Likewise when calling
write_optimization_summary hook.
(ipa_read_summaries_1): Likewise for read_summary hook.
(ipa_read_optimization_summaries_1): Likewise for
read_optimization_summary hook.
(execute_ipa_stmt_fixups): Likewise.
* stringpool.c (init_stringpool): Clean up if we're called more
than once.
* timevar.c (timevar_init): Ignore repeated calls.
* toplev.c: Include "dwarf2out.h", "ipa-reference.h", "gcse.h",
"ipa-prop.h".
(general_init): Reset "input_location" to UNKNOWN_LOCATION.
(initialize_rtl): Move static local "initialized_once"
into file scope, and rename to...
(rtl_initialized): New variable.
(do_compile): Move timevar initialization from here to
toplev::start_timevars.
(toplev::toplev, toplev::~toplev, toplev::start_timevars,
toplev::finalize): New functions.
(toplev_main): Rename to...
(toplev::main): ...this.
* toplev.h (class toplev): New class.
2014-10-21 Andrew MacLeod <amacleod@redhat.com> 2014-10-21 Andrew MacLeod <amacleod@redhat.com>
* loop-doloop.c: Include loop-unroll.h. * loop-doloop.c: Include loop-unroll.h.
...@@ -3097,4 +3097,18 @@ gimple_check_call_matching_types (gimple call_stmt, tree callee, ...@@ -3097,4 +3097,18 @@ gimple_check_call_matching_types (gimple call_stmt, tree callee,
return true; return true;
} }
/* Reset all state within cgraph.c so that we can rerun the compiler
within the same process. For use by toplev::finalize. */
void
cgraph_c_finalize (void)
{
symtab = NULL;
x_cgraph_nodes_queue = NULL;
cgraph_fnver_htab = NULL;
version_info_node = NULL;
}
#include "gt-cgraph.h" #include "gt-cgraph.h"
...@@ -2108,6 +2108,7 @@ asmname_hasher::pch_nx (symtab_node *&n, gt_pointer_operator op, void *cookie) ...@@ -2108,6 +2108,7 @@ asmname_hasher::pch_nx (symtab_node *&n, gt_pointer_operator op, void *cookie)
} }
/* In cgraph.c */ /* In cgraph.c */
void cgraph_c_finalize (void);
void release_function_body (tree); void release_function_body (tree);
cgraph_indirect_call_info *cgraph_allocate_init_indirect_info (void); cgraph_indirect_call_info *cgraph_allocate_init_indirect_info (void);
...@@ -2121,6 +2122,8 @@ bool resolution_used_from_other_file_p (enum ld_plugin_symbol_resolution); ...@@ -2121,6 +2122,8 @@ bool resolution_used_from_other_file_p (enum ld_plugin_symbol_resolution);
extern bool gimple_check_call_matching_types (gimple, tree, bool); extern bool gimple_check_call_matching_types (gimple, tree, bool);
/* In cgraphunit.c */ /* In cgraphunit.c */
void cgraphunit_c_finalize (void);
/* Initialize datastructures so DECL is a function in lowered gimple form. /* Initialize datastructures so DECL is a function in lowered gimple form.
IN_SSA is true if the gimple is in SSA. */ IN_SSA is true if the gimple is in SSA. */
basic_block init_lowered_empty_function (tree, bool); basic_block init_lowered_empty_function (tree, bool);
......
...@@ -884,15 +884,15 @@ walk_polymorphic_call_targets (hash_set<void *> *reachable_call_targets, ...@@ -884,15 +884,15 @@ walk_polymorphic_call_targets (hash_set<void *> *reachable_call_targets,
/* Discover all functions and variables that are trivially needed, analyze /* Discover all functions and variables that are trivially needed, analyze
them as well as all functions and variables referred by them */ them as well as all functions and variables referred by them */
static cgraph_node *first_analyzed;
static varpool_node *first_analyzed_var;
static void static void
analyze_functions (void) analyze_functions (void)
{ {
/* Keep track of already processed nodes when called multiple times for /* Keep track of already processed nodes when called multiple times for
intermodule optimization. */ intermodule optimization. */
static cgraph_node *first_analyzed;
cgraph_node *first_handled = first_analyzed; cgraph_node *first_handled = first_analyzed;
static varpool_node *first_analyzed_var;
varpool_node *first_handled_var = first_analyzed_var; varpool_node *first_handled_var = first_analyzed_var;
hash_set<void *> reachable_call_targets; hash_set<void *> reachable_call_targets;
...@@ -2292,6 +2292,22 @@ symbol_table::finalize_compilation_unit (void) ...@@ -2292,6 +2292,22 @@ symbol_table::finalize_compilation_unit (void)
timevar_pop (TV_CGRAPH); timevar_pop (TV_CGRAPH);
} }
/* Reset all state within cgraphunit.c so that we can rerun the compiler
within the same process. For use by toplev::finalize. */
void
cgraphunit_c_finalize (void)
{
gcc_assert (cgraph_new_nodes.length () == 0);
cgraph_new_nodes.truncate (0);
vtable_entry_type = NULL;
queued_nodes = &symtab_terminator;
first_analyzed = NULL;
first_analyzed_var = NULL;
}
/* Creates a wrapper from cgraph_node to TARGET node. Thunk is used for this /* Creates a wrapper from cgraph_node to TARGET node. Thunk is used for this
kind of wrapper method. */ kind of wrapper method. */
......
...@@ -177,6 +177,15 @@ diagnostic_finish (diagnostic_context *context) ...@@ -177,6 +177,15 @@ diagnostic_finish (diagnostic_context *context)
} }
diagnostic_file_cache_fini (); diagnostic_file_cache_fini ();
XDELETEVEC (context->classify_diagnostic);
context->classify_diagnostic = NULL;
/* diagnostic_initialize allocates context->printer using XNEW
and placement-new. */
context->printer->~pretty_printer ();
XDELETE (context->printer);
context->printer = NULL;
} }
/* Initialize DIAGNOSTIC, where the message MSG has already been /* Initialize DIAGNOSTIC, where the message MSG has already been
...@@ -342,7 +351,7 @@ diagnostic_show_locus (diagnostic_context * context, ...@@ -342,7 +351,7 @@ diagnostic_show_locus (diagnostic_context * context,
static const char * const bt_stop[] = static const char * const bt_stop[] =
{ {
"main", "main",
"toplev_main", "toplev::main",
"execute_one_pass", "execute_one_pass",
"compile_file", "compile_file",
}; };
......
...@@ -24619,4 +24619,90 @@ dwarf2out_finish (const char *filename) ...@@ -24619,4 +24619,90 @@ dwarf2out_finish (const char *filename)
output_indirect_strings (); output_indirect_strings ();
} }
/* Reset all state within dwarf2out.c so that we can rerun the compiler
within the same process. For use by toplev::finalize. */
void
dwarf2out_c_finalize (void)
{
last_var_location_insn = NULL;
cached_next_real_insn = NULL;
used_rtx_array = NULL;
incomplete_types = NULL;
decl_scope_table = NULL;
debug_info_section = NULL;
debug_skeleton_info_section = NULL;
debug_abbrev_section = NULL;
debug_skeleton_abbrev_section = NULL;
debug_aranges_section = NULL;
debug_addr_section = NULL;
debug_macinfo_section = NULL;
debug_line_section = NULL;
debug_skeleton_line_section = NULL;
debug_loc_section = NULL;
debug_pubnames_section = NULL;
debug_pubtypes_section = NULL;
debug_str_section = NULL;
debug_str_dwo_section = NULL;
debug_str_offsets_section = NULL;
debug_ranges_section = NULL;
debug_frame_section = NULL;
fde_vec = NULL;
debug_str_hash = NULL;
skeleton_debug_str_hash = NULL;
dw2_string_counter = 0;
have_multiple_function_sections = false;
text_section_used = false;
cold_text_section_used = false;
cold_text_section = NULL;
current_unit_personality = NULL;
deferred_locations_list = NULL;
next_die_offset = 0;
single_comp_unit_die = NULL;
comdat_type_list = NULL;
limbo_die_list = NULL;
deferred_asm_name = NULL;
file_table = NULL;
decl_die_table = NULL;
common_block_die_table = NULL;
decl_loc_table = NULL;
call_arg_locations = NULL;
call_arg_loc_last = NULL;
call_site_count = -1;
tail_call_site_count = -1;
//block_map = NULL;
cached_dw_loc_list_table = NULL;
abbrev_die_table = NULL;
abbrev_die_table_allocated = 0;
abbrev_die_table_in_use = 0;
line_info_label_num = 0;
cur_line_info_table = NULL;
text_section_line_info = NULL;
cold_text_section_line_info = NULL;
separate_line_info = NULL;
info_section_emitted = false;
pubname_table = NULL;
pubtype_table = NULL;
macinfo_table = NULL;
ranges_table = NULL;
ranges_table_allocated = 0;
ranges_table_in_use = 0;
ranges_by_label = 0;
ranges_by_label_allocated = 0;
ranges_by_label_in_use = 0;
have_location_lists = false;
loclabel_num = 0;
poc_label_num = 0;
last_emitted_file = NULL;
label_num = 0;
file_table_last_lookup = NULL;
tmpl_value_parm_die_table = NULL;
generic_type_instances = NULL;
frame_pointer_fb_offset = 0;
frame_pointer_fb_offset_valid = false;
base_types.release ();
}
#include "gt-dwarf2out.h" #include "gt-dwarf2out.h"
...@@ -277,4 +277,6 @@ struct array_descr_info ...@@ -277,4 +277,6 @@ struct array_descr_info
} dimen[10]; } dimen[10];
}; };
void dwarf2out_c_finalize (void);
#endif /* GCC_DWARF2OUT_H */ #endif /* GCC_DWARF2OUT_H */
...@@ -4293,4 +4293,13 @@ make_pass_rtl_hoist (gcc::context *ctxt) ...@@ -4293,4 +4293,13 @@ make_pass_rtl_hoist (gcc::context *ctxt)
return new pass_rtl_hoist (ctxt); return new pass_rtl_hoist (ctxt);
} }
/* Reset all state within gcse.c so that we can rerun the compiler
within the same process. For use by toplev::finalize. */
void
gcse_c_finalize (void)
{
test_insn = NULL;
}
#include "gt-gcse.h" #include "gt-gcse.h"
...@@ -39,4 +39,6 @@ extern struct target_gcse *this_target_gcse; ...@@ -39,4 +39,6 @@ extern struct target_gcse *this_target_gcse;
#define this_target_gcse (&default_target_gcse) #define this_target_gcse (&default_target_gcse)
#endif #endif
void gcse_c_finalize (void);
#endif #endif
...@@ -1697,8 +1697,13 @@ compute_inverse (unsigned order) ...@@ -1697,8 +1697,13 @@ compute_inverse (unsigned order)
void void
init_ggc (void) init_ggc (void)
{ {
static bool init_p = false;
unsigned order; unsigned order;
if (init_p)
return;
init_p = true;
G.pagesize = getpagesize (); G.pagesize = getpagesize ();
G.lg_pagesize = exact_log2 (G.pagesize); G.lg_pagesize = exact_log2 (G.pagesize);
......
...@@ -105,7 +105,7 @@ struct fcache ...@@ -105,7 +105,7 @@ struct fcache
/* Current position in real source file. */ /* Current position in real source file. */
location_t input_location; location_t input_location = UNKNOWN_LOCATION;
struct line_maps *line_table; struct line_maps *line_table;
......
...@@ -3827,3 +3827,15 @@ make_pass_ipa_cp (gcc::context *ctxt) ...@@ -3827,3 +3827,15 @@ make_pass_ipa_cp (gcc::context *ctxt)
{ {
return new pass_ipa_cp (ctxt); return new pass_ipa_cp (ctxt);
} }
/* Reset all state within ipa-cp.c so that we can rerun the compiler
within the same process. For use by toplev::finalize. */
void
ipa_cp_c_finalize (void)
{
max_count = 0;
overall_size = 0;
max_new_size = 0;
values_topo = NULL;
}
...@@ -732,4 +732,7 @@ ipa_parm_adjustment *ipa_get_adjustment_candidate (tree **, bool *, ...@@ -732,4 +732,7 @@ ipa_parm_adjustment *ipa_get_adjustment_candidate (tree **, bool *,
tree build_ref_for_offset (location_t, tree, HOST_WIDE_INT, tree, tree build_ref_for_offset (location_t, tree, HOST_WIDE_INT, tree,
gimple_stmt_iterator *, bool); gimple_stmt_iterator *, bool);
/* In ipa-cp.c */
void ipa_cp_c_finalize (void);
#endif /* IPA_PROP_H */ #endif /* IPA_PROP_H */
...@@ -115,10 +115,45 @@ typedef struct funct_state_d * funct_state; ...@@ -115,10 +115,45 @@ typedef struct funct_state_d * funct_state;
static vec<funct_state> funct_state_vec; static vec<funct_state> funct_state_vec;
/* Holders of ipa cgraph hooks: */ static bool gate_pure_const (void);
static struct cgraph_node_hook_list *function_insertion_hook_holder;
static struct cgraph_2node_hook_list *node_duplication_hook_holder; namespace {
static struct cgraph_node_hook_list *node_removal_hook_holder;
const pass_data pass_data_ipa_pure_const =
{
IPA_PASS, /* type */
"pure-const", /* name */
OPTGROUP_NONE, /* optinfo_flags */
TV_IPA_PURE_CONST, /* tv_id */
0, /* properties_required */
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
0, /* todo_flags_finish */
};
class pass_ipa_pure_const : public ipa_opt_pass_d
{
public:
pass_ipa_pure_const(gcc::context *ctxt);
/* opt_pass methods: */
bool gate (function *) { return gate_pure_const (); }
unsigned int execute (function *fun);
void register_hooks (void);
private:
bool init_p;
/* Holders of ipa cgraph hooks: */
struct cgraph_node_hook_list *function_insertion_hook_holder;
struct cgraph_2node_hook_list *node_duplication_hook_holder;
struct cgraph_node_hook_list *node_removal_hook_holder;
}; // class pass_ipa_pure_const
} // anon namespace
/* Try to guess if function body will always be visible to compiler /* Try to guess if function body will always be visible to compiler
when compiling the call and whether compiler will be able when compiling the call and whether compiler will be able
...@@ -881,11 +916,10 @@ remove_node_data (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED) ...@@ -881,11 +916,10 @@ remove_node_data (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
} }
static void void
pass_ipa_pure_const::
register_hooks (void) register_hooks (void)
{ {
static bool init_p = false;
if (init_p) if (init_p)
return; return;
...@@ -908,7 +942,8 @@ pure_const_generate_summary (void) ...@@ -908,7 +942,8 @@ pure_const_generate_summary (void)
{ {
struct cgraph_node *node; struct cgraph_node *node;
register_hooks (); pass_ipa_pure_const *pass = static_cast <pass_ipa_pure_const *> (current_pass);
pass->register_hooks ();
/* Process all of the functions. /* Process all of the functions.
...@@ -989,7 +1024,9 @@ pure_const_read_summary (void) ...@@ -989,7 +1024,9 @@ pure_const_read_summary (void)
struct lto_file_decl_data *file_data; struct lto_file_decl_data *file_data;
unsigned int j = 0; unsigned int j = 0;
register_hooks (); pass_ipa_pure_const *pass = static_cast <pass_ipa_pure_const *> (current_pass);
pass->register_hooks ();
while ((file_data = file_data_vec[j++])) while ((file_data = file_data_vec[j++]))
{ {
const char *data; const char *data;
...@@ -1470,8 +1507,9 @@ propagate_nothrow (void) ...@@ -1470,8 +1507,9 @@ propagate_nothrow (void)
/* Produce the global information by preforming a transitive closure /* Produce the global information by preforming a transitive closure
on the local information that was produced by generate_summary. */ on the local information that was produced by generate_summary. */
static unsigned int unsigned int
propagate (void) pass_ipa_pure_const::
execute (function *)
{ {
struct cgraph_node *node; struct cgraph_node *node;
...@@ -1500,26 +1538,8 @@ gate_pure_const (void) ...@@ -1500,26 +1538,8 @@ gate_pure_const (void)
&& !seen_error ()); && !seen_error ());
} }
namespace { pass_ipa_pure_const::pass_ipa_pure_const(gcc::context *ctxt)
: ipa_opt_pass_d(pass_data_ipa_pure_const, ctxt,
const pass_data pass_data_ipa_pure_const =
{
IPA_PASS, /* type */
"pure-const", /* name */
OPTGROUP_NONE, /* optinfo_flags */
TV_IPA_PURE_CONST, /* tv_id */
0, /* properties_required */
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
0, /* todo_flags_finish */
};
class pass_ipa_pure_const : public ipa_opt_pass_d
{
public:
pass_ipa_pure_const (gcc::context *ctxt)
: ipa_opt_pass_d (pass_data_ipa_pure_const, ctxt,
pure_const_generate_summary, /* generate_summary */ pure_const_generate_summary, /* generate_summary */
pure_const_write_summary, /* write_summary */ pure_const_write_summary, /* write_summary */
pure_const_read_summary, /* read_summary */ pure_const_read_summary, /* read_summary */
...@@ -1528,16 +1548,13 @@ public: ...@@ -1528,16 +1548,13 @@ public:
NULL, /* stmt_fixup */ NULL, /* stmt_fixup */
0, /* function_transform_todo_flags_start */ 0, /* function_transform_todo_flags_start */
NULL, /* function_transform */ NULL, /* function_transform */
NULL) /* variable_transform */ NULL), /* variable_transform */
{} init_p(false),
function_insertion_hook_holder(NULL),
/* opt_pass methods: */ node_duplication_hook_holder(NULL),
virtual bool gate (function *) { return gate_pure_const (); } node_removal_hook_holder(NULL)
virtual unsigned int execute (function *) { return propagate (); } {
}
}; // class pass_ipa_pure_const
} // anon namespace
ipa_opt_pass_d * ipa_opt_pass_d *
make_pass_ipa_pure_const (gcc::context *ctxt) make_pass_ipa_pure_const (gcc::context *ctxt)
......
...@@ -399,17 +399,17 @@ propagate_bits (ipa_reference_global_vars_info_t x_global, struct cgraph_node *x ...@@ -399,17 +399,17 @@ propagate_bits (ipa_reference_global_vars_info_t x_global, struct cgraph_node *x
} }
} }
static bool ipa_init_p = false;
/* The init routine for analyzing global static variable usage. See /* The init routine for analyzing global static variable usage. See
comments at top for description. */ comments at top for description. */
static void static void
ipa_init (void) ipa_init (void)
{ {
static bool init_p = false; if (ipa_init_p)
if (init_p)
return; return;
init_p = true; ipa_init_p = true;
if (dump_file) if (dump_file)
reference_vars_to_consider = splay_tree_new (splay_tree_compare_ints, 0, 0); reference_vars_to_consider = splay_tree_new (splay_tree_compare_ints, 0, 0);
...@@ -1173,3 +1173,12 @@ make_pass_ipa_reference (gcc::context *ctxt) ...@@ -1173,3 +1173,12 @@ make_pass_ipa_reference (gcc::context *ctxt)
{ {
return new pass_ipa_reference (ctxt); return new pass_ipa_reference (ctxt);
} }
/* Reset all state within ipa-reference.c so that we can rerun the compiler
within the same process. For use by toplev::finalize. */
void
ipa_reference_c_finalize (void)
{
ipa_init_p = false;
}
...@@ -26,6 +26,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -26,6 +26,7 @@ along with GCC; see the file COPYING3. If not see
/* In ipa-reference.c */ /* In ipa-reference.c */
bitmap ipa_reference_get_not_read_global (struct cgraph_node *fn); bitmap ipa_reference_get_not_read_global (struct cgraph_node *fn);
bitmap ipa_reference_get_not_written_global (struct cgraph_node *fn); bitmap ipa_reference_get_not_written_global (struct cgraph_node *fn);
void ipa_reference_c_finalize (void);
#endif /* GCC_IPA_REFERENCE_H */ #endif /* GCC_IPA_REFERENCE_H */
...@@ -26,12 +26,14 @@ along with GCC; see the file COPYING3. If not see ...@@ -26,12 +26,14 @@ along with GCC; see the file COPYING3. If not see
int main (int argc, char **argv); int main (int argc, char **argv);
/* We define main() to call toplev_main(), which is defined in toplev.c. /* We define main() to call toplev::main(), which is defined in toplev.c.
We do this in a separate file in order to allow the language front-end We do this in a separate file in order to allow the language front-end
to define a different main(), if it so desires. */ to define a different main(), if it so desires. */
int int
main (int argc, char **argv) main (int argc, char **argv)
{ {
return toplev_main (argc, argv); toplev toplev (true);
return toplev.main (argc, argv);
} }
...@@ -69,6 +69,8 @@ add_params (const param_info params[], size_t n) ...@@ -69,6 +69,8 @@ add_params (const param_info params[], size_t n)
void void
global_init_params (void) global_init_params (void)
{ {
gcc_assert (!params_finished);
add_params (lang_independent_params, LAST_PARAM); add_params (lang_independent_params, LAST_PARAM);
targetm_common.option_default_params (); targetm_common.option_default_params ();
} }
...@@ -82,6 +84,18 @@ finish_params (void) ...@@ -82,6 +84,18 @@ finish_params (void)
params_finished = true; params_finished = true;
} }
/* Reset all state within params.c so that we can rerun the compiler
within the same process. For use by toplev::finalize. */
void
params_c_finalize (void)
{
XDELETEVEC (compiler_params);
compiler_params = NULL;
num_compiler_params = 0;
params_finished = false;
}
/* Set the value of the parameter given by NUM to VALUE in PARAMS and /* Set the value of the parameter given by NUM to VALUE in PARAMS and
PARAMS_SET. If EXPLICIT_P, this is being set by the user; PARAMS_SET. If EXPLICIT_P, this is being set by the user;
otherwise it is being set implicitly by the compiler. */ otherwise it is being set implicitly by the compiler. */
......
...@@ -113,6 +113,10 @@ extern void global_init_params (void); ...@@ -113,6 +113,10 @@ extern void global_init_params (void);
set. */ set. */
extern void finish_params (void); extern void finish_params (void);
/* Reset all state in params.c */
extern void params_c_finalize (void);
/* Return the default value of parameter NUM. */ /* Return the default value of parameter NUM. */
extern int default_param_value (compiler_param num); extern int default_param_value (compiler_param num);
......
...@@ -1948,6 +1948,7 @@ execute_ipa_summary_passes (ipa_opt_pass_d *ipa_pass) ...@@ -1948,6 +1948,7 @@ execute_ipa_summary_passes (ipa_opt_pass_d *ipa_pass)
if (pass->tv_id) if (pass->tv_id)
timevar_push (pass->tv_id); timevar_push (pass->tv_id);
current_pass = pass;
ipa_pass->generate_summary (); ipa_pass->generate_summary ();
/* Stop timevar. */ /* Stop timevar. */
...@@ -2259,6 +2260,7 @@ ipa_write_summaries_2 (opt_pass *pass, struct lto_out_decl_state *state) ...@@ -2259,6 +2260,7 @@ ipa_write_summaries_2 (opt_pass *pass, struct lto_out_decl_state *state)
pass_init_dump_file (pass); pass_init_dump_file (pass);
current_pass = pass;
ipa_pass->write_summary (); ipa_pass->write_summary ();
pass_fini_dump_file (pass); pass_fini_dump_file (pass);
...@@ -2377,6 +2379,7 @@ ipa_write_optimization_summaries_1 (opt_pass *pass, ...@@ -2377,6 +2379,7 @@ ipa_write_optimization_summaries_1 (opt_pass *pass,
pass_init_dump_file (pass); pass_init_dump_file (pass);
current_pass = pass;
ipa_pass->write_optimization_summary (); ipa_pass->write_optimization_summary ();
pass_fini_dump_file (pass); pass_fini_dump_file (pass);
...@@ -2457,6 +2460,7 @@ ipa_read_summaries_1 (opt_pass *pass) ...@@ -2457,6 +2460,7 @@ ipa_read_summaries_1 (opt_pass *pass)
pass_init_dump_file (pass); pass_init_dump_file (pass);
current_pass = pass;
ipa_pass->read_summary (); ipa_pass->read_summary ();
pass_fini_dump_file (pass); pass_fini_dump_file (pass);
...@@ -2507,6 +2511,7 @@ ipa_read_optimization_summaries_1 (opt_pass *pass) ...@@ -2507,6 +2511,7 @@ ipa_read_optimization_summaries_1 (opt_pass *pass)
pass_init_dump_file (pass); pass_init_dump_file (pass);
current_pass = pass;
ipa_pass->read_optimization_summary (); ipa_pass->read_optimization_summary ();
pass_fini_dump_file (pass); pass_fini_dump_file (pass);
...@@ -2586,6 +2591,7 @@ execute_ipa_stmt_fixups (opt_pass *pass, ...@@ -2586,6 +2591,7 @@ execute_ipa_stmt_fixups (opt_pass *pass,
if (pass->tv_id) if (pass->tv_id)
timevar_push (pass->tv_id); timevar_push (pass->tv_id);
current_pass = pass;
ipa_pass->stmt_fixup (node, stmts); ipa_pass->stmt_fixup (node, stmts);
/* Stop timevar. */ /* Stop timevar. */
......
...@@ -61,6 +61,11 @@ stringpool_ggc_alloc (size_t x) ...@@ -61,6 +61,11 @@ stringpool_ggc_alloc (size_t x)
void void
init_stringpool (void) init_stringpool (void)
{ {
/* Clean up if we're called more than once.
(We can't make this idempotent since identifiers contain state) */
if (ident_hash)
ht_destroy (ident_hash);
/* Create with 16K (2^14) entries. */ /* Create with 16K (2^14) entries. */
ident_hash = ht_create (14); ident_hash = ht_create (14);
ident_hash->alloc_node = alloc_node; ident_hash->alloc_node = alloc_node;
......
...@@ -223,6 +223,9 @@ timevar_accumulate (struct timevar_time_def *timer, ...@@ -223,6 +223,9 @@ timevar_accumulate (struct timevar_time_def *timer,
void void
timevar_init (void) timevar_init (void)
{ {
if (timevar_enable)
return;
timevar_enable = true; timevar_enable = true;
/* Zero all elapsed times. */ /* Zero all elapsed times. */
......
...@@ -83,6 +83,10 @@ along with GCC; see the file COPYING3. If not see ...@@ -83,6 +83,10 @@ along with GCC; see the file COPYING3. If not see
#include "diagnostic-color.h" #include "diagnostic-color.h"
#include "context.h" #include "context.h"
#include "pass_manager.h" #include "pass_manager.h"
#include "dwarf2out.h"
#include "ipa-reference.h"
#include "ipa-prop.h"
#include "gcse.h"
#include "optabs.h" #include "optabs.h"
#if defined(DBX_DEBUGGING_INFO) || defined(XCOFF_DEBUGGING_INFO) #if defined(DBX_DEBUGGING_INFO) || defined(XCOFF_DEBUGGING_INFO)
...@@ -101,7 +105,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -101,7 +105,7 @@ along with GCC; see the file COPYING3. If not see
#include <new> #include <new>
static void general_init (const char *); static void general_init (const char *);
static void do_compile (void); static void do_compile ();
static void process_options (void); static void process_options (void);
static void backend_init (void); static void backend_init (void);
static int lang_dependent_init (const char *); static int lang_dependent_init (const char *);
...@@ -1161,6 +1165,7 @@ general_init (const char *argv0) ...@@ -1161,6 +1165,7 @@ general_init (const char *argv0)
table. */ table. */
init_ggc (); init_ggc ();
init_stringpool (); init_stringpool ();
input_location = UNKNOWN_LOCATION;
line_table = ggc_alloc<line_maps> (); line_table = ggc_alloc<line_maps> ();
linemap_init (line_table, BUILTINS_LOCATION); linemap_init (line_table, BUILTINS_LOCATION);
line_table->reallocator = realloc_for_line_map; line_table->reallocator = realloc_for_line_map;
...@@ -1708,16 +1713,16 @@ lang_dependent_init_target (void) ...@@ -1708,16 +1713,16 @@ lang_dependent_init_target (void)
/* Perform initializations that are lang-dependent or target-dependent. /* Perform initializations that are lang-dependent or target-dependent.
but matters only for late optimizations and RTL generation. */ but matters only for late optimizations and RTL generation. */
static int rtl_initialized;
void void
initialize_rtl (void) initialize_rtl (void)
{ {
static int initialized_once;
/* Initialization done just once per compilation, but delayed /* Initialization done just once per compilation, but delayed
till code generation. */ till code generation. */
if (!initialized_once) if (!rtl_initialized)
ira_init_once (); ira_init_once ();
initialized_once = true; rtl_initialized = true;
/* Target specific RTL backend initialization. */ /* Target specific RTL backend initialization. */
if (!this_target_rtl->target_specific_initialized) if (!this_target_rtl->target_specific_initialized)
...@@ -1922,14 +1927,8 @@ standard_type_bitsize (int bitsize) ...@@ -1922,14 +1927,8 @@ standard_type_bitsize (int bitsize)
/* Initialize the compiler, and compile the input file. */ /* Initialize the compiler, and compile the input file. */
static void static void
do_compile (void) do_compile ()
{ {
/* Initialize timing first. The C front ends read the main file in
the post_options hook, and C++ does file timings. */
if (time_report || !quiet_flag || flag_detailed_statistics)
timevar_init ();
timevar_start (TV_TOTAL);
process_options (); process_options ();
/* Don't do any more if an error has already occurred. */ /* Don't do any more if an error has already occurred. */
...@@ -1987,12 +1986,30 @@ do_compile (void) ...@@ -1987,12 +1986,30 @@ do_compile (void)
timevar_stop (TV_PHASE_FINALIZE); timevar_stop (TV_PHASE_FINALIZE);
} }
}
/* Stop timing and print the times. */ toplev::toplev (bool use_TV_TOTAL)
: m_use_TV_TOTAL (use_TV_TOTAL)
{
if (!m_use_TV_TOTAL)
start_timevars ();
}
toplev::~toplev ()
{
timevar_stop (TV_TOTAL); timevar_stop (TV_TOTAL);
timevar_print (stderr); timevar_print (stderr);
} }
void
toplev::start_timevars ()
{
if (time_report || !quiet_flag || flag_detailed_statistics)
timevar_init ();
timevar_start (TV_TOTAL);
}
/* Entry point of cc1, cc1plus, jc1, f771, etc. /* Entry point of cc1, cc1plus, jc1, f771, etc.
Exit code is FATAL_EXIT_CODE if can't open files or if there were Exit code is FATAL_EXIT_CODE if can't open files or if there were
any errors, or SUCCESS_EXIT_CODE if compilation succeeded. any errors, or SUCCESS_EXIT_CODE if compilation succeeded.
...@@ -2000,7 +2017,7 @@ do_compile (void) ...@@ -2000,7 +2017,7 @@ do_compile (void)
It is not safe to call this function more than once. */ It is not safe to call this function more than once. */
int int
toplev_main (int argc, char **argv) toplev::main (int argc, char **argv)
{ {
/* Parsing and gimplification sometimes need quite large stack. /* Parsing and gimplification sometimes need quite large stack.
Increase stack size limits if possible. */ Increase stack size limits if possible. */
...@@ -2050,7 +2067,11 @@ toplev_main (int argc, char **argv) ...@@ -2050,7 +2067,11 @@ toplev_main (int argc, char **argv)
/* Exit early if we can (e.g. -help). */ /* Exit early if we can (e.g. -help). */
if (!exit_after_options) if (!exit_after_options)
{
if (m_use_TV_TOTAL)
start_timevars ();
do_compile (); do_compile ();
}
if (warningcount || errorcount || werrorcount) if (warningcount || errorcount || werrorcount)
print_ignored_options (); print_ignored_options ();
...@@ -2068,3 +2089,20 @@ toplev_main (int argc, char **argv) ...@@ -2068,3 +2089,20 @@ toplev_main (int argc, char **argv)
return (SUCCESS_EXIT_CODE); return (SUCCESS_EXIT_CODE);
} }
/* For those that want to, this function aims to clean up enough state that
you can call toplev::main again. */
void
toplev::finalize (void)
{
rtl_initialized = false;
this_target_rtl->target_specific_initialized = false;
cgraph_c_finalize ();
cgraphunit_c_finalize ();
dwarf2out_c_finalize ();
gcse_c_finalize ();
ipa_cp_c_finalize ();
ipa_reference_c_finalize ();
params_c_finalize ();
}
...@@ -24,7 +24,24 @@ along with GCC; see the file COPYING3. If not see ...@@ -24,7 +24,24 @@ along with GCC; see the file COPYING3. If not see
extern struct cl_decoded_option *save_decoded_options; extern struct cl_decoded_option *save_decoded_options;
extern unsigned int save_decoded_options_count; extern unsigned int save_decoded_options_count;
extern int toplev_main (int, char **); /* Invoking the compiler. */
class toplev
{
public:
toplev (bool use_TV_TOTAL);
~toplev ();
int main (int argc, char **argv);
void finalize ();
private:
void start_timevars ();
bool m_use_TV_TOTAL;
};
extern void rest_of_decl_compilation (tree, int, int); extern void rest_of_decl_compilation (tree, int, int);
extern void rest_of_type_compilation (tree, int); extern void rest_of_type_compilation (tree, int);
extern void init_optimization_passes (void); extern void init_optimization_passes (void);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment