Message ID | 8c883adb-9ec5-c9d5-f1cb-cc48a6ccd2ea@suse.cz |
---|---|
State | New |
Headers | show |
Series | Remove unreachable nodes before IPA profile pass (PR ipa/87706). | expand |
On 11/8/18 12:19 PM, Jan Hubicka wrote: >> Hi. >> >> In order to fix the warnings mentioned in the PR, we need >> to run remove_unreachable_nodes after early tree passes. That's >> however possible only within a IPA pass. Thus I'm calling that >> before the profile PASS. >> >> Patch survives regression tests on ppc64le-linux-gnu and majority >> of warnings are gone in profiledbootstrap. >> >> Ready for trunk? > > I think we want to do that even with no -fprofile-generate because the > unreachable code otherwise goes into all other IPA passes for no good > reason. So perhaps adding it as todo after the early optimization > metapass? That fails due to gcc_assert. So one needs: diff --git a/gcc/passes.c b/gcc/passes.c index d838d909941..be92a2f3be3 100644 --- a/gcc/passes.c +++ b/gcc/passes.c @@ -485,7 +485,7 @@ const pass_data pass_data_all_early_optimizations = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - 0, /* todo_flags_finish */ + TODO_remove_functions | TODO_rebuild_cgraph_edges, /* todo_flags_finish */ }; class pass_all_early_optimizations : public gimple_opt_pass @@ -1989,7 +1989,8 @@ execute_todo (unsigned int flags) of IPA pass queue. */ if (flags & TODO_remove_functions) { - gcc_assert (!cfun); + gcc_assert (!cfun + || strcmp (current_pass->name, "early_optimizations") == 0); symtab->remove_unreachable_nodes (dump_file); } Or do you prefer to a new pass_remove_functions pass that will be added after pass_local_optimization_passes ? Martin > > Honza >> Thanks, >> Martin >> >> gcc/ChangeLog: >> >> 2018-11-08 Martin Liska <mliska@suse.cz> >> >> * tree-profile.c: Run TODO_remove_functions before "profile" >> pass in order to remove dead functions that will trigger >> -Wmissing-profile. >> --- >> gcc/tree-profile.c | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> > >> diff --git a/gcc/tree-profile.c b/gcc/tree-profile.c >> index d8f2a3b1ba4..c14ebc556a6 100644 >> --- a/gcc/tree-profile.c >> +++ b/gcc/tree-profile.c >> @@ -776,7 +776,7 @@ const pass_data pass_data_ipa_tree_profile = >> 0, /* properties_required */ >> 0, /* properties_provided */ >> 0, /* properties_destroyed */ >> - 0, /* todo_flags_start */ >> + TODO_remove_functions, /* todo_flags_start */ >> TODO_dump_symtab, /* todo_flags_finish */ >> }; >> >> >
On Thu, Nov 8, 2018 at 12:39 PM Martin Liška <mliska@suse.cz> wrote: > > On 11/8/18 12:19 PM, Jan Hubicka wrote: > >> Hi. > >> > >> In order to fix the warnings mentioned in the PR, we need > >> to run remove_unreachable_nodes after early tree passes. That's > >> however possible only within a IPA pass. Thus I'm calling that > >> before the profile PASS. > >> > >> Patch survives regression tests on ppc64le-linux-gnu and majority > >> of warnings are gone in profiledbootstrap. > >> > >> Ready for trunk? > > > > I think we want to do that even with no -fprofile-generate because the > > unreachable code otherwise goes into all other IPA passes for no good > > reason. So perhaps adding it as todo after the early optimization > > metapass? > > That fails due to gcc_assert. > So one needs: > > diff --git a/gcc/passes.c b/gcc/passes.c > index d838d909941..be92a2f3be3 100644 > --- a/gcc/passes.c > +++ b/gcc/passes.c > @@ -485,7 +485,7 @@ const pass_data pass_data_all_early_optimizations = > 0, /* properties_provided */ > 0, /* properties_destroyed */ > 0, /* todo_flags_start */ > - 0, /* todo_flags_finish */ > + TODO_remove_functions | TODO_rebuild_cgraph_edges, /* todo_flags_finish */ > }; > > class pass_all_early_optimizations : public gimple_opt_pass > @@ -1989,7 +1989,8 @@ execute_todo (unsigned int flags) > of IPA pass queue. */ > if (flags & TODO_remove_functions) > { > - gcc_assert (!cfun); > + gcc_assert (!cfun > + || strcmp (current_pass->name, "early_optimizations") == 0); > symtab->remove_unreachable_nodes (dump_file); > } > > > Or do you prefer to a new pass_remove_functions pass that will be added after > pass_local_optimization_passes ? Can you make it todo_flags_start of pass_ipa_tree_profile instead? > Martin > > > > > Honza > >> Thanks, > >> Martin > >> > >> gcc/ChangeLog: > >> > >> 2018-11-08 Martin Liska <mliska@suse.cz> > >> > >> * tree-profile.c: Run TODO_remove_functions before "profile" > >> pass in order to remove dead functions that will trigger > >> -Wmissing-profile. > >> --- > >> gcc/tree-profile.c | 2 +- > >> 1 file changed, 1 insertion(+), 1 deletion(-) > >> > >> > > > >> diff --git a/gcc/tree-profile.c b/gcc/tree-profile.c > >> index d8f2a3b1ba4..c14ebc556a6 100644 > >> --- a/gcc/tree-profile.c > >> +++ b/gcc/tree-profile.c > >> @@ -776,7 +776,7 @@ const pass_data pass_data_ipa_tree_profile = > >> 0, /* properties_required */ > >> 0, /* properties_provided */ > >> 0, /* properties_destroyed */ > >> - 0, /* todo_flags_start */ > >> + TODO_remove_functions, /* todo_flags_start */ > >> TODO_dump_symtab, /* todo_flags_finish */ > >> }; > >> > >> > > >
> On Thu, Nov 8, 2018 at 12:39 PM Martin Liška <mliska@suse.cz> wrote: > > > > On 11/8/18 12:19 PM, Jan Hubicka wrote: > > >> Hi. > > >> > > >> In order to fix the warnings mentioned in the PR, we need > > >> to run remove_unreachable_nodes after early tree passes. That's > > >> however possible only within a IPA pass. Thus I'm calling that > > >> before the profile PASS. > > >> > > >> Patch survives regression tests on ppc64le-linux-gnu and majority > > >> of warnings are gone in profiledbootstrap. > > >> > > >> Ready for trunk? > > > > > > I think we want to do that even with no -fprofile-generate because the > > > unreachable code otherwise goes into all other IPA passes for no good > > > reason. So perhaps adding it as todo after the early optimization > > > metapass? > > > > That fails due to gcc_assert. > > So one needs: > > > > diff --git a/gcc/passes.c b/gcc/passes.c > > index d838d909941..be92a2f3be3 100644 > > --- a/gcc/passes.c > > +++ b/gcc/passes.c > > @@ -485,7 +485,7 @@ const pass_data pass_data_all_early_optimizations = > > 0, /* properties_provided */ > > 0, /* properties_destroyed */ > > 0, /* todo_flags_start */ > > - 0, /* todo_flags_finish */ > > + TODO_remove_functions | TODO_rebuild_cgraph_edges, /* todo_flags_finish */ > > }; > > > > class pass_all_early_optimizations : public gimple_opt_pass > > @@ -1989,7 +1989,8 @@ execute_todo (unsigned int flags) > > of IPA pass queue. */ > > if (flags & TODO_remove_functions) > > { > > - gcc_assert (!cfun); > > + gcc_assert (!cfun > > + || strcmp (current_pass->name, "early_optimizations") == 0); > > symtab->remove_unreachable_nodes (dump_file); > > } > > > > > > Or do you prefer to a new pass_remove_functions pass that will be added after > > pass_local_optimization_passes ? > > Can you make it todo_flags_start of pass_ipa_tree_profile instead? It fails because all_early_optimizations are now gimple pass, so it should be TODO after pass_local_optimization_passes? Honza > > > Martin > > > > > > > > Honza > > >> Thanks, > > >> Martin > > >> > > >> gcc/ChangeLog: > > >> > > >> 2018-11-08 Martin Liska <mliska@suse.cz> > > >> > > >> * tree-profile.c: Run TODO_remove_functions before "profile" > > >> pass in order to remove dead functions that will trigger > > >> -Wmissing-profile. > > >> --- > > >> gcc/tree-profile.c | 2 +- > > >> 1 file changed, 1 insertion(+), 1 deletion(-) > > >> > > >> > > > > > >> diff --git a/gcc/tree-profile.c b/gcc/tree-profile.c > > >> index d8f2a3b1ba4..c14ebc556a6 100644 > > >> --- a/gcc/tree-profile.c > > >> +++ b/gcc/tree-profile.c > > >> @@ -776,7 +776,7 @@ const pass_data pass_data_ipa_tree_profile = > > >> 0, /* properties_required */ > > >> 0, /* properties_provided */ > > >> 0, /* properties_destroyed */ > > >> - 0, /* todo_flags_start */ > > >> + TODO_remove_functions, /* todo_flags_start */ > > >> TODO_dump_symtab, /* todo_flags_finish */ > > >> }; > > >> > > >> > > > > >
On 11/8/18 12:46 PM, Jan Hubicka wrote: >> On Thu, Nov 8, 2018 at 12:39 PM Martin Liška <mliska@suse.cz> wrote: >>> >>> On 11/8/18 12:19 PM, Jan Hubicka wrote: >>>>> Hi. >>>>> >>>>> In order to fix the warnings mentioned in the PR, we need >>>>> to run remove_unreachable_nodes after early tree passes. That's >>>>> however possible only within a IPA pass. Thus I'm calling that >>>>> before the profile PASS. >>>>> >>>>> Patch survives regression tests on ppc64le-linux-gnu and majority >>>>> of warnings are gone in profiledbootstrap. >>>>> >>>>> Ready for trunk? >>>> >>>> I think we want to do that even with no -fprofile-generate because the >>>> unreachable code otherwise goes into all other IPA passes for no good >>>> reason. So perhaps adding it as todo after the early optimization >>>> metapass? >>> >>> That fails due to gcc_assert. >>> So one needs: >>> >>> diff --git a/gcc/passes.c b/gcc/passes.c >>> index d838d909941..be92a2f3be3 100644 >>> --- a/gcc/passes.c >>> +++ b/gcc/passes.c >>> @@ -485,7 +485,7 @@ const pass_data pass_data_all_early_optimizations = >>> 0, /* properties_provided */ >>> 0, /* properties_destroyed */ >>> 0, /* todo_flags_start */ >>> - 0, /* todo_flags_finish */ >>> + TODO_remove_functions | TODO_rebuild_cgraph_edges, /* todo_flags_finish */ >>> }; >>> >>> class pass_all_early_optimizations : public gimple_opt_pass >>> @@ -1989,7 +1989,8 @@ execute_todo (unsigned int flags) >>> of IPA pass queue. */ >>> if (flags & TODO_remove_functions) >>> { >>> - gcc_assert (!cfun); >>> + gcc_assert (!cfun >>> + || strcmp (current_pass->name, "early_optimizations") == 0); >>> symtab->remove_unreachable_nodes (dump_file); >>> } >>> >>> >>> Or do you prefer to a new pass_remove_functions pass that will be added after >>> pass_local_optimization_passes ? >> >> Can you make it todo_flags_start of pass_ipa_tree_profile instead? > > It fails because all_early_optimizations are now gimple pass, so it > should be TODO after pass_local_optimization_passes? Please read my last email. Martin > > Honza >> >>> Martin >>> >>>> >>>> Honza >>>>> Thanks, >>>>> Martin >>>>> >>>>> gcc/ChangeLog: >>>>> >>>>> 2018-11-08 Martin Liska <mliska@suse.cz> >>>>> >>>>> * tree-profile.c: Run TODO_remove_functions before "profile" >>>>> pass in order to remove dead functions that will trigger >>>>> -Wmissing-profile. >>>>> --- >>>>> gcc/tree-profile.c | 2 +- >>>>> 1 file changed, 1 insertion(+), 1 deletion(-) >>>>> >>>>> >>>> >>>>> diff --git a/gcc/tree-profile.c b/gcc/tree-profile.c >>>>> index d8f2a3b1ba4..c14ebc556a6 100644 >>>>> --- a/gcc/tree-profile.c >>>>> +++ b/gcc/tree-profile.c >>>>> @@ -776,7 +776,7 @@ const pass_data pass_data_ipa_tree_profile = >>>>> 0, /* properties_required */ >>>>> 0, /* properties_provided */ >>>>> 0, /* properties_destroyed */ >>>>> - 0, /* todo_flags_start */ >>>>> + TODO_remove_functions, /* todo_flags_start */ >>>>> TODO_dump_symtab, /* todo_flags_finish */ >>>>> }; >>>>> >>>>> >>>> >>>
On 11/8/18 12:46 PM, Jan Hubicka wrote: >> On Thu, Nov 8, 2018 at 12:39 PM Martin Liška <mliska@suse.cz> wrote: >>> >>> On 11/8/18 12:19 PM, Jan Hubicka wrote: >>>>> Hi. >>>>> >>>>> In order to fix the warnings mentioned in the PR, we need >>>>> to run remove_unreachable_nodes after early tree passes. That's >>>>> however possible only within a IPA pass. Thus I'm calling that >>>>> before the profile PASS. >>>>> >>>>> Patch survives regression tests on ppc64le-linux-gnu and majority >>>>> of warnings are gone in profiledbootstrap. >>>>> >>>>> Ready for trunk? >>>> >>>> I think we want to do that even with no -fprofile-generate because the >>>> unreachable code otherwise goes into all other IPA passes for no good >>>> reason. So perhaps adding it as todo after the early optimization >>>> metapass? >>> >>> That fails due to gcc_assert. >>> So one needs: >>> >>> diff --git a/gcc/passes.c b/gcc/passes.c >>> index d838d909941..be92a2f3be3 100644 >>> --- a/gcc/passes.c >>> +++ b/gcc/passes.c >>> @@ -485,7 +485,7 @@ const pass_data pass_data_all_early_optimizations = >>> 0, /* properties_provided */ >>> 0, /* properties_destroyed */ >>> 0, /* todo_flags_start */ >>> - 0, /* todo_flags_finish */ >>> + TODO_remove_functions | TODO_rebuild_cgraph_edges, /* todo_flags_finish */ >>> }; >>> >>> class pass_all_early_optimizations : public gimple_opt_pass >>> @@ -1989,7 +1989,8 @@ execute_todo (unsigned int flags) >>> of IPA pass queue. */ >>> if (flags & TODO_remove_functions) >>> { >>> - gcc_assert (!cfun); >>> + gcc_assert (!cfun >>> + || strcmp (current_pass->name, "early_optimizations") == 0); >>> symtab->remove_unreachable_nodes (dump_file); >>> } >>> >>> >>> Or do you prefer to a new pass_remove_functions pass that will be added after >>> pass_local_optimization_passes ? >> >> Can you make it todo_flags_start of pass_ipa_tree_profile instead? > > It fails because all_early_optimizations are now gimple pass, so it > should be TODO after pass_local_optimization_passes? Unfortunately it does not work. Following file can't be compiled: ./xgcc -B. /home/marxin/Programming/gcc/gcc/testsuite/gcc.dg/torture/inline-2.c -O0 /usr/lib64/gcc/x86_64-suse-linux/8/../../../../x86_64-suse-linux/bin/ld: /tmp/ccCVFrPv.o: in function `bar1': inline-2.c:(.text+0x5): undefined reference to `foo2' /usr/lib64/gcc/x86_64-suse-linux/8/../../../../x86_64-suse-linux/bin/ld: /tmp/ccCVFrPv.o: in function `bar2': inline-2.c:(.text+0x11): undefined reference to `foo1' collect2: error: ld returned 1 exit status So it's some interference with einline. Honza? Thus I'm suggesting to add a new IPA pass. That survives regression tests on x86_64-linux-gnu and bootstrap works. Martin > > Honza >> >>> Martin >>> >>>> >>>> Honza >>>>> Thanks, >>>>> Martin >>>>> >>>>> gcc/ChangeLog: >>>>> >>>>> 2018-11-08 Martin Liska <mliska@suse.cz> >>>>> >>>>> * tree-profile.c: Run TODO_remove_functions before "profile" >>>>> pass in order to remove dead functions that will trigger >>>>> -Wmissing-profile. >>>>> --- >>>>> gcc/tree-profile.c | 2 +- >>>>> 1 file changed, 1 insertion(+), 1 deletion(-) >>>>> >>>>> >>>> >>>>> diff --git a/gcc/tree-profile.c b/gcc/tree-profile.c >>>>> index d8f2a3b1ba4..c14ebc556a6 100644 >>>>> --- a/gcc/tree-profile.c >>>>> +++ b/gcc/tree-profile.c >>>>> @@ -776,7 +776,7 @@ const pass_data pass_data_ipa_tree_profile = >>>>> 0, /* properties_required */ >>>>> 0, /* properties_provided */ >>>>> 0, /* properties_destroyed */ >>>>> - 0, /* todo_flags_start */ >>>>> + TODO_remove_functions, /* todo_flags_start */ >>>>> TODO_dump_symtab, /* todo_flags_finish */ >>>>> }; >>>>> >>>>> >>>> >>> From 00fd2e0870860d5e1b4e599e1f88292982a03efb Mon Sep 17 00:00:00 2001 From: marxin <mliska@suse.cz> Date: Wed, 7 Nov 2018 13:10:57 +0100 Subject: [PATCH] Remove unreachable nodes before IPA profile pass (PR ipa/87706). gcc/ChangeLog: 2018-11-12 Martin Liska <mliska@suse.cz> PR ipa/87706 * cgraphbuild.c (class pass_ipa_remove_functions): New pass. (make_pass_remove_functions): Likewise. * passes.def: Declare the new pass. * tree-pass.h (make_pass_remove_functions): New. --- gcc/cgraphbuild.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ gcc/passes.def | 1 + gcc/tree-pass.h | 1 + 3 files changed, 46 insertions(+) diff --git a/gcc/cgraphbuild.c b/gcc/cgraphbuild.c index c2ad5cf2ef7..f903df38c31 100644 --- a/gcc/cgraphbuild.c +++ b/gcc/cgraphbuild.c @@ -547,3 +547,47 @@ make_pass_remove_cgraph_callee_edges (gcc::context *ctxt) { return new pass_remove_cgraph_callee_edges (ctxt); } + +namespace { + +const pass_data pass_data_ipa_remove_functions = +{ + IPA_PASS, /* type */ + "*remove_functions", /* name */ + OPTGROUP_INLINE, /* optinfo_flags */ + TV_IPA_FNSUMMARY, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_remove_functions /* todo_flags_finish */ +}; + +class pass_ipa_remove_functions : public ipa_opt_pass_d +{ +public: + pass_ipa_remove_functions (gcc::context *ctxt) + : ipa_opt_pass_d (pass_data_ipa_remove_functions, ctxt, + NULL, /* generate_summary */ + NULL, /* write_summary */ + NULL, /* 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 unsigned int execute (function *) { return 0; } + +}; // class pass_ipa_fn_summary + +} // anon namespace + +ipa_opt_pass_d * +make_pass_remove_functions (gcc::context *ctxt) +{ + return new pass_ipa_remove_functions (ctxt); +} diff --git a/gcc/passes.def b/gcc/passes.def index 24f212c8e31..f7ebc061721 100644 --- a/gcc/passes.def +++ b/gcc/passes.def @@ -105,6 +105,7 @@ along with GCC; see the file COPYING3. If not see NEXT_PASS (pass_rebuild_cgraph_edges); NEXT_PASS (pass_local_fn_summary); POP_INSERT_PASSES () + NEXT_PASS (pass_remove_functions); NEXT_PASS (pass_ipa_oacc); PUSH_INSERT_PASSES_WITHIN (pass_ipa_oacc) diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h index af15adc8e0c..872d3533b49 100644 --- a/gcc/tree-pass.h +++ b/gcc/tree-pass.h @@ -514,6 +514,7 @@ extern ipa_opt_pass_d *make_pass_ipa_single_use (gcc::context *ctxt); extern ipa_opt_pass_d *make_pass_ipa_comdats (gcc::context *ctxt); extern simple_ipa_opt_pass *make_pass_materialize_all_clones (gcc::context * ctxt); +extern ipa_opt_pass_d *make_pass_remove_functions (gcc::context *ctxt); extern gimple_opt_pass *make_pass_cleanup_cfg_post_optimizing (gcc::context *ctxt);
> Hi. > > In order to fix the warnings mentioned in the PR, we need > to run remove_unreachable_nodes after early tree passes. That's > however possible only within a IPA pass. Thus I'm calling that > before the profile PASS. > > Patch survives regression tests on ppc64le-linux-gnu and majority > of warnings are gone in profiledbootstrap. > > Ready for trunk? > Thanks, > Martin > > gcc/ChangeLog: > > 2018-11-08 Martin Liska <mliska@suse.cz> > > * tree-profile.c: Run TODO_remove_functions before "profile" > pass in order to remove dead functions that will trigger > -Wmissing-profile. Hi, it turns out there are few bugs on the way. First ipa.c has incomplete tests on when it needs to keep the functions. Also the function remval is actually scheduled in fnsummary1 pass that just run bit late because post-profile function splitting needs it. This is variant I ended up testing. My original plan to do it at the end of the early passes ipa pass did not fly because TODOs are run before subpasses (as already commented in ipa-fnsummary.c. So I ended up splitting ipa_fnsummary into two mini-passes. Bootstrapped/regtested x86_64-linux, plan to commit it shortly. Honza * 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. Index: ipa-fnsummary.c =================================================================== --- ipa-fnsummary.c (revision 266288) +++ ipa-fnsummary.c (working copy) @@ -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: Index: ipa.c =================================================================== --- ipa.c (revision 266288) +++ ipa.c (working copy) @@ -101,12 +101,32 @@ enqueue_node (symtab_node *node, symtab_ *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< /* 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 ( 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 ( 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 ( 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 ( && (!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 ( 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))) { Index: passes.c =================================================================== --- passes.c (revision 266288) +++ passes.c (working copy) @@ -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 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 = Index: passes.def =================================================================== --- passes.def (revision 266288) +++ passes.def (working copy) @@ -106,6 +106,7 @@ along with GCC; see the file COPYING3. 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); Index: testsuite/gcc.dg/ipa/ctor-empty-1.c =================================================================== --- testsuite/gcc.dg/ipa/ctor-empty-1.c (revision 266288) +++ testsuite/gcc.dg/ipa/ctor-empty-1.c (working copy) @@ -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" } } */
diff --git a/gcc/tree-profile.c b/gcc/tree-profile.c index d8f2a3b1ba4..c14ebc556a6 100644 --- a/gcc/tree-profile.c +++ b/gcc/tree-profile.c @@ -776,7 +776,7 @@ const pass_data pass_data_ipa_tree_profile = 0, /* properties_required */ 0, /* properties_provided */ 0, /* properties_destroyed */ - 0, /* todo_flags_start */ + TODO_remove_functions, /* todo_flags_start */ TODO_dump_symtab, /* todo_flags_finish */ };