State cleanups from jit branch
authorDavid Malcolm <dmalcolm@redhat.com>
Tue, 21 Oct 2014 16:55:38 +0000 (16:55 +0000)
committerDavid Malcolm <dmalcolm@gcc.gnu.org>
Tue, 21 Oct 2014 16:55:38 +0000 (16:55 +0000)
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

24 files changed:
gcc/ChangeLog
gcc/cgraph.c
gcc/cgraph.h
gcc/cgraphunit.c
gcc/diagnostic.c
gcc/dwarf2out.c
gcc/dwarf2out.h
gcc/gcse.c
gcc/gcse.h
gcc/ggc-page.c
gcc/input.c
gcc/ipa-cp.c
gcc/ipa-prop.h
gcc/ipa-pure-const.c
gcc/ipa-reference.c
gcc/ipa-reference.h
gcc/main.c
gcc/params.c
gcc/params.h
gcc/passes.c
gcc/stringpool.c
gcc/timevar.c
gcc/toplev.c
gcc/toplev.h

index f29decfb56623ec8851effa69444c4b7701f4e68..bce5f7010eb65922419e93c5865d48abb4914357 100644 (file)
@@ -1,3 +1,77 @@
+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>
 
        * loop-doloop.c: Include loop-unroll.h.
index f472ec531592cbd7de1063de227204612ea13f14..6536233430dd7537e329b32e47917befcacba4ee 100644 (file)
@@ -3097,4 +3097,18 @@ gimple_check_call_matching_types (gimple call_stmt, tree callee,
   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"
index aa28414e8513ffde83d104dae04e9d1406bddbd9..2a55e171f9837f788b23b225115112ec2f22fe3d 100644 (file)
@@ -2108,6 +2108,7 @@ asmname_hasher::pch_nx (symtab_node *&n, gt_pointer_operator op, void *cookie)
 }
 
 /* In cgraph.c  */
+void cgraph_c_finalize (void);
 void release_function_body (tree);
 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);
 extern bool gimple_check_call_matching_types (gimple, tree, bool);
 
 /* In cgraphunit.c  */
+void cgraphunit_c_finalize (void);
+
 /*  Initialize datastructures so DECL is a function in lowered gimple form.
     IN_SSA is true if the gimple is in SSA.  */
 basic_block init_lowered_empty_function (tree, bool);
index c558a000c628fae4fc739c8147c833a81d78c42f..e84c70089c1a254454cc11dcd9b1bb58cc0ceb50 100644 (file)
@@ -884,15 +884,15 @@ walk_polymorphic_call_targets (hash_set<void *> *reachable_call_targets,
 
 /* Discover all functions and variables that are trivially needed, analyze
    them as well as all functions and variables referred by them  */
+static cgraph_node *first_analyzed;
+static varpool_node *first_analyzed_var;
 
 static void
 analyze_functions (void)
 {
   /* Keep track of already processed nodes when called multiple times for
      intermodule optimization.  */
-  static cgraph_node *first_analyzed;
   cgraph_node *first_handled = first_analyzed;
-  static varpool_node *first_analyzed_var;
   varpool_node *first_handled_var = first_analyzed_var;
   hash_set<void *> reachable_call_targets;
 
@@ -2292,6 +2292,22 @@ symbol_table::finalize_compilation_unit (void)
   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
    kind of wrapper method.  */
 
index 881da0b80455b2c629a07a6370317ef2c2647be3..642cbe38b9af67752cb1509b359d0cba2e835481 100644 (file)
@@ -177,6 +177,15 @@ diagnostic_finish (diagnostic_context *context)
     }
 
   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
@@ -342,7 +351,7 @@ diagnostic_show_locus (diagnostic_context * context,
 static const char * const bt_stop[] =
 {
   "main",
-  "toplev_main",
+  "toplev::main",
   "execute_one_pass",
   "compile_file",
 };
index 8c651766f0b4db80d28be75a2218a7c9b33813d8..a87f9c0997e7ed52fa0b1229a465047bcde7206b 100644 (file)
@@ -24619,4 +24619,90 @@ dwarf2out_finish (const char *filename)
     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"
index 7843e0a7eac762b1123481da42a5fbf4d3a8d53d..c30d81f0d6e2f7c34c6520e688502b5f77ecfc2b 100644 (file)
@@ -277,4 +277,6 @@ struct array_descr_info
     } dimen[10];
 };
 
+void dwarf2out_c_finalize (void);
+
 #endif /* GCC_DWARF2OUT_H */
