]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
predict.c (tree_estimate_probability): Add new parameter for estimate_bb_frequencies.
authorTeresa Johnson <tejohnson@google.com>
Thu, 10 Oct 2013 20:30:08 +0000 (20:30 +0000)
committerTeresa Johnson <tejohnson@gcc.gnu.org>
Thu, 10 Oct 2013 20:30:08 +0000 (20:30 +0000)
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

gcc/ChangeLog
gcc/predict.c
gcc/predict.h

index 654946a565134d8194d72306abede8bb2ca7233f..00ef1a8d8b07312c3ff9a748d41e105cee612ed3 100644 (file)
@@ -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
index e6a4095acd151c3e8a149b961ba9693f42dc2d16..ca1a0c9802c8f420346eeb0b943b36bbf7507f48 100644 (file)
@@ -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 ();
     }
index 559f803076eb5edcc336f222010c47c0d98085ac..02650e2d55cbb8d9d7c717957a9e4826419397cf 100644 (file)
@@ -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);