diff options
author | Jan Hubicka <hubicka@ucw.cz> | 2018-11-20 14:25:04 +0100 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2018-11-20 13:25:04 +0000 |
commit | 12485662c00914ed132d950f1329fdaf32c11a3c (patch) | |
tree | 915c311dd930a542e608132872f89e56f2d114e0 /gcc | |
parent | 8c944c97a2e5a264779ad1d448f97319f471275a (diff) | |
download | gcc-12485662c00914ed132d950f1329fdaf32c11a3c.zip gcc-12485662c00914ed132d950f1329fdaf32c11a3c.tar.gz gcc-12485662c00914ed132d950f1329fdaf32c11a3c.tar.bz2 |
re PR ipa/87706 (Inlined functions trigger invalid -Wmissing-profile warning)
PR ipa/87706
* ipa-fnsummary.c (pass_ipa_fnsummary): Do not remove functions
* ipa.c (possible_inline_candidate_p): Break out from ..
(process_references): ... here ; drop before_inlining_p;
cleanup handling of alises.
(walk_polymorphic_call_targets): Likewise.
(symbol_table::remove_unreachable_nodes): Likewise.
* passes.c (pass_data_ipa_remove_symbols): New structure.
(pass_ipa_remove_symbols): New pass.
(make_pass_ipa_remove_symbols): New functoin.
* passes.def (pass_ipa_remove_symbols): Schedule after early passes.
From-SVN: r266315
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/ipa-fnsummary.c | 5 | ||||
-rw-r--r-- | gcc/ipa.c | 59 | ||||
-rw-r--r-- | gcc/passes.c | 35 | ||||
-rw-r--r-- | gcc/passes.def | 1 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/ipa/ctor-empty-1.c | 4 |
7 files changed, 89 insertions, 34 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5a18ba9..44ca2ce 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2018-11-20 Jan Hubicka <hubicka@ucw.cz> + + PR ipa/87706 + * ipa-fnsummary.c (pass_ipa_fnsummary): Do not remove functions + * ipa.c (possible_inline_candidate_p): Break out from .. + (process_references): ... here ; drop before_inlining_p; + cleanup handling of alises. + (walk_polymorphic_call_targets): Likewise. + (symbol_table::remove_unreachable_nodes): Likewise. + * passes.c (pass_data_ipa_remove_symbols): New structure. + (pass_ipa_remove_symbols): New pass. + (make_pass_ipa_remove_symbols): New functoin. + * passes.def (pass_ipa_remove_symbols): Schedule after early passes. + 2018-11-20 Richard Biener <rguenther@suse.de> * tree-vect-stmts.c (vectorizable_condition): Do not get diff --git a/gcc/ipa-fnsummary.c b/gcc/ipa-fnsummary.c index 9cb7d41..23b7821 100644 --- a/gcc/ipa-fnsummary.c +++ b/gcc/ipa-fnsummary.c @@ -3563,10 +3563,7 @@ public: virtual unsigned int execute (function *) { ipa_free_fn_summary (); - /* Early optimizations may make function unreachable. We can not - remove unreachable functions as part of the early opts pass because - TODOs are run before subpasses. Do it here. */ - return small_p ? TODO_remove_functions | TODO_dump_symtab : 0; + return 0; } private: @@ -101,12 +101,32 @@ enqueue_node (symtab_node *node, symtab_node **first, *first = node; } +/* Return true if NODE may get inlined later. + This is used to keep DECL_EXTERNAL function bodies around long enough + so inliner can proces them. */ + +static bool +possible_inline_candidate_p (symtab_node *node) +{ + if (symtab->state >= IPA_SSA_AFTER_INLINING) + return false; + cgraph_node *cnode = dyn_cast <cgraph_node *> (node); + if (!cnode) + return false; + if (DECL_UNINLINABLE (cnode->decl)) + return false; + if (opt_for_fn (cnode->decl, optimize)) + return true; + if (symtab->state >= IPA_SSA) + return false; + return lookup_attribute ("always_inline", DECL_ATTRIBUTES (node->decl)); +} + /* Process references. */ static void process_references (symtab_node *snode, symtab_node **first, - bool before_inlining_p, hash_set<symtab_node *> *reachable) { int i; @@ -118,14 +138,7 @@ process_references (symtab_node *snode, if (node->definition && !node->in_other_partition && ((!DECL_EXTERNAL (node->decl) || node->alias) - || (((before_inlining_p - && (TREE_CODE (node->decl) != FUNCTION_DECL - || (TREE_CODE (node->decl) == FUNCTION_DECL - && opt_for_fn (body->decl, optimize)) - || (symtab->state < IPA_SSA - && lookup_attribute - ("always_inline", - DECL_ATTRIBUTES (body->decl)))))) + || (possible_inline_candidate_p (node) /* We use variable constructors during late compilation for constant folding. Keep references alive so partitioning knows about potential references. */ @@ -140,7 +153,7 @@ process_references (symtab_node *snode, body. */ if (DECL_EXTERNAL (node->decl) && node->alias - && before_inlining_p) + && symtab->state < IPA_SSA_AFTER_INLINING) reachable->add (body); reachable->add (node); } @@ -160,8 +173,7 @@ static void walk_polymorphic_call_targets (hash_set<void *> *reachable_call_targets, struct cgraph_edge *edge, symtab_node **first, - hash_set<symtab_node *> *reachable, - bool before_inlining_p) + hash_set<symtab_node *> *reachable) { unsigned int i; void *cache_token; @@ -190,15 +202,14 @@ walk_polymorphic_call_targets (hash_set<void *> *reachable_call_targets, /* Prior inlining, keep alive bodies of possible targets for devirtualization. */ if (n->definition - && (before_inlining_p - && opt_for_fn (body->decl, optimize) + && (possible_inline_candidate_p (body) && opt_for_fn (body->decl, flag_devirtualize))) { /* Be sure that we will not optimize out alias target body. */ if (DECL_EXTERNAL (n->decl) && n->alias - && before_inlining_p) + && symtab->state < IPA_SSA_AFTER_INLINING) reachable->add (body); reachable->add (n); } @@ -303,8 +314,6 @@ symbol_table::remove_unreachable_nodes (FILE *file) hash_set<symtab_node *> reachable; hash_set<tree> body_needed_for_clonning; hash_set<void *> reachable_call_targets; - bool before_inlining_p = symtab->state < (!optimize && !in_lto_p ? IPA_SSA - : IPA_SSA_AFTER_INLINING); timevar_push (TV_IPA_UNREACHABLE); build_type_inheritance_graph (); @@ -396,7 +405,7 @@ symbol_table::remove_unreachable_nodes (FILE *file) enqueue_node (next, &first, &reachable); } /* Mark references as reachable. */ - process_references (node, &first, before_inlining_p, &reachable); + process_references (node, &first, &reachable); } if (cgraph_node *cnode = dyn_cast <cgraph_node *> (node)) @@ -416,8 +425,7 @@ symbol_table::remove_unreachable_nodes (FILE *file) next = e->next_callee; if (e->indirect_info->polymorphic) walk_polymorphic_call_targets (&reachable_call_targets, - e, &first, &reachable, - before_inlining_p); + e, &first, &reachable); } } for (e = cnode->callees; e; e = e->next_callee) @@ -428,18 +436,13 @@ symbol_table::remove_unreachable_nodes (FILE *file) && (!e->inline_failed || !DECL_EXTERNAL (e->callee->decl) || e->callee->alias - || (before_inlining_p - && (opt_for_fn (body->decl, optimize) - || (symtab->state < IPA_SSA - && lookup_attribute - ("always_inline", - DECL_ATTRIBUTES (body->decl))))))) + || possible_inline_candidate_p (e->callee))) { /* Be sure that we will not optimize out alias target body. */ if (DECL_EXTERNAL (e->callee->decl) && e->callee->alias - && before_inlining_p) + && symtab->state < IPA_SSA_AFTER_INLINING) reachable.add (body); reachable.add (e->callee); } @@ -654,7 +657,7 @@ symbol_table::remove_unreachable_nodes (FILE *file) of possible later devirtualization. Do not mark them as local too early so we won't optimize them out before we are done with polymorphic call analysis. */ - && (!before_inlining_p + && (symtab->state >= IPA_SSA_AFTER_INLINING || !node->call_for_symbol_and_aliases (is_indirect_call_target_p, NULL, true))) { diff --git a/gcc/passes.c b/gcc/passes.c index 5d2372b..85aa47d 100644 --- a/gcc/passes.c +++ b/gcc/passes.c @@ -459,6 +459,35 @@ public: }; // class pass_local_optimization_passes +const pass_data pass_data_ipa_remove_symbols = +{ + SIMPLE_IPA_PASS, /* type */ + "remove_symbols", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ + TV_NONE, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_remove_functions | TODO_dump_symtab, /* todo_flags_finish */ +}; + +class pass_ipa_remove_symbols : public simple_ipa_opt_pass +{ +public: + pass_ipa_remove_symbols (gcc::context *ctxt) + : simple_ipa_opt_pass (pass_data_ipa_remove_symbols, ctxt) + {} + + /* opt_pass methods: */ + virtual bool gate (function *) + { + /* Don't bother doing anything if the program has errors. */ + return (!seen_error () && !in_lto_p); + } + +}; // class pass_local_optimization_passes + } // anon namespace simple_ipa_opt_pass * @@ -473,6 +502,12 @@ make_pass_local_optimization_passes (gcc::context *ctxt) return new pass_local_optimization_passes (ctxt); } +simple_ipa_opt_pass * +make_pass_ipa_remove_symbols (gcc::context *ctxt) +{ + return new pass_ipa_remove_symbols (ctxt); +} + namespace { const pass_data pass_data_all_early_optimizations = diff --git a/gcc/passes.def b/gcc/passes.def index 24f212c..82ad940 100644 --- a/gcc/passes.def +++ b/gcc/passes.def @@ -106,6 +106,7 @@ along with GCC; see the file COPYING3. If not see NEXT_PASS (pass_local_fn_summary); POP_INSERT_PASSES () + NEXT_PASS (pass_ipa_remove_symbols); NEXT_PASS (pass_ipa_oacc); PUSH_INSERT_PASSES_WITHIN (pass_ipa_oacc) NEXT_PASS (pass_ipa_pta); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 32c0f3d..4ec625f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-11-20 Jan Hubicka <hubicka@ucw.cz> + + PR ipa/87706 + * gcc.dg/ipa/ctor-empty-1.c: Update template. + 2018-11-20 Richard Biener <rguenther@suse.de> PR tree-optimization/88074 diff --git a/gcc/testsuite/gcc.dg/ipa/ctor-empty-1.c b/gcc/testsuite/gcc.dg/ipa/ctor-empty-1.c index 264ca3f..b1f4f854 100644 --- a/gcc/testsuite/gcc.dg/ipa/ctor-empty-1.c +++ b/gcc/testsuite/gcc.dg/ipa/ctor-empty-1.c @@ -1,7 +1,7 @@ /* { dg-do compile } */ -/* { dg-options "-O3 -c -fdump-ipa-free-fnsummary1" } */ +/* { dg-options "-O3 -c -fdump-ipa-remove_symbols" } */ static __attribute__((constructor)) void empty_constructor() { } -/* { dg-final { scan-ipa-dump "Reclaiming functions: empty_constructor" "free-fnsummary1" } } */ +/* { dg-final { scan-ipa-dump "Reclaiming functions: empty_constructor" "remove_symbols" } } */ |