index b6e3cf801b1b92476ab77376578771b0cde231f4..9c62f8b3bb1d5a69c6aeacf839193593d79f5c97 100644 (file)
@@ -4293,4 +4293,13 @@ make_pass_rtl_hoist (gcc::context *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"
index 1b8c1c65a2b6916c413b574eb8754b7bc6ae4e11..8e6820f79fe7c0d25cfa9fdb44ed7f4352f545d1 100644 (file)
@@ -39,4 +39,6 @@ extern struct target_gcse *this_target_gcse;
 #define this_target_gcse (&default_target_gcse)
 #endif
 
+void gcse_c_finalize (void);
+
 #endif
index 85b1ce9f284e0f397ea421929e6f112a79bd3de4..2236a3a7d2ffc38131ef0a90a6bd6676a8681e91 100644 (file)
@@ -1697,8 +1697,13 @@ compute_inverse (unsigned order)
 void
 init_ggc (void)
 {
+  static bool init_p = false;
   unsigned order;
 
+  if (init_p)
+    return;
+  init_p = true;
+
   G.pagesize = getpagesize ();
   G.lg_pagesize = exact_log2 (G.pagesize);
 
index 7a88e2e29acb7c4e0fa39e65e5a2f67baa15cc01..8d6356a014df19202886e25726bc33c5f79a1a2f 100644 (file)
@@ -105,7 +105,7 @@ struct fcache
 
 /* Current position in real source file.  */
 
-location_t input_location;
+location_t input_location = UNKNOWN_LOCATION;
 
 struct line_maps *line_table;
 
index a3be16f8bf45b63fd6bb1f2a51e4bacd20224bbf..a6269755036380973f97982a3fc8011e5b1acd1d 100644 (file)
@@ -3827,3 +3827,15 @@ make_pass_ipa_cp (gcc::context *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;
+}
index 7a06af9958bceb1746572b828db07114535c37f7..d2f0c675846ef5e2b7d294764ff27394573864b2 100644 (file)
@@ -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,
                           gimple_stmt_iterator *, bool);
 
+/* In ipa-cp.c  */
+void ipa_cp_c_finalize (void);
+
 #endif /* IPA_PROP_H */
index b5ded3e73ed5e998a989e5a23b4b9d97291df823..c221cd0a3babf94a2beaff3e8f4fb5f8c2052f48 100644 (file)
@@ -115,10 +115,45 @@ typedef struct funct_state_d * funct_state;
 
 static vec<funct_state> funct_state_vec;
 
-/* Holders of ipa cgraph hooks: */
-static struct cgraph_node_hook_list *function_insertion_hook_holder;
-static struct cgraph_2node_hook_list *node_duplication_hook_holder;
-static struct cgraph_node_hook_list *node_removal_hook_holder;
+static bool gate_pure_const (void);
+
+namespace {
+
+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
    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)
 }
 
 \f
-static void
+void
+pass_ipa_pure_const::
 register_hooks (void)
 {
-  static bool init_p = false;
-
   if (init_p)
     return;
 
@@ -908,7 +942,8 @@ pure_const_generate_summary (void)
 {
   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.
 
@@ -989,7 +1024,9 @@ pure_const_read_summary (void)
   struct lto_file_decl_data *file_data;
   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++]))
     {
       const char *data;
@@ -1470,8 +1507,9 @@ propagate_nothrow (void)
 /* Produce the global information by preforming a transitive closure
    on the local information that was produced by generate_summary.  */
 
-static unsigned int
-propagate (void)
+unsigned int
+pass_ipa_pure_const::
+execute (function *)
 {
   struct cgraph_node *node;
 
@@ -1500,44 +1538,23 @@ gate_pure_const (void)
          && !seen_error ());
 }
 
-namespace {
-
-const pass_data pass_data_ipa_pure_const =
+pass_ipa_pure_const::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_write_summary, /* write_summary */
+                    pure_const_read_summary, /* read_summary */
+                    NULL, /* write_optimization_summary */
+                    NULL, /* read_optimization_summary */
+                    NULL, /* stmt_fixup */
+                    0, /* function_transform_todo_flags_start */
+                    NULL, /* function_transform */
+                    NULL), /* variable_transform */
+  init_p(false),
+  function_insertion_hook_holder(NULL),
+  node_duplication_hook_holder(NULL),
+  node_removal_hook_holder(NULL)
 {
-  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_write_summary, /* write_summary */
-                     pure_const_read_summary, /* read_summary */
-                     NULL, /* write_optimization_summary */
-                     NULL, /* read_optimization_summary */
-                     NULL, /* stmt_fixup */
-                     0, /* function_transform_todo_flags_start */
-                     NULL, /* function_transform */
-                     NULL) /* variable_transform */
-  {}
-
-  /* opt_pass methods: */
-  virtual bool gate (function *) { return gate_pure_const (); }
-  virtual unsigned int execute (function *) { return propagate (); }
-
-}; // class pass_ipa_pure_const
-
-} // anon namespace
+}
 
 ipa_opt_pass_d *
 make_pass_ipa_pure_const (gcc::context *ctxt)
index 9767eabaddf9e0f3b2a73cad8a021642f5b50229..f3af47ae832e2e6950fba28cc9e6cee85f3214ee 100644 (file)
@@ -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
    comments at top for description.  */
 static void
 ipa_init (void)
 {
-  static bool init_p = false;
-
-  if (init_p)
+  if (ipa_init_p)
     return;
 
-  init_p = true;
+  ipa_init_p = true;
 
   if (dump_file)
     reference_vars_to_consider = splay_tree_new (splay_tree_compare_ints, 0, 0);
@@ -1173,3 +1173,12 @@ make_pass_ipa_reference (gcc::context *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;
+}
index c840024e4b4499c69103b2eb0c866d16ca5e9cac..3e7dc73198090dfad9a9fb2f792efc90809e7f76 100644 (file)
@@ -26,6 +26,7 @@ along with GCC; see the file COPYING3.  If not see
 /* In ipa-reference.c  */
 bitmap ipa_reference_get_not_read_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  */
 
index 241d15144f27038dfcacf05ae91f095ae7ebfedc..4bba0415ab332df1ad5ffef8d6e36d78598f9b12 100644 (file)
@@ -26,12 +26,14 @@ along with GCC; see the file COPYING3.  If not see
 
 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
    to define a different main(), if it so desires.  */
 
 int
 main (int argc, char **argv)
 {
-  return toplev_main (argc, argv);
+  toplev toplev (true);
+
+  return toplev.main (argc, argv);
 }
index 3ae5ccd5cbe68a0a5eba04694d21e6fbeb838f0f..7aa96e2c8f365457db009d60555ee137f521ac1f 100644 (file)
@@ -69,6 +69,8 @@ add_params (const param_info params[], size_t n)
 void
 global_init_params (void)
 {
+  gcc_assert (!params_finished);
+
   add_params (lang_independent_params, LAST_PARAM);
   targetm_common.option_default_params ();
 }
@@ -82,6 +84,18 @@ finish_params (void)
   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
    PARAMS_SET.  If EXPLICIT_P, this is being set by the user;
    otherwise it is being set implicitly by the compiler.  */
index d488e32ebfe453951f02ef839104e2f0ff967187..4779e17da33041c10fc8c19dadef5e6477f5de0e 100644 (file)
@@ -113,6 +113,10 @@ extern void global_init_params (void);
    set.  */
 extern void finish_params (void);
 
+/* Reset all state in params.c  */
+
+extern void params_c_finalize (void);
+
 /* Return the default value of parameter NUM.  */
 
 extern int default_param_value (compiler_param num);
index 68de5d62d32e30342f59369f85ba0be47d655df2..428c79792b72ddc73530add6ea1c000f1e8d993a 100644 (file)
@@ -1948,6 +1948,7 @@ execute_ipa_summary_passes (ipa_opt_pass_d *ipa_pass)
          if (pass->tv_id)
            timevar_push (pass->tv_id);
 
+         current_pass = pass;
          ipa_pass->generate_summary ();
 
          /* Stop timevar.  */
@@ -2259,6 +2260,7 @@ ipa_write_summaries_2 (opt_pass *pass, struct lto_out_decl_state *state)
 
           pass_init_dump_file (pass);
 
+         current_pass = pass;
          ipa_pass->write_summary ();
 
           pass_fini_dump_file (pass);
@@ -2377,6 +2379,7 @@ ipa_write_optimization_summaries_1 (opt_pass *pass,
 
           pass_init_dump_file (pass);
 
+         current_pass = pass;
          ipa_pass->write_optimization_summary ();
 
           pass_fini_dump_file (pass);
@@ -2457,6 +2460,7 @@ ipa_read_summaries_1 (opt_pass *pass)
 
              pass_init_dump_file (pass);
 
+             current_pass = pass;
              ipa_pass->read_summary ();
 
              pass_fini_dump_file (pass);
@@ -2507,6 +2511,7 @@ ipa_read_optimization_summaries_1 (opt_pass *pass)
 
              pass_init_dump_file (pass);
 
+             current_pass = pass;
              ipa_pass->read_optimization_summary ();
 
              pass_fini_dump_file (pass);
@@ -2586,6 +2591,7 @@ execute_ipa_stmt_fixups (opt_pass *pass,
              if (pass->tv_id)
                timevar_push (pass->tv_id);
 
+             current_pass = pass;
              ipa_pass->stmt_fixup (node, stmts);
 
              /* Stop timevar.  */
index c880cb1e6785b132f58392c6a75d0bc10097c6b1..330df6c1d3579e9f8fd6370e6cb5d57b52b53d56 100644 (file)
@@ -61,6 +61,11 @@ stringpool_ggc_alloc (size_t x)
 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.  */
   ident_hash = ht_create (14);
   ident_hash->alloc_node = alloc_node;
index c111e983cbd1f28b87923cf043d2669ede1bce5b..0e56a23e23c5bfe0b799ddf7c4bab29082892020 100644 (file)
@@ -223,6 +223,9 @@ timevar_accumulate (struct timevar_time_def *timer,
 void
 timevar_init (void)
 {
+  if (timevar_enable)
+    return;
+
   timevar_enable = true;
 
   /* Zero all elapsed times.  */
index 7df9cc79004f2e7ee2fccd41423ff367dc187600..a87ff9a2ff897669b407448777cba720c582a760 100644 (file)
@@ -83,6 +83,10 @@ along with GCC; see the file COPYING3.  If not see
 #include "diagnostic-color.h"
 #include "context.h"
 #include "pass_manager.h"
+#include "dwarf2out.h"
+#include "ipa-reference.h"
+#include "ipa-prop.h"
+#include "gcse.h"
 #include "optabs.h"
 
 #if defined(DBX_DEBUGGING_INFO) || defined(XCOFF_DEBUGGING_INFO)
@@ -101,7 +105,7 @@ along with GCC; see the file COPYING3.  If not see
 #include <new>
 
 static void general_init (const char *);
-static void do_compile (void);
+static void do_compile ();
 static void process_options (void);
 static void backend_init (void);
 static int lang_dependent_init (const char *);
@@ -1161,6 +1165,7 @@ general_init (const char *argv0)
      table.  */
   init_ggc ();
   init_stringpool ();
+  input_location = UNKNOWN_LOCATION;
   line_table = ggc_alloc<line_maps> ();
   linemap_init (line_table, BUILTINS_LOCATION);
   line_table->reallocator = realloc_for_line_map;
@@ -1708,16 +1713,16 @@ lang_dependent_init_target (void)
 /* Perform initializations that are lang-dependent or target-dependent.
    but matters only for late optimizations and RTL generation.  */
 
+static int rtl_initialized;
+
 void
 initialize_rtl (void)
 {
-  static int initialized_once;
-
   /* Initialization done just once per compilation, but delayed
      till code generation.  */
-  if (!initialized_once)
+  if (!rtl_initialized)
     ira_init_once ();
-  initialized_once = true;
+  rtl_initialized = true;
 
   /* Target specific RTL backend initialization.  */
   if (!this_target_rtl->target_specific_initialized)
@@ -1922,14 +1927,8 @@ standard_type_bitsize (int bitsize)
 
 /* Initialize the compiler, and compile the input file.  */
 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 ();
 
   /* Don't do any more if an error has already occurred.  */
@@ -1987,12 +1986,30 @@ do_compile (void)
 
       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_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.
    Exit code is FATAL_EXIT_CODE if can't open files or if there were
    any errors, or SUCCESS_EXIT_CODE if compilation succeeded.
@@ -2000,7 +2017,7 @@ do_compile (void)
    It is not safe to call this function more than once.  */
 
 int
-toplev_main (int argc, char **argv)
+toplev::main (int argc, char **argv)
 {
   /* Parsing and gimplification sometimes need quite large stack.
      Increase stack size limits if possible.  */
@@ -2050,7 +2067,11 @@ toplev_main (int argc, char **argv)
 
   /* Exit early if we can (e.g. -help).  */
   if (!exit_after_options)
-    do_compile ();
+    {
+      if (m_use_TV_TOTAL)
+       start_timevars ();
+      do_compile ();
+    }
 
   if (warningcount || errorcount || werrorcount)
     print_ignored_options ();
@@ -2068,3 +2089,20 @@ toplev_main (int argc, char **argv)
 
   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 ();
+}
index 1b5457823b80599c5ea2674961e132c51fbffa70..b845843307a8cae3866b7fe3bd26401ce4b133c0 100644 (file)
@@ -24,7 +24,24 @@ along with GCC; see the file COPYING3.  If not see
 extern struct cl_decoded_option *save_decoded_options;
 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_type_compilation (tree, int);
 extern void init_optimization_passes (void);