diff options
-rw-r--r-- | gcc/cgraph.h | 2 | ||||
-rw-r--r-- | gcc/ipa-inline-analysis.c | 3 | ||||
-rw-r--r-- | gcc/ipa-inline-transform.c | 10 | ||||
-rw-r--r-- | gcc/ipa-prop.c | 5 | ||||
-rw-r--r-- | gcc/ipa-prop.h | 5 | ||||
-rw-r--r-- | gcc/ipa-reference.c | 6 | ||||
-rw-r--r-- | gcc/ipa-sra.c | 164 | ||||
-rw-r--r-- | gcc/passes.c | 3 | ||||
-rw-r--r-- | gcc/symbol-summary.h | 112 | ||||
-rw-r--r-- | gcc/tree-nested.c | 10 |
10 files changed, 210 insertions, 110 deletions
diff --git a/gcc/cgraph.h b/gcc/cgraph.h index 9eb48d5..65e4646 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 acbf82e..bd0e322 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 3782cce..279ba2f 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 a848f1d..6014766 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 0bbbbf9..77e92b0 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 4a6c011..871c997 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) @@ -1130,6 +1133,7 @@ ipa_reference_read_optimization_summary (void) gcc_checking_assert (ipa_ref_opt_sum_summaries == NULL); ipa_ref_opt_sum_summaries = new ipa_ref_opt_summary_t (symtab); + ipa_ref_opt_sum_summaries->disable_insertion_hook (); ipa_reference_vars_map = new reference_vars_map_t(257); varpool_node_hooks = symtab->add_varpool_removal_hook (varpool_removal_hook, NULL); diff --git a/gcc/ipa-sra.c b/gcc/ipa-sra.c index 8d4f580..07227c0 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 1942b7c..02a47e2 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 a38eb1d..af5f4e6 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 788883f..9cb4a08 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) { |