aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTeresa Johnson <tejohnson@google.com>2013-10-10 20:30:08 +0000
committerTeresa Johnson <tejohnson@gcc.gnu.org>2013-10-10 20:30:08 +0000
commit67fa7880729adbe567fd578151060e3a4a8873e8 (patch)
treeee44642551d3ee1b05cabe70b04747b7d739f6bf
parent58b2a3585302ca85e06c5957e307f292c61036d9 (diff)
downloadgcc-67fa7880729adbe567fd578151060e3a4a8873e8.zip
gcc-67fa7880729adbe567fd578151060e3a4a8873e8.tar.gz
gcc-67fa7880729adbe567fd578151060e3a4a8873e8.tar.bz2
predict.c (tree_estimate_probability): Add new parameter for estimate_bb_frequencies.
2013-10-10 Teresa Johnson <tejohnson@google.com> * 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
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/predict.c36
-rw-r--r--gcc/predict.h2
3 files changed, 37 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 654946a..00ef1a8 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2013-10-10 Teresa Johnson <tejohnson@google.com>
+
+ * 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 <dmalcolm@redhat.com>
* ipa-inline.c (ipa_inline): Fix leak of "order" when
diff --git a/gcc/predict.c b/gcc/predict.c
index e6a4095..ca1a0c9 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 559f803..02650e2 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);