From 12485662c00914ed132d950f1329fdaf32c11a3c Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Tue, 20 Nov 2018 14:25:04 +0100 Subject: [PATCH] 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 --- gcc/ChangeLog | 14 ++++++ gcc/ipa-fnsummary.c | 5 +-- gcc/ipa.c | 59 +++++++++++++------------ gcc/passes.c | 35 +++++++++++++++ gcc/passes.def | 1 + gcc/testsuite/ChangeLog | 5 +++ 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 5a18ba9d543..44ca2cefb3e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2018-11-20 Jan Hubicka + + 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 * tree-vect-stmts.c (vectorizable_condition): Do not get diff --git a/gcc/ipa-fnsummary.c b/gcc/ipa-fnsummary.c index 9cb7d41ccc5..23b7821dcc1 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: diff --git a/gcc/ipa.c b/gcc/ipa.c index 22c21354f75..89fb1da50fd 100644 --- a/gcc/ipa.c +++ b/gcc/ipa.c @@ -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 (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 *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 *reachable_call_targets, struct cgraph_edge *edge, symtab_node **first, - hash_set *reachable, - bool before_inlining_p) + hash_set *reachable) { unsigned int i; void *cache_token; @@ -190,15 +202,14 @@ walk_polymorphic_call_targets (hash_set *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 reachable; hash_set body_needed_for_clonning; hash_set 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 (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 5d2372bac24..85aa47d5c81 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 24f212c8e31..82ad9404b9e 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 32c0f3d6381..4ec625f1768 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-11-20 Jan Hubicka + + PR ipa/87706 + * gcc.dg/ipa/ctor-empty-1.c: Update template. + 2018-11-20 Richard Biener 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 264ca3f0349..b1f4f8545a1 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" } } */ -- 2.30.2