Message ID | 20201025132248.GE46434@kam.mff.cuni.cz |
---|---|
State | New |
Headers | show |
Series | Make default duplicate and insert methods of summaries abort; fix fallout | expand |
On 10/25/20 2:22 PM, Jan Hubicka wrote: > Hi, > the default duplicate and insert methods of sumaries produce empty > summary that is not useful for anything and makes it easy to introduce > bugs. > > This patch makes the default hooks to abort and summaries that do not > need dupicaito/insertion disable the corresponding hooks. I also > implemented missing insertion hook for ipa-sra which forced me to move > analysis out of anounmous namespace. > > Wi aready have disable_insertion_hook, I also added > disable_duplication_hook. Martin (Liska), it would be nice to simply > unregiter the hooks instead of having bool controlling htem so we save > some indirect calls. Hi. Good idea. I've made some refactoring and the following patch enables and disables directly the callgraph hooks. Patch can bootstrap on x86_64-linux-gnu and survives regression tests. Ready to be installed? Thanks, Martin > > Bootstrapped/regtested x86_64-linux, plan to commit it tomorrow if there > are no comments. > > Honza > > 2020-10-23 Jan Hubicka <hubicka@ucw.cz> > > * cgraph.h (struct cgraph_node): Make ipa_transforms_to_apply vl_ptr. > * ipa-inline-analysis.c (initialize_growth_caches): Disable insertion > and duplication hooks. > * ipa-inline-transform.c (clone_inlined_nodes): Clear > ipa_transforms_to_apply. > (save_inline_function_body): Disable insertion hoook for > ipa_saved_clone_sources. > * ipa-prop.c (ipcp_transformation_initialize): Disable insertion hook. > * ipa-prop.h (ipa_node_params_t): Disable insertion hook. > * ipa-reference.c (propagate): Disable insertion hoook. > * ipa-sra.c (ipa_sra_summarize_function): Move out of anonymous > namespace. > (ipa_sra_function_summaries::insert): New virtual function. > * passes.c (execute_one_pass): Do not add transforms to inline clones. > * symbol-summary.h (function_summary_base): Make insert and duplicate > hooks fail instead of silently producing empty summaries; add way to > disable duplication hooks > (call_summary_base): Likewise. > * tree-nested.c (nested_function_info::get_create): Disable insertion > hooks > (maybe_record_nested_function): Likewise. > > > diff --git a/gcc/cgraph.h b/gcc/cgraph.h > index 9eb48d5b62f..65e4646efcd 100644 > --- a/gcc/cgraph.h > +++ b/gcc/cgraph.h > @@ -1402,7 +1402,7 @@ struct GTY((tag ("SYMTAB_FUNCTION"))) cgraph_node : public symtab_node > /* Interprocedural passes scheduled to have their transform functions > applied next time we execute local pass on them. We maintain it > per-function in order to allow IPA passes to introduce new functions. */ > - vec<ipa_opt_pass> GTY((skip)) ipa_transforms_to_apply; > + vec<ipa_opt_pass, va_heap, vl_ptr> GTY((skip)) ipa_transforms_to_apply; > > /* For inline clones this points to the function they will be > inlined into. */ > diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c > index acbf82e84d9..bd0e322605f 100644 > --- a/gcc/ipa-inline-analysis.c > +++ b/gcc/ipa-inline-analysis.c > @@ -127,6 +127,9 @@ initialize_growth_caches () > = new fast_call_summary<edge_growth_cache_entry *, va_heap> (symtab); > node_context_cache > = new fast_function_summary<node_context_summary *, va_heap> (symtab); > + edge_growth_cache->disable_duplication_hook (); > + node_context_cache->disable_insertion_hook (); > + node_context_cache->disable_duplication_hook (); > } > > /* Free growth caches. */ > diff --git a/gcc/ipa-inline-transform.c b/gcc/ipa-inline-transform.c > index 3782cce12e3..279ba2f7cb0 100644 > --- a/gcc/ipa-inline-transform.c > +++ b/gcc/ipa-inline-transform.c > @@ -231,6 +231,11 @@ clone_inlined_nodes (struct cgraph_edge *e, bool duplicate, > e->callee->remove_from_same_comdat_group (); > > e->callee->inlined_to = inlining_into; > + if (e->callee->ipa_transforms_to_apply.length ()) > + { > + e->callee->ipa_transforms_to_apply.release (); > + e->callee->ipa_transforms_to_apply = vNULL; > + } > > /* Recursively clone all bodies. */ > for (e = e->callee->callees; e; e = next) > @@ -606,7 +611,10 @@ save_inline_function_body (struct cgraph_node *node) > > tree prev_body_holder = node->decl; > if (!ipa_saved_clone_sources) > - ipa_saved_clone_sources = new function_summary <tree *> (symtab); > + { > + ipa_saved_clone_sources = new function_summary <tree *> (symtab); > + ipa_saved_clone_sources->disable_insertion_hook (); > + } > else > { > tree *p = ipa_saved_clone_sources->get (node); > diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c > index a848f1db95e..6014766b418 100644 > --- a/gcc/ipa-prop.c > +++ b/gcc/ipa-prop.c > @@ -4211,7 +4211,10 @@ ipcp_transformation_initialize (void) > if (!ipa_vr_hash_table) > ipa_vr_hash_table = hash_table<ipa_vr_ggc_hash_traits>::create_ggc (37); > if (ipcp_transformation_sum == NULL) > - ipcp_transformation_sum = ipcp_transformation_t::create_ggc (symtab); > + { > + ipcp_transformation_sum = ipcp_transformation_t::create_ggc (symtab); > + ipcp_transformation_sum->disable_insertion_hook (); > + } > } > > /* Release the IPA CP transformation summary. */ > diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h > index 0bbbbf9bd9f..77e92b04bba 100644 > --- a/gcc/ipa-prop.h > +++ b/gcc/ipa-prop.h > @@ -941,7 +941,10 @@ class GTY((user)) ipa_node_params_t: public function_summary <ipa_node_params *> > { > public: > ipa_node_params_t (symbol_table *table, bool ggc): > - function_summary<ipa_node_params *> (table, ggc) { } > + function_summary<ipa_node_params *> (table, ggc) > + { > + disable_insertion_hook (); > + } > > /* Hook that is called by summary when a node is duplicated. */ > virtual void duplicate (cgraph_node *node, > diff --git a/gcc/ipa-reference.c b/gcc/ipa-reference.c > index 4a6c011c525..ced83d218ab 100644 > --- a/gcc/ipa-reference.c > +++ b/gcc/ipa-reference.c > @@ -894,7 +894,10 @@ propagate (void) > } > > if (ipa_ref_opt_sum_summaries == NULL) > - ipa_ref_opt_sum_summaries = new ipa_ref_opt_summary_t (symtab); > + { > + ipa_ref_opt_sum_summaries = new ipa_ref_opt_summary_t (symtab); > + ipa_ref_opt_sum_summaries->disable_insertion_hook (); > + } > > /* Cleanup. */ > FOR_EACH_DEFINED_FUNCTION (node) > diff --git a/gcc/ipa-sra.c b/gcc/ipa-sra.c > index 8d4f580e009..07227c0bfec 100644 > --- a/gcc/ipa-sra.c > +++ b/gcc/ipa-sra.c > @@ -85,6 +85,8 @@ along with GCC; see the file COPYING3. If not see > #include "tree-streamer.h" > #include "internal-fn.h" > > +static void ipa_sra_summarize_function (cgraph_node *); > + > /* Bits used to track size of an aggregate in bytes interprocedurally. */ > #define ISRA_ARG_SIZE_LIMIT_BITS 16 > #define ISRA_ARG_SIZE_LIMIT (1 << ISRA_ARG_SIZE_LIMIT_BITS) > @@ -373,6 +375,7 @@ public: > virtual void duplicate (cgraph_node *, cgraph_node *, > isra_func_summary *old_sum, > isra_func_summary *new_sum); > + virtual void insert (cgraph_node *, isra_func_summary *); > }; > > /* Hook that is called by summary when a node is duplicated. */ > @@ -426,6 +429,21 @@ ipa_sra_function_summaries::duplicate (cgraph_node *, cgraph_node *, > > static GTY(()) ipa_sra_function_summaries *func_sums; > > +/* Hook that is called by summary when new node appears. */ > + > +void > +ipa_sra_function_summaries::insert (cgraph_node *node, isra_func_summary *) > +{ > + if (opt_for_fn (node->decl, flag_ipa_sra)) > + { > + push_cfun (DECL_STRUCT_FUNCTION (node->decl)); > + ipa_sra_summarize_function (node); > + pop_cfun (); > + } > + else > + func_sums->remove (node); > +} > + > /* Class to manage call summaries. */ > > class ipa_sra_call_summaries: public call_summary <isra_call_summary *> > @@ -2478,79 +2496,6 @@ verify_splitting_accesses (cgraph_node *node, bool certain_must_exist) > } > } > > -/* Intraprocedural part of IPA-SRA analysis. Scan function body of NODE and > - create a summary structure describing IPA-SRA opportunities and constraints > - in it. */ > - > -static void > -ipa_sra_summarize_function (cgraph_node *node) > -{ > - if (dump_file) > - fprintf (dump_file, "Creating summary for %s/%i:\n", node->name (), > - node->order); > - if (!ipa_sra_preliminary_function_checks (node)) > - return; > - gcc_obstack_init (&gensum_obstack); > - isra_func_summary *ifs = func_sums->get_create (node); > - ifs->m_candidate = true; > - tree ret = TREE_TYPE (TREE_TYPE (node->decl)); > - ifs->m_returns_value = (TREE_CODE (ret) != VOID_TYPE); > - > - decl2desc = new hash_map<tree, gensum_param_desc *>; > - unsigned count = 0; > - for (tree parm = DECL_ARGUMENTS (node->decl); parm; parm = DECL_CHAIN (parm)) > - count++; > - > - if (count > 0) > - { > - auto_vec<gensum_param_desc, 16> param_descriptions (count); > - param_descriptions.reserve_exact (count); > - param_descriptions.quick_grow_cleared (count); > - > - bool cfun_pushed = false; > - struct function *fun = DECL_STRUCT_FUNCTION (node->decl); > - if (create_parameter_descriptors (node, ¶m_descriptions)) > - { > - push_cfun (fun); > - cfun_pushed = true; > - final_bbs = BITMAP_ALLOC (NULL); > - bb_dereferences = XCNEWVEC (HOST_WIDE_INT, > - by_ref_count > - * last_basic_block_for_fn (fun)); > - aa_walking_limit = opt_for_fn (node->decl, param_ipa_max_aa_steps); > - scan_function (node, fun); > - > - if (dump_file) > - { > - dump_gensum_param_descriptors (dump_file, node->decl, > - ¶m_descriptions); > - fprintf (dump_file, "----------------------------------------\n"); > - } > - } > - process_scan_results (node, fun, ifs, ¶m_descriptions); > - > - if (cfun_pushed) > - pop_cfun (); > - if (bb_dereferences) > - { > - free (bb_dereferences); > - bb_dereferences = NULL; > - BITMAP_FREE (final_bbs); > - final_bbs = NULL; > - } > - } > - isra_analyze_all_outgoing_calls (node); > - > - delete decl2desc; > - decl2desc = NULL; > - obstack_free (&gensum_obstack, NULL); > - if (dump_file) > - fprintf (dump_file, "\n\n"); > - if (flag_checking) > - verify_splitting_accesses (node, false); > - return; > -} > - > /* Intraprocedural part of IPA-SRA analysis. Scan bodies of all functions in > this compilation unit and create summary structures describing IPA-SRA > opportunities and constraints in them. */ > @@ -4102,6 +4047,79 @@ public: > > } // anon namespace > > +/* Intraprocedural part of IPA-SRA analysis. Scan function body of NODE and > + create a summary structure describing IPA-SRA opportunities and constraints > + in it. */ > + > +static void > +ipa_sra_summarize_function (cgraph_node *node) > +{ > + if (dump_file) > + fprintf (dump_file, "Creating summary for %s/%i:\n", node->name (), > + node->order); > + if (!ipa_sra_preliminary_function_checks (node)) > + return; > + gcc_obstack_init (&gensum_obstack); > + isra_func_summary *ifs = func_sums->get_create (node); > + ifs->m_candidate = true; > + tree ret = TREE_TYPE (TREE_TYPE (node->decl)); > + ifs->m_returns_value = (TREE_CODE (ret) != VOID_TYPE); > + > + decl2desc = new hash_map<tree, gensum_param_desc *>; > + unsigned count = 0; > + for (tree parm = DECL_ARGUMENTS (node->decl); parm; parm = DECL_CHAIN (parm)) > + count++; > + > + if (count > 0) > + { > + auto_vec<gensum_param_desc, 16> param_descriptions (count); > + param_descriptions.reserve_exact (count); > + param_descriptions.quick_grow_cleared (count); > + > + bool cfun_pushed = false; > + struct function *fun = DECL_STRUCT_FUNCTION (node->decl); > + if (create_parameter_descriptors (node, ¶m_descriptions)) > + { > + push_cfun (fun); > + cfun_pushed = true; > + final_bbs = BITMAP_ALLOC (NULL); > + bb_dereferences = XCNEWVEC (HOST_WIDE_INT, > + by_ref_count > + * last_basic_block_for_fn (fun)); > + aa_walking_limit = opt_for_fn (node->decl, param_ipa_max_aa_steps); > + scan_function (node, fun); > + > + if (dump_file) > + { > + dump_gensum_param_descriptors (dump_file, node->decl, > + ¶m_descriptions); > + fprintf (dump_file, "----------------------------------------\n"); > + } > + } > + process_scan_results (node, fun, ifs, ¶m_descriptions); > + > + if (cfun_pushed) > + pop_cfun (); > + if (bb_dereferences) > + { > + free (bb_dereferences); > + bb_dereferences = NULL; > + BITMAP_FREE (final_bbs); > + final_bbs = NULL; > + } > + } > + isra_analyze_all_outgoing_calls (node); > + > + delete decl2desc; > + decl2desc = NULL; > + obstack_free (&gensum_obstack, NULL); > + if (dump_file) > + fprintf (dump_file, "\n\n"); > + if (flag_checking) > + verify_splitting_accesses (node, false); > + return; > +} > + > ipa_opt_pass_d * > make_pass_ipa_sra (gcc::context *ctxt) > { > diff --git a/gcc/passes.c b/gcc/passes.c > index 1942b7cd1c3..02a47e2595c 100644 > --- a/gcc/passes.c > +++ b/gcc/passes.c > @@ -2566,7 +2566,8 @@ execute_one_pass (opt_pass *pass) > { > struct cgraph_node *node; > FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node) > - node->ipa_transforms_to_apply.safe_push ((ipa_opt_pass_d *)pass); > + if (!node->inlined_to) > + node->ipa_transforms_to_apply.safe_push ((ipa_opt_pass_d *)pass); > } > else if (dump_file) > do_per_function (execute_function_dump, pass); > diff --git a/gcc/symbol-summary.h b/gcc/symbol-summary.h > index a38eb1db778..af5f4e6da62 100644 > --- a/gcc/symbol-summary.h > +++ b/gcc/symbol-summary.h > @@ -31,17 +31,27 @@ public: > function_summary_base (symbol_table *symtab CXX_MEM_STAT_INFO): > m_symtab (symtab), > m_insertion_enabled (true), > + m_duplication_enabled (true), > m_allocator ("function summary" PASS_MEM_STAT) > {} > > /* Basic implementation of insert operation. */ > - virtual void insert (cgraph_node *, T *) {} > + virtual void insert (cgraph_node *, T *) > + { > + /* In most cases, it makes no sense to create summaries without > + initializing them. */ > + gcc_unreachable (); > + } > > /* Basic implementation of removal operation. */ > virtual void remove (cgraph_node *, T *) {} > > /* Basic implementation of duplication operation. */ > - virtual void duplicate (cgraph_node *, cgraph_node *, T *, T *) {} > + virtual void duplicate (cgraph_node *, cgraph_node *, T *, T *) > + { > + /* It makes no sense to not copy anything during duplication. */ > + gcc_unreachable (); > + } > > /* Enable insertion hook invocation. */ > void enable_insertion_hook () > @@ -55,6 +65,18 @@ public: > m_insertion_enabled = false; > } > > + /* Enable duplication hook invocation. */ > + void enable_duplication_hook () > + { > + m_duplication_enabled = true; > + } > + > + /* Enable duplication hook invocation. */ > + void disable_duplication_hook () > + { > + m_duplication_enabled = false; > + } > + > protected: > /* Allocates new data that are stored within map. */ > T* allocate_new () > @@ -88,6 +110,8 @@ protected: > > /* Indicates if insertion hook is enabled. */ > bool m_insertion_enabled; > + /* Indicates if duplication hook is enabled. */ > + bool m_duplication_enabled; > > private: > /* Return true when the summary uses GGC memory for allocation. */ > @@ -269,10 +293,13 @@ function_summary<T *>::symtab_duplication (cgraph_node *node, > cgraph_node *node2, void *data) > { > function_summary *summary = (function_summary <T *> *) (data); > - T *v = summary->get (node); > + if (summary->m_duplication_enabled) > + { > + T *v = summary->get (node); > > - if (v) > - summary->duplicate (node, node2, v, summary->get_create (node2)); > + if (v) > + summary->duplicate (node, node2, v, summary->get_create (node2)); > + } > } > > template <typename T> > @@ -468,12 +495,15 @@ fast_function_summary<T *, V>::symtab_duplication (cgraph_node *node, > void *data) > { > fast_function_summary *summary = (fast_function_summary <T *, V> *) (data); > - T *v = summary->get (node); > - > - if (v) > + if (summary->m_duplication_enabled) > { > - T *duplicate = summary->get_create (node2); > - summary->duplicate (node, node2, v, duplicate); > + T *v = summary->get (node); > + > + if (v) > + { > + T *duplicate = summary->get_create (node2); > + summary->duplicate (node, node2, v, duplicate); > + } > } > } > > @@ -536,6 +566,7 @@ public: > call_summary_base (symbol_table *symtab CXX_MEM_STAT_INFO): > m_symtab (symtab), > m_initialize_when_cloning (false), > + m_duplication_enabled (true), > m_allocator ("call summary" PASS_MEM_STAT) > {} > > @@ -543,7 +574,22 @@ public: > virtual void remove (cgraph_edge *, T *) {} > > /* Basic implementation of duplication operation. */ > - virtual void duplicate (cgraph_edge *, cgraph_edge *, T *, T *) {} > + virtual void duplicate (cgraph_edge *, cgraph_edge *, T *, T *) > + { > + gcc_unreachable (); > + } > + > + /* Enable duplication hook invocation. */ > + void enable_duplication_hook () > + { > + m_duplication_enabled = true; > + } > + > + /* Enable duplication hook invocation. */ > + void disable_duplication_hook () > + { > + m_duplication_enabled = false; > + } > > protected: > /* Allocates new data that are stored within map. */ > @@ -576,6 +622,8 @@ protected: > cgraph_2edge_hook_list *m_symtab_duplication_hook; > /* Initialize summary for an edge that is cloned. */ > bool m_initialize_when_cloning; > + /* Indicates if duplication hook is enabled. */ > + bool m_duplication_enabled; > > private: > /* Return true when the summary uses GGC memory for allocation. */ > @@ -726,16 +774,19 @@ call_summary<T *>::symtab_duplication (cgraph_edge *edge1, > cgraph_edge *edge2, void *data) > { > call_summary *summary = (call_summary <T *> *) (data); > - T *edge1_summary = NULL; > + if (summary->m_duplication_enabled) > + { > + T *edge1_summary = NULL; > > - if (summary->m_initialize_when_cloning) > - edge1_summary = summary->get_create (edge1); > - else > - edge1_summary = summary->get (edge1); > + if (summary->m_initialize_when_cloning) > + edge1_summary = summary->get_create (edge1); > + else > + edge1_summary = summary->get (edge1); > > - if (edge1_summary) > - summary->duplicate (edge1, edge2, edge1_summary, > - summary->get_create (edge2)); > + if (edge1_summary) > + summary->duplicate (edge1, edge2, edge1_summary, > + summary->get_create (edge2)); > + } > } > > template <typename T> > @@ -892,17 +943,20 @@ fast_call_summary<T *, V>::symtab_duplication (cgraph_edge *edge1, > cgraph_edge *edge2, void *data) > { > fast_call_summary *summary = (fast_call_summary <T *, V> *) (data); > - T *edge1_summary = NULL; > - > - if (summary->m_initialize_when_cloning) > - edge1_summary = summary->get_create (edge1); > - else > - edge1_summary = summary->get (edge1); > - > - if (edge1_summary) > + if (summary->m_duplication_enabled) > { > - T *duplicate = summary->get_create (edge2); > - summary->duplicate (edge1, edge2, edge1_summary, duplicate); > + T *edge1_summary = NULL; > + > + if (summary->m_initialize_when_cloning) > + edge1_summary = summary->get_create (edge1); > + else > + edge1_summary = summary->get (edge1); > + > + if (edge1_summary) > + { > + T *duplicate = summary->get_create (edge2); > + summary->duplicate (edge1, edge2, edge1_summary, duplicate); > + } > } > } > > diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c > index 788883faa4c..9cb4a08e2d9 100644 > --- a/gcc/tree-nested.c > +++ b/gcc/tree-nested.c > @@ -65,8 +65,11 @@ nested_function_info * > nested_function_info::get_create (cgraph_node *node) > { > if (!nested_function_sum) > - nested_function_sum = new function_summary <nested_function_info *> > - (symtab); > + { > + nested_function_sum = new function_summary <nested_function_info *> > + (symtab); > + nested_function_sum->disable_insertion_hook (); > + } > return nested_function_sum->get_create (node); > } > > @@ -124,6 +127,9 @@ nested_function_info::release () > void > maybe_record_nested_function (cgraph_node *node) > { > + /* All nested functions gets lowered during the construction of symtab. */ > + if (symtab->state > CONSTRUCTION) > + return; > if (DECL_CONTEXT (node->decl) > && TREE_CODE (DECL_CONTEXT (node->decl)) == FUNCTION_DECL) > { >
> > gcc/ChangeLog: > > * symbol-summary.h (function_summary_base::unregister_hooks): > Call disable_insertion_hook and disable_duplication_hook. > (function_summary_base::symtab_insertion): New field. > (function_summary_base::symtab_removal): Likewise. > (function_summary_base::symtab_duplication): Likewise. > Register hooks in function_summary_base and directly register > (or unregister) hooks. OK, thanks a lot! Honza > --- > gcc/symbol-summary.h | 127 ++++++++++++++++++++++--------------------- > 1 file changed, 65 insertions(+), 62 deletions(-) > > diff --git a/gcc/symbol-summary.h b/gcc/symbol-summary.h > index af5f4e6da62..97106c7c25b 100644 > --- a/gcc/symbol-summary.h > +++ b/gcc/symbol-summary.h > @@ -28,12 +28,22 @@ class function_summary_base > { > public: > /* Default construction takes SYMTAB as an argument. */ > - function_summary_base (symbol_table *symtab CXX_MEM_STAT_INFO): > - m_symtab (symtab), > - m_insertion_enabled (true), > - m_duplication_enabled (true), > + function_summary_base (symbol_table *symtab, > + cgraph_node_hook symtab_insertion, > + cgraph_node_hook symtab_removal, > + cgraph_2node_hook symtab_duplication > + CXX_MEM_STAT_INFO): > + m_symtab (symtab), m_symtab_insertion (symtab_insertion), > + m_symtab_removal (symtab_removal), > + m_symtab_duplication (symtab_duplication), > + m_symtab_insertion_hook (NULL), m_symtab_duplication_hook (NULL), > m_allocator ("function summary" PASS_MEM_STAT) > - {} > + { > + enable_insertion_hook (); > + m_symtab_removal_hook > + = m_symtab->add_cgraph_removal_hook (m_symtab_removal, this); > + enable_duplication_hook (); > + } > > /* Basic implementation of insert operation. */ > virtual void insert (cgraph_node *, T *) > @@ -56,25 +66,37 @@ public: > /* Enable insertion hook invocation. */ > void enable_insertion_hook () > { > - m_insertion_enabled = true; > + if (m_symtab_insertion_hook == NULL) > + m_symtab_insertion_hook > + = m_symtab->add_cgraph_insertion_hook (m_symtab_insertion, this); > } > > /* Enable insertion hook invocation. */ > void disable_insertion_hook () > { > - m_insertion_enabled = false; > + if (m_symtab_insertion_hook != NULL) > + { > + m_symtab->remove_cgraph_insertion_hook (m_symtab_insertion_hook); > + m_symtab_insertion_hook = NULL; > + } > } > > /* Enable duplication hook invocation. */ > void enable_duplication_hook () > { > - m_duplication_enabled = true; > + if (m_symtab_duplication_hook == NULL) > + m_symtab_duplication_hook > + = m_symtab->add_cgraph_duplication_hook (m_symtab_duplication, this); > } > > /* Enable duplication hook invocation. */ > void disable_duplication_hook () > { > - m_duplication_enabled = false; > + if (m_symtab_duplication_hook != NULL) > + { > + m_symtab->remove_cgraph_duplication_hook (m_symtab_duplication_hook); > + m_symtab_duplication_hook = NULL; > + } > } > > protected: > @@ -99,19 +121,22 @@ protected: > /* Unregister all call-graph hooks. */ > void unregister_hooks (); > > + /* Symbol table the summary is registered to. */ > + symbol_table *m_symtab; > + > + /* Insertion function defined by a summary. */ > + cgraph_node_hook m_symtab_insertion; > + /* Removal function defined by a summary. */ > + cgraph_node_hook m_symtab_removal; > + /* Duplication function defined by a summary. */ > + cgraph_2node_hook m_symtab_duplication; > + > /* Internal summary insertion hook pointer. */ > cgraph_node_hook_list *m_symtab_insertion_hook; > /* Internal summary removal hook pointer. */ > cgraph_node_hook_list *m_symtab_removal_hook; > /* Internal summary duplication hook pointer. */ > cgraph_2node_hook_list *m_symtab_duplication_hook; > - /* Symbol table the summary is registered to. */ > - symbol_table *m_symtab; > - > - /* Indicates if insertion hook is enabled. */ > - bool m_insertion_enabled; > - /* Indicates if duplication hook is enabled. */ > - bool m_duplication_enabled; > > private: > /* Return true when the summary uses GGC memory for allocation. */ > @@ -125,9 +150,9 @@ template <typename T> > void > function_summary_base<T>::unregister_hooks () > { > - m_symtab->remove_cgraph_insertion_hook (m_symtab_insertion_hook); > + disable_insertion_hook (); > m_symtab->remove_cgraph_removal_hook (m_symtab_removal_hook); > - m_symtab->remove_cgraph_duplication_hook (m_symtab_duplication_hook); > + disable_duplication_hook (); > } > > /* We want to pass just pointer types as argument for function_summary > @@ -242,19 +267,11 @@ private: > template <typename T> > function_summary<T *>::function_summary (symbol_table *symtab, bool ggc > MEM_STAT_DECL): > - function_summary_base<T> (symtab PASS_MEM_STAT), m_ggc (ggc), > - m_map (13, ggc, true, GATHER_STATISTICS PASS_MEM_STAT) > -{ > - this->m_symtab_insertion_hook > - = this->m_symtab->add_cgraph_insertion_hook (function_summary::symtab_insertion, > - this); > - this->m_symtab_removal_hook > - = this->m_symtab->add_cgraph_removal_hook (function_summary::symtab_removal, > - this); > - this->m_symtab_duplication_hook > - = this->m_symtab->add_cgraph_duplication_hook (function_summary::symtab_duplication, > - this); > -} > + function_summary_base<T> (symtab, function_summary::symtab_insertion, > + function_summary::symtab_removal, > + function_summary::symtab_duplication > + PASS_MEM_STAT), > + m_ggc (ggc), m_map (13, ggc, true, GATHER_STATISTICS PASS_MEM_STAT) {} > > template <typename T> > function_summary<T *>::~function_summary () > @@ -273,9 +290,7 @@ function_summary<T *>::symtab_insertion (cgraph_node *node, void *data) > { > gcc_checking_assert (node->get_uid ()); > function_summary *summary = (function_summary <T *> *) (data); > - > - if (summary->m_insertion_enabled) > - summary->insert (node, summary->get_create (node)); > + summary->insert (node, summary->get_create (node)); > } > > template <typename T> > @@ -293,13 +308,10 @@ function_summary<T *>::symtab_duplication (cgraph_node *node, > cgraph_node *node2, void *data) > { > function_summary *summary = (function_summary <T *> *) (data); > - if (summary->m_duplication_enabled) > - { > - T *v = summary->get (node); > + T *v = summary->get (node); > > - if (v) > - summary->duplicate (node, node2, v, summary->get_create (node2)); > - } > + if (v) > + summary->duplicate (node, node2, v, summary->get_create (node2)); > } > > template <typename T> > @@ -439,19 +451,15 @@ private: > }; > > template <typename T, typename V> > -fast_function_summary<T *, V>::fast_function_summary (symbol_table *symtab MEM_STAT_DECL): > - function_summary_base<T> (symtab PASS_MEM_STAT), m_vector (NULL) > +fast_function_summary<T *, V>::fast_function_summary (symbol_table *symtab > + MEM_STAT_DECL): > + function_summary_base<T> (symtab, > + fast_function_summary::symtab_insertion, > + fast_function_summary::symtab_removal, > + fast_function_summary::symtab_duplication > + PASS_MEM_STAT), m_vector (NULL) > { > vec_alloc (m_vector, 13 PASS_MEM_STAT); > - this->m_symtab_insertion_hook > - = this->m_symtab->add_cgraph_insertion_hook (fast_function_summary::symtab_insertion, > - this); > - this->m_symtab_removal_hook > - = this->m_symtab->add_cgraph_removal_hook (fast_function_summary::symtab_removal, > - this); > - this->m_symtab_duplication_hook > - = this->m_symtab->add_cgraph_duplication_hook (fast_function_summary::symtab_duplication, > - this); > } > > template <typename T, typename V> > @@ -472,9 +480,7 @@ fast_function_summary<T *, V>::symtab_insertion (cgraph_node *node, void *data) > { > gcc_checking_assert (node->get_uid ()); > fast_function_summary *summary = (fast_function_summary <T *, V> *) (data); > - > - if (summary->m_insertion_enabled) > - summary->insert (node, summary->get_create (node)); > + summary->insert (node, summary->get_create (node)); > } > > template <typename T, typename V> > @@ -495,15 +501,12 @@ fast_function_summary<T *, V>::symtab_duplication (cgraph_node *node, > void *data) > { > fast_function_summary *summary = (fast_function_summary <T *, V> *) (data); > - if (summary->m_duplication_enabled) > - { > - T *v = summary->get (node); > + T *v = summary->get (node); > > - if (v) > - { > - T *duplicate = summary->get_create (node2); > - summary->duplicate (node, node2, v, duplicate); > - } > + if (v) > + { > + T *duplicate = summary->get_create (node2); > + summary->duplicate (node, node2, v, duplicate); > } > } > > -- > 2.29.0 > > From 8bf1464ee2d43a14e4d6ed8d11e3b7e2d15b46e4 Mon Sep 17 00:00:00 2001 > From: Martin Liska <mliska@suse.cz> > Date: Mon, 26 Oct 2020 15:24:28 +0100 > Subject: [PATCH 2/2] call_summary: move hooks to base. > > gcc/ChangeLog: > > * symbol-summary.h (call_summary_base): Pass symtab hooks to > base and register (or unregister) hooks directly. > --- > gcc/symbol-summary.h | 98 ++++++++++++++++++++++---------------------- > 1 file changed, 48 insertions(+), 50 deletions(-) > > diff --git a/gcc/symbol-summary.h b/gcc/symbol-summary.h > index 97106c7c25b..3944f11c78a 100644 > --- a/gcc/symbol-summary.h > +++ b/gcc/symbol-summary.h > @@ -566,12 +566,17 @@ class call_summary_base > { > public: > /* Default construction takes SYMTAB as an argument. */ > - call_summary_base (symbol_table *symtab CXX_MEM_STAT_INFO): > - m_symtab (symtab), > + call_summary_base (symbol_table *symtab, cgraph_edge_hook symtab_removal, > + cgraph_2edge_hook symtab_duplication CXX_MEM_STAT_INFO): > + m_symtab (symtab), m_symtab_removal (symtab_removal), > + m_symtab_duplication (symtab_duplication), m_symtab_duplication_hook (NULL), > m_initialize_when_cloning (false), > - m_duplication_enabled (true), > m_allocator ("call summary" PASS_MEM_STAT) > - {} > + { > + m_symtab_removal_hook > + = m_symtab->add_edge_removal_hook (m_symtab_removal, this); > + enable_duplication_hook (); > + } > > /* Basic implementation of removal operation. */ > virtual void remove (cgraph_edge *, T *) {} > @@ -585,13 +590,20 @@ public: > /* Enable duplication hook invocation. */ > void enable_duplication_hook () > { > - m_duplication_enabled = true; > + if (m_symtab_duplication_hook == NULL) > + m_symtab_duplication_hook > + = m_symtab->add_edge_duplication_hook (m_symtab_duplication, > + this); > } > > /* Enable duplication hook invocation. */ > void disable_duplication_hook () > { > - m_duplication_enabled = false; > + if (m_symtab_duplication_hook != NULL) > + { > + m_symtab->remove_edge_duplication_hook (m_symtab_duplication_hook); > + m_symtab_duplication_hook = NULL; > + } > } > > protected: > @@ -619,14 +631,17 @@ protected: > /* Symbol table the summary is registered to. */ > symbol_table *m_symtab; > > + /* Removal function defined by a summary. */ > + cgraph_edge_hook m_symtab_removal; > + /* Duplication function defined by a summary. */ > + cgraph_2edge_hook m_symtab_duplication; > + > /* Internal summary removal hook pointer. */ > cgraph_edge_hook_list *m_symtab_removal_hook; > /* Internal summary duplication hook pointer. */ > cgraph_2edge_hook_list *m_symtab_duplication_hook; > /* Initialize summary for an edge that is cloned. */ > bool m_initialize_when_cloning; > - /* Indicates if duplication hook is enabled. */ > - bool m_duplication_enabled; > > private: > /* Return true when the summary uses GGC memory for allocation. */ > @@ -641,7 +656,7 @@ void > call_summary_base<T>::unregister_hooks () > { > m_symtab->remove_edge_removal_hook (m_symtab_removal_hook); > - m_symtab->remove_edge_duplication_hook (m_symtab_duplication_hook); > + disable_duplication_hook (); > } > > /* An impossible class templated by non-pointers so, which makes sure that only > @@ -663,16 +678,9 @@ public: > /* Default construction takes SYMTAB as an argument. */ > call_summary (symbol_table *symtab, bool ggc = false > CXX_MEM_STAT_INFO) > - : call_summary_base<T> (symtab PASS_MEM_STAT), m_ggc (ggc), > - m_map (13, ggc, true, GATHER_STATISTICS PASS_MEM_STAT) > - { > - this->m_symtab_removal_hook > - = this->m_symtab->add_edge_removal_hook (call_summary::symtab_removal, > - this); > - this->m_symtab_duplication_hook > - = this->m_symtab->add_edge_duplication_hook (call_summary::symtab_duplication, > - this); > - } > + : call_summary_base<T> (symtab, call_summary::symtab_removal, > + call_summary::symtab_duplication PASS_MEM_STAT), > + m_ggc (ggc), m_map (13, ggc, true, GATHER_STATISTICS PASS_MEM_STAT) {} > > /* Destructor. */ > virtual ~call_summary (); > @@ -777,19 +785,16 @@ call_summary<T *>::symtab_duplication (cgraph_edge *edge1, > cgraph_edge *edge2, void *data) > { > call_summary *summary = (call_summary <T *> *) (data); > - if (summary->m_duplication_enabled) > - { > - T *edge1_summary = NULL; > + T *edge1_summary = NULL; > > - if (summary->m_initialize_when_cloning) > - edge1_summary = summary->get_create (edge1); > - else > - edge1_summary = summary->get (edge1); > + if (summary->m_initialize_when_cloning) > + edge1_summary = summary->get_create (edge1); > + else > + edge1_summary = summary->get (edge1); > > - if (edge1_summary) > - summary->duplicate (edge1, edge2, edge1_summary, > - summary->get_create (edge2)); > - } > + if (edge1_summary) > + summary->duplicate (edge1, edge2, edge1_summary, > + summary->get_create (edge2)); > } > > template <typename T> > @@ -833,15 +838,11 @@ class GTY((user)) fast_call_summary <T *, V>: public call_summary_base<T> > public: > /* Default construction takes SYMTAB as an argument. */ > fast_call_summary (symbol_table *symtab CXX_MEM_STAT_INFO) > - : call_summary_base<T> (symtab PASS_MEM_STAT), m_vector (NULL) > + : call_summary_base<T> (symtab, fast_call_summary::symtab_removal, > + fast_call_summary::symtab_duplication PASS_MEM_STAT), > + m_vector (NULL) > { > vec_alloc (m_vector, 13 PASS_MEM_STAT); > - this->m_symtab_removal_hook > - = this->m_symtab->add_edge_removal_hook (fast_call_summary::symtab_removal, > - this); > - this->m_symtab_duplication_hook > - = this->m_symtab->add_edge_duplication_hook (fast_call_summary::symtab_duplication, > - this); > } > > /* Destructor. */ > @@ -946,20 +947,17 @@ fast_call_summary<T *, V>::symtab_duplication (cgraph_edge *edge1, > cgraph_edge *edge2, void *data) > { > fast_call_summary *summary = (fast_call_summary <T *, V> *) (data); > - if (summary->m_duplication_enabled) > + T *edge1_summary = NULL; > + > + if (summary->m_initialize_when_cloning) > + edge1_summary = summary->get_create (edge1); > + else > + edge1_summary = summary->get (edge1); > + > + if (edge1_summary) > { > - T *edge1_summary = NULL; > - > - if (summary->m_initialize_when_cloning) > - edge1_summary = summary->get_create (edge1); > - else > - edge1_summary = summary->get (edge1); > - > - if (edge1_summary) > - { > - T *duplicate = summary->get_create (edge2); > - summary->duplicate (edge1, edge2, edge1_summary, duplicate); > - } > + T *duplicate = summary->get_create (edge2); > + summary->duplicate (edge1, edge2, edge1_summary, duplicate); > } > } > > -- > 2.29.0 >
diff --git a/gcc/cgraph.h b/gcc/cgraph.h index 9eb48d5b62f..65e4646efcd 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -1402,7 +1402,7 @@ struct GTY((tag ("SYMTAB_FUNCTION"))) cgraph_node : public symtab_node /* Interprocedural passes scheduled to have their transform functions applied next time we execute local pass on them. We maintain it per-function in order to allow IPA passes to introduce new functions. */ - vec<ipa_opt_pass> GTY((skip)) ipa_transforms_to_apply; + vec<ipa_opt_pass, va_heap, vl_ptr> GTY((skip)) ipa_transforms_to_apply; /* For inline clones this points to the function they will be inlined into. */ diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c index acbf82e84d9..bd0e322605f 100644 --- a/gcc/ipa-inline-analysis.c +++ b/gcc/ipa-inline-analysis.c @@ -127,6 +127,9 @@ initialize_growth_caches () = new fast_call_summary<edge_growth_cache_entry *, va_heap> (symtab); node_context_cache = new fast_function_summary<node_context_summary *, va_heap> (symtab); + edge_growth_cache->disable_duplication_hook (); + node_context_cache->disable_insertion_hook (); + node_context_cache->disable_duplication_hook (); } /* Free growth caches. */ diff --git a/gcc/ipa-inline-transform.c b/gcc/ipa-inline-transform.c index 3782cce12e3..279ba2f7cb0 100644 --- a/gcc/ipa-inline-transform.c +++ b/gcc/ipa-inline-transform.c @@ -231,6 +231,11 @@ clone_inlined_nodes (struct cgraph_edge *e, bool duplicate, e->callee->remove_from_same_comdat_group (); e->callee->inlined_to = inlining_into; + if (e->callee->ipa_transforms_to_apply.length ()) + { + e->callee->ipa_transforms_to_apply.release (); + e->callee->ipa_transforms_to_apply = vNULL; + } /* Recursively clone all bodies. */ for (e = e->callee->callees; e; e = next) @@ -606,7 +611,10 @@ save_inline_function_body (struct cgraph_node *node) tree prev_body_holder = node->decl; if (!ipa_saved_clone_sources) - ipa_saved_clone_sources = new function_summary <tree *> (symtab); + { + ipa_saved_clone_sources = new function_summary <tree *> (symtab); + ipa_saved_clone_sources->disable_insertion_hook (); + } else { tree *p = ipa_saved_clone_sources->get (node); diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index a848f1db95e..6014766b418 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -4211,7 +4211,10 @@ ipcp_transformation_initialize (void) if (!ipa_vr_hash_table) ipa_vr_hash_table = hash_table<ipa_vr_ggc_hash_traits>::create_ggc (37); if (ipcp_transformation_sum == NULL) - ipcp_transformation_sum = ipcp_transformation_t::create_ggc (symtab); + { + ipcp_transformation_sum = ipcp_transformation_t::create_ggc (symtab); + ipcp_transformation_sum->disable_insertion_hook (); + } } /* Release the IPA CP transformation summary. */ diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h index 0bbbbf9bd9f..77e92b04bba 100644 --- a/gcc/ipa-prop.h +++ b/gcc/ipa-prop.h @@ -941,7 +941,10 @@ class GTY((user)) ipa_node_params_t: public function_summary <ipa_node_params *> { public: ipa_node_params_t (symbol_table *table, bool ggc): - function_summary<ipa_node_params *> (table, ggc) { } + function_summary<ipa_node_params *> (table, ggc) + { + disable_insertion_hook (); + } /* Hook that is called by summary when a node is duplicated. */ virtual void duplicate (cgraph_node *node, diff --git a/gcc/ipa-reference.c b/gcc/ipa-reference.c index 4a6c011c525..ced83d218ab 100644 --- a/gcc/ipa-reference.c +++ b/gcc/ipa-reference.c @@ -894,7 +894,10 @@ propagate (void) } if (ipa_ref_opt_sum_summaries == NULL) - ipa_ref_opt_sum_summaries = new ipa_ref_opt_summary_t (symtab); + { + ipa_ref_opt_sum_summaries = new ipa_ref_opt_summary_t (symtab); + ipa_ref_opt_sum_summaries->disable_insertion_hook (); + } /* Cleanup. */ FOR_EACH_DEFINED_FUNCTION (node) diff --git a/gcc/ipa-sra.c b/gcc/ipa-sra.c index 8d4f580e009..07227c0bfec 100644 --- a/gcc/ipa-sra.c +++ b/gcc/ipa-sra.c @@ -85,6 +85,8 @@ along with GCC; see the file COPYING3. If not see #include "tree-streamer.h" #include "internal-fn.h" +static void ipa_sra_summarize_function (cgraph_node *); + /* Bits used to track size of an aggregate in bytes interprocedurally. */ #define ISRA_ARG_SIZE_LIMIT_BITS 16 #define ISRA_ARG_SIZE_LIMIT (1 << ISRA_ARG_SIZE_LIMIT_BITS) @@ -373,6 +375,7 @@ public: virtual void duplicate (cgraph_node *, cgraph_node *, isra_func_summary *old_sum, isra_func_summary *new_sum); + virtual void insert (cgraph_node *, isra_func_summary *); }; /* Hook that is called by summary when a node is duplicated. */ @@ -426,6 +429,21 @@ ipa_sra_function_summaries::duplicate (cgraph_node *, cgraph_node *, static GTY(()) ipa_sra_function_summaries *func_sums; +/* Hook that is called by summary when new node appears. */ + +void +ipa_sra_function_summaries::insert (cgraph_node *node, isra_func_summary *) +{ + if (opt_for_fn (node->decl, flag_ipa_sra)) + { + push_cfun (DECL_STRUCT_FUNCTION (node->decl)); + ipa_sra_summarize_function (node); + pop_cfun (); + } + else + func_sums->remove (node); +} + /* Class to manage call summaries. */ class ipa_sra_call_summaries: public call_summary <isra_call_summary *> @@ -2478,79 +2496,6 @@ verify_splitting_accesses (cgraph_node *node, bool certain_must_exist) } } -/* Intraprocedural part of IPA-SRA analysis. Scan function body of NODE and - create a summary structure describing IPA-SRA opportunities and constraints - in it. */ - -static void -ipa_sra_summarize_function (cgraph_node *node) -{ - if (dump_file) - fprintf (dump_file, "Creating summary for %s/%i:\n", node->name (), - node->order); - if (!ipa_sra_preliminary_function_checks (node)) - return; - gcc_obstack_init (&gensum_obstack); - isra_func_summary *ifs = func_sums->get_create (node); - ifs->m_candidate = true; - tree ret = TREE_TYPE (TREE_TYPE (node->decl)); - ifs->m_returns_value = (TREE_CODE (ret) != VOID_TYPE); - - decl2desc = new hash_map<tree, gensum_param_desc *>; - unsigned count = 0; - for (tree parm = DECL_ARGUMENTS (node->decl); parm; parm = DECL_CHAIN (parm)) - count++; - - if (count > 0) - { - auto_vec<gensum_param_desc, 16> param_descriptions (count); - param_descriptions.reserve_exact (count); - param_descriptions.quick_grow_cleared (count); - - bool cfun_pushed = false; - struct function *fun = DECL_STRUCT_FUNCTION (node->decl); - if (create_parameter_descriptors (node, ¶m_descriptions)) - { - push_cfun (fun); - cfun_pushed = true; - final_bbs = BITMAP_ALLOC (NULL); - bb_dereferences = XCNEWVEC (HOST_WIDE_INT, - by_ref_count - * last_basic_block_for_fn (fun)); - aa_walking_limit = opt_for_fn (node->decl, param_ipa_max_aa_steps); - scan_function (node, fun); - - if (dump_file) - { - dump_gensum_param_descriptors (dump_file, node->decl, - ¶m_descriptions); - fprintf (dump_file, "----------------------------------------\n"); - } - } - process_scan_results (node, fun, ifs, ¶m_descriptions); - - if (cfun_pushed) - pop_cfun (); - if (bb_dereferences) - { - free (bb_dereferences); - bb_dereferences = NULL; - BITMAP_FREE (final_bbs); - final_bbs = NULL; - } - } - isra_analyze_all_outgoing_calls (node); - - delete decl2desc; - decl2desc = NULL; - obstack_free (&gensum_obstack, NULL); - if (dump_file) - fprintf (dump_file, "\n\n"); - if (flag_checking) - verify_splitting_accesses (node, false); - return; -} - /* Intraprocedural part of IPA-SRA analysis. Scan bodies of all functions in this compilation unit and create summary structures describing IPA-SRA opportunities and constraints in them. */ @@ -4102,6 +4047,79 @@ public: } // anon namespace +/* Intraprocedural part of IPA-SRA analysis. Scan function body of NODE and + create a summary structure describing IPA-SRA opportunities and constraints + in it. */ + +static void +ipa_sra_summarize_function (cgraph_node *node) +{ + if (dump_file) + fprintf (dump_file, "Creating summary for %s/%i:\n", node->name (), + node->order); + if (!ipa_sra_preliminary_function_checks (node)) + return; + gcc_obstack_init (&gensum_obstack); + isra_func_summary *ifs = func_sums->get_create (node); + ifs->m_candidate = true; + tree ret = TREE_TYPE (TREE_TYPE (node->decl)); + ifs->m_returns_value = (TREE_CODE (ret) != VOID_TYPE); + + decl2desc = new hash_map<tree, gensum_param_desc *>; + unsigned count = 0; + for (tree parm = DECL_ARGUMENTS (node->decl); parm; parm = DECL_CHAIN (parm)) + count++; + + if (count > 0) + { + auto_vec<gensum_param_desc, 16> param_descriptions (count); + param_descriptions.reserve_exact (count); + param_descriptions.quick_grow_cleared (count); + + bool cfun_pushed = false; + struct function *fun = DECL_STRUCT_FUNCTION (node->decl); + if (create_parameter_descriptors (node, ¶m_descriptions)) + { + push_cfun (fun); + cfun_pushed = true; + final_bbs = BITMAP_ALLOC (NULL); + bb_dereferences = XCNEWVEC (HOST_WIDE_INT, + by_ref_count + * last_basic_block_for_fn (fun)); + aa_walking_limit = opt_for_fn (node->decl, param_ipa_max_aa_steps); + scan_function (node, fun); + + if (dump_file) + { + dump_gensum_param_descriptors (dump_file, node->decl, + ¶m_descriptions); + fprintf (dump_file, "----------------------------------------\n"); + } + } + process_scan_results (node, fun, ifs, ¶m_descriptions); + + if (cfun_pushed) + pop_cfun (); + if (bb_dereferences) + { + free (bb_dereferences); + bb_dereferences = NULL; + BITMAP_FREE (final_bbs); + final_bbs = NULL; + } + } + isra_analyze_all_outgoing_calls (node); + + delete decl2desc; + decl2desc = NULL; + obstack_free (&gensum_obstack, NULL); + if (dump_file) + fprintf (dump_file, "\n\n"); + if (flag_checking) + verify_splitting_accesses (node, false); + return; +} + ipa_opt_pass_d * make_pass_ipa_sra (gcc::context *ctxt) { diff --git a/gcc/passes.c b/gcc/passes.c index 1942b7cd1c3..02a47e2595c 100644 --- a/gcc/passes.c +++ b/gcc/passes.c @@ -2566,7 +2566,8 @@ execute_one_pass (opt_pass *pass) { struct cgraph_node *node; FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node) - node->ipa_transforms_to_apply.safe_push ((ipa_opt_pass_d *)pass); + if (!node->inlined_to) + node->ipa_transforms_to_apply.safe_push ((ipa_opt_pass_d *)pass); } else if (dump_file) do_per_function (execute_function_dump, pass); diff --git a/gcc/symbol-summary.h b/gcc/symbol-summary.h index a38eb1db778..af5f4e6da62 100644 --- a/gcc/symbol-summary.h +++ b/gcc/symbol-summary.h @@ -31,17 +31,27 @@ public: function_summary_base (symbol_table *symtab CXX_MEM_STAT_INFO): m_symtab (symtab), m_insertion_enabled (true), + m_duplication_enabled (true), m_allocator ("function summary" PASS_MEM_STAT) {} /* Basic implementation of insert operation. */ - virtual void insert (cgraph_node *, T *) {} + virtual void insert (cgraph_node *, T *) + { + /* In most cases, it makes no sense to create summaries without + initializing them. */ + gcc_unreachable (); + } /* Basic implementation of removal operation. */ virtual void remove (cgraph_node *, T *) {} /* Basic implementation of duplication operation. */ - virtual void duplicate (cgraph_node *, cgraph_node *, T *, T *) {} + virtual void duplicate (cgraph_node *, cgraph_node *, T *, T *) + { + /* It makes no sense to not copy anything during duplication. */ + gcc_unreachable (); + } /* Enable insertion hook invocation. */ void enable_insertion_hook () @@ -55,6 +65,18 @@ public: m_insertion_enabled = false; } + /* Enable duplication hook invocation. */ + void enable_duplication_hook () + { + m_duplication_enabled = true; + } + + /* Enable duplication hook invocation. */ + void disable_duplication_hook () + { + m_duplication_enabled = false; + } + protected: /* Allocates new data that are stored within map. */ T* allocate_new () @@ -88,6 +110,8 @@ protected: /* Indicates if insertion hook is enabled. */ bool m_insertion_enabled; + /* Indicates if duplication hook is enabled. */ + bool m_duplication_enabled; private: /* Return true when the summary uses GGC memory for allocation. */ @@ -269,10 +293,13 @@ function_summary<T *>::symtab_duplication (cgraph_node *node, cgraph_node *node2, void *data) { function_summary *summary = (function_summary <T *> *) (data); - T *v = summary->get (node); + if (summary->m_duplication_enabled) + { + T *v = summary->get (node); - if (v) - summary->duplicate (node, node2, v, summary->get_create (node2)); + if (v) + summary->duplicate (node, node2, v, summary->get_create (node2)); + } } template <typename T> @@ -468,12 +495,15 @@ fast_function_summary<T *, V>::symtab_duplication (cgraph_node *node, void *data) { fast_function_summary *summary = (fast_function_summary <T *, V> *) (data); - T *v = summary->get (node); - - if (v) + if (summary->m_duplication_enabled) { - T *duplicate = summary->get_create (node2); - summary->duplicate (node, node2, v, duplicate); + T *v = summary->get (node); + + if (v) + { + T *duplicate = summary->get_create (node2); + summary->duplicate (node, node2, v, duplicate); + } } } @@ -536,6 +566,7 @@ public: call_summary_base (symbol_table *symtab CXX_MEM_STAT_INFO): m_symtab (symtab), m_initialize_when_cloning (false), + m_duplication_enabled (true), m_allocator ("call summary" PASS_MEM_STAT) {} @@ -543,7 +574,22 @@ public: virtual void remove (cgraph_edge *, T *) {} /* Basic implementation of duplication operation. */ - virtual void duplicate (cgraph_edge *, cgraph_edge *, T *, T *) {} + virtual void duplicate (cgraph_edge *, cgraph_edge *, T *, T *) + { + gcc_unreachable (); + } + + /* Enable duplication hook invocation. */ + void enable_duplication_hook () + { + m_duplication_enabled = true; + } + + /* Enable duplication hook invocation. */ + void disable_duplication_hook () + { + m_duplication_enabled = false; + } protected: /* Allocates new data that are stored within map. */ @@ -576,6 +622,8 @@ protected: cgraph_2edge_hook_list *m_symtab_duplication_hook; /* Initialize summary for an edge that is cloned. */ bool m_initialize_when_cloning; + /* Indicates if duplication hook is enabled. */ + bool m_duplication_enabled; private: /* Return true when the summary uses GGC memory for allocation. */ @@ -726,16 +774,19 @@ call_summary<T *>::symtab_duplication (cgraph_edge *edge1, cgraph_edge *edge2, void *data) { call_summary *summary = (call_summary <T *> *) (data); - T *edge1_summary = NULL; + if (summary->m_duplication_enabled) + { + T *edge1_summary = NULL; - if (summary->m_initialize_when_cloning) - edge1_summary = summary->get_create (edge1); - else - edge1_summary = summary->get (edge1); + if (summary->m_initialize_when_cloning) + edge1_summary = summary->get_create (edge1); + else + edge1_summary = summary->get (edge1); - if (edge1_summary) - summary->duplicate (edge1, edge2, edge1_summary, - summary->get_create (edge2)); + if (edge1_summary) + summary->duplicate (edge1, edge2, edge1_summary, + summary->get_create (edge2)); + } } template <typename T> @@ -892,17 +943,20 @@ fast_call_summary<T *, V>::symtab_duplication (cgraph_edge *edge1, cgraph_edge *edge2, void *data) { fast_call_summary *summary = (fast_call_summary <T *, V> *) (data); - T *edge1_summary = NULL; - - if (summary->m_initialize_when_cloning) - edge1_summary = summary->get_create (edge1); - else - edge1_summary = summary->get (edge1); - - if (edge1_summary) + if (summary->m_duplication_enabled) { - T *duplicate = summary->get_create (edge2); - summary->duplicate (edge1, edge2, edge1_summary, duplicate); + T *edge1_summary = NULL; + + if (summary->m_initialize_when_cloning) + edge1_summary = summary->get_create (edge1); + else + edge1_summary = summary->get (edge1); + + if (edge1_summary) + { + T *duplicate = summary->get_create (edge2); + summary->duplicate (edge1, edge2, edge1_summary, duplicate); + } } } diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c index 788883faa4c..9cb4a08e2d9 100644 --- a/gcc/tree-nested.c +++ b/gcc/tree-nested.c @@ -65,8 +65,11 @@ nested_function_info * nested_function_info::get_create (cgraph_node *node) { if (!nested_function_sum) - nested_function_sum = new function_summary <nested_function_info *> - (symtab); + { + nested_function_sum = new function_summary <nested_function_info *> + (symtab); + nested_function_sum->disable_insertion_hook (); + } return nested_function_sum->get_create (node); } @@ -124,6 +127,9 @@ nested_function_info::release () void maybe_record_nested_function (cgraph_node *node) { + /* All nested functions gets lowered during the construction of symtab. */ + if (symtab->state > CONSTRUCTION) + return; if (DECL_CONTEXT (node->decl) && TREE_CODE (DECL_CONTEXT (node->decl)) == FUNCTION_DECL) {