From 67fa7880729adbe567fd578151060e3a4a8873e8 Mon Sep 17 00:00:00 2001 From: Teresa Johnson Date: Thu, 10 Oct 2013 20:30:08 +0000 Subject: [PATCH] predict.c (tree_estimate_probability): Add new parameter for estimate_bb_frequencies. 2013-10-10 Teresa Johnson * predict.c (tree_estimate_probability): Add new parameter for estimate_bb_frequencies. (estimate_bb_frequencies): Add new parameter to force estimation. (rebuild_frequencies): When max frequency in function is small, recompute counts from frequencies. * predict.h (estimate_bb_frequencies): New parameter. From-SVN: r203395 --- gcc/ChangeLog | 9 +++++++++ gcc/predict.c | 36 +++++++++++++++++++++++++++--------- gcc/predict.h | 2 +- 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 654946a5651..00ef1a8d8b0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2013-10-10 Teresa Johnson + + * predict.c (tree_estimate_probability): Add new parameter + for estimate_bb_frequencies. + (estimate_bb_frequencies): Add new parameter to force estimation. + (rebuild_frequencies): When max frequency in function is small, + recompute counts from frequencies. + * predict.h (estimate_bb_frequencies): New parameter. + 2013-10-10 David Malcolm * ipa-inline.c (ipa_inline): Fix leak of "order" when diff --git a/gcc/predict.c b/gcc/predict.c index e6a4095acd1..ca1a0c9802c 100644 --- a/gcc/predict.c +++ b/gcc/predict.c @@ -2389,7 +2389,7 @@ tree_estimate_probability (void) pointer_map_destroy (bb_predictions); bb_predictions = NULL; - estimate_bb_frequencies (); + estimate_bb_frequencies (false); free_dominance_info (CDI_POST_DOMINATORS); remove_fake_exit_edges (); } @@ -2692,7 +2692,7 @@ propagate_freq (basic_block head, bitmap tovisit) } } -/* Estimate probabilities of loopback edges in loops at same nest level. */ +/* Estimate frequencies in loops at same nest level. */ static void estimate_loops_at_level (struct loop *first_loop) @@ -2801,15 +2801,17 @@ expensive_function_p (int threshold) return false; } -/* Estimate basic blocks frequency by given branch probabilities. */ +/* Estimate and propagate basic block frequencies using the given branch + probabilities. If FORCE is true, the frequencies are used to estimate + the counts even when there are already non-zero profile counts. */ void -estimate_bb_frequencies (void) +estimate_bb_frequencies (bool force) { basic_block bb; sreal freq_max; - if (profile_status != PROFILE_READ || !counts_to_freqs ()) + if (force || profile_status != PROFILE_READ || !counts_to_freqs ()) { static int real_values_initialized = 0; @@ -2846,8 +2848,8 @@ estimate_bb_frequencies (void) } } - /* First compute probabilities locally for each loop from innermost - to outermost to examine probabilities for back edges. */ + /* First compute frequencies locally for each loop from innermost + to outermost to examine frequencies for back edges. */ estimate_loops (); memcpy (&freq_max, &real_zero, sizeof (real_zero)); @@ -3028,13 +3030,29 @@ void rebuild_frequencies (void) { timevar_push (TV_REBUILD_FREQUENCIES); - if (profile_status == PROFILE_GUESSED) + + /* When the max bb count in the function is small, there is a higher + chance that there were truncation errors in the integer scaling + of counts by inlining and other optimizations. This could lead + to incorrect classification of code as being cold when it isn't. + In that case, force the estimation of bb counts/frequencies from the + branch probabilities, rather than computing frequencies from counts, + which may also lead to frequencies incorrectly reduced to 0. There + is less precision in the probabilities, so we only do this for small + max counts. */ + gcov_type count_max = 0; + basic_block bb; + FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb) + count_max = MAX (bb->count, count_max); + + if (profile_status == PROFILE_GUESSED + || (profile_status == PROFILE_READ && count_max < REG_BR_PROB_BASE/10)) { loop_optimizer_init (0); add_noreturn_fake_exit_edges (); mark_irreducible_loops (); connect_infinite_loops_to_exit (); - estimate_bb_frequencies (); + estimate_bb_frequencies (true); remove_fake_exit_edges (); loop_optimizer_finalize (); } diff --git a/gcc/predict.h b/gcc/predict.h index 559f803076e..02650e2d55c 100644 --- a/gcc/predict.h +++ b/gcc/predict.h @@ -37,7 +37,7 @@ enum prediction extern void predict_insn_def (rtx, enum br_predictor, enum prediction); extern int counts_to_freqs (void); -extern void estimate_bb_frequencies (void); +extern void estimate_bb_frequencies (bool); extern const char *predictor_name (enum br_predictor); extern tree build_predict_expr (enum br_predictor, enum prediction); extern void tree_estimate_probability (void);