From cf9712ccc092e054e2a48d78c275b709700a0032 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Mon, 10 Jan 2011 15:33:04 +0100 Subject: re PR tree-optimization/47234 (ipa-split is executed before profile feedback is read) PR tree-optimization/47234 * tree-pass.h (TODO_rebuild_cgraph_edges): New TODO. (pass_feedback_split_functions): Declare. * passes.c (init_optimization_passes): Add ipa-split as subpass of tree-profile. * ipa-split.c (gate_split_functions): Update comments; disable split-functions for profile_arc_flag and branch_probabilities. (gate_feedback_split_functions): New function. (execute_feedback_split_functions): New function. (pass_feedback_split_functions): New global var. From-SVN: r168632 --- gcc/ipa-split.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 2 deletions(-) (limited to 'gcc/ipa-split.c') diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c index fabd6d1..4fcbfe9 100644 --- a/gcc/ipa-split.c +++ b/gcc/ipa-split.c @@ -1265,7 +1265,9 @@ execute_split_functions (void) /* See if it makes sense to try to split. It makes sense to split if we inline, that is if we have direct calls to handle or direct calls are possibly going to appear as result of indirect - inlining or LTO. + inlining or LTO. Also handle -fprofile-generate as LTO to allow non-LTO + training for LTO -fprofile-use build. + Note that we are not completely conservative about disqualifying functions called once. It is possible that the caller is called more then once and then inlining would still benefit. */ @@ -1336,10 +1338,15 @@ execute_split_functions (void) return todo; } +/* Gate function splitting pass. When doing profile feedback, we want + to execute the pass after profiling is read. So disable one in + early optimization. */ + static bool gate_split_functions (void) { - return flag_partial_inlining; + return (flag_partial_inlining + && !profile_arc_flag && !flag_branch_probabilities); } struct gimple_opt_pass pass_split_functions = @@ -1360,3 +1367,44 @@ struct gimple_opt_pass pass_split_functions = TODO_dump_func /* todo_flags_finish */ } }; + +/* Gate feedback driven function splitting pass. + We don't need to split when profiling at all, we are producing + lousy code anyway. */ + +static bool +gate_feedback_split_functions (void) +{ + return (flag_partial_inlining + && flag_branch_probabilities); +} + +/* Execute function splitting pass. */ + +static unsigned int +execute_feedback_split_functions (void) +{ + unsigned int retval = execute_split_functions (); + if (retval) + retval |= TODO_rebuild_cgraph_edges; + return retval; +} + +struct gimple_opt_pass pass_feedback_split_functions = +{ + { + GIMPLE_PASS, + "feedback_fnsplit", /* name */ + gate_feedback_split_functions, /* gate */ + execute_feedback_split_functions, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_IPA_FNSPLIT, /* tv_id */ + PROP_cfg, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func /* todo_flags_finish */ + } +}; -- cgit v1.1