From: "hongtao.liu" <hongtao....@intel.com>

AutoFDO profile is a scaled profile, as a result, 0 sample does not
mean never executed. especially there's profile from function
body. Prevent combine_with_ipa_count·(ipa_count) from zeroing all
bb->count.

Bootstrapped and regtested on x86_64-pc-linux-gnu{-m32,}
OK for trunk?

gcc/ChangeLog:

        PR gcov-profile/118551
        * predict.cc (estimate_bb_frequencies): Prevent
        combine_with_ipa_count·(ipa_count) from zeroing all bb->count
        when function body is known to be hot.
---
 gcc/predict.cc | 73 +++++++++++++++++++++++++++++---------------------
 1 file changed, 42 insertions(+), 31 deletions(-)

diff --git a/gcc/predict.cc b/gcc/predict.cc
index ef31c48bfe2..7d4bf5261ad 100644
--- a/gcc/predict.cc
+++ b/gcc/predict.cc
@@ -4105,40 +4105,51 @@ estimate_bb_frequencies ()
   if (freq_max < 16)
     freq_max = 16;
   profile_count ipa_count = ENTRY_BLOCK_PTR_FOR_FN (cfun)->count.ipa ();
-  cfun->cfg->count_max = profile_count::uninitialized ();
-  FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL, next_bb)
+
+  /* AutoFDO profile is a scaled profile, as a result, 0 sample does not
+     mean never executed. especially there's profile from function
+     body. Prevent combine_with_ipa_count·(ipa_count) from zeroing all
+     bb->count.  */
+  if (!(ipa_count.quality () == AFDO
+       && cfun->cfg->count_max.quality () == AFDO
+       && !ipa_count.nonzero_p ()
+       && cfun->cfg->count_max.nonzero_p ()))
     {
-      sreal tmp = BLOCK_INFO (bb)->frequency;
-      if (tmp >= 1)
+      cfun->cfg->count_max = profile_count::uninitialized ();
+      FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL, next_bb)
        {
-         gimple_stmt_iterator gsi;
-         tree decl;
-
-         /* Self recursive calls can not have frequency greater than 1
-            or program will never terminate.  This will result in an
-            inconsistent bb profile but it is better than greatly confusing
-            IPA cost metrics.  */
-         for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
-           if (is_gimple_call (gsi_stmt (gsi))
-               && (decl = gimple_call_fndecl (gsi_stmt (gsi))) != NULL
-               && recursive_call_p (current_function_decl, decl))
-             {
-               if (dump_file)
-                 fprintf (dump_file, "Dropping frequency of recursive call"
-                          " in bb %i from %f\n", bb->index,
-                          tmp.to_double ());
-               tmp = (sreal)9 / (sreal)10;
-               break;
-             }
+         sreal tmp = BLOCK_INFO (bb)->frequency;
+         if (tmp >= 1)
+           {
+             gimple_stmt_iterator gsi;
+             tree decl;
+
+             /* Self recursive calls can not have frequency greater than 1
+                or program will never terminate.  This will result in an
+                inconsistent bb profile but it is better than greatly confusing
+                IPA cost metrics.  */
+             for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+               if (is_gimple_call (gsi_stmt (gsi))
+                   && (decl = gimple_call_fndecl (gsi_stmt (gsi))) != NULL
+                   && recursive_call_p (current_function_decl, decl))
+                 {
+                   if (dump_file)
+                     fprintf (dump_file, "Dropping frequency of recursive call"
+                              " in bb %i from %f\n", bb->index,
+                              tmp.to_double ());
+                   tmp = (sreal)9 / (sreal)10;
+                   break;
+                 }
+           }
+         tmp = tmp * freq_max;
+         profile_count count = profile_count::from_gcov_type 
(tmp.to_nearest_int ());
+
+         /* If we have profile feedback in which this function was never
+            executed, then preserve this info.  */
+         if (!(bb->count == profile_count::zero ()))
+           bb->count = count.guessed_local ().combine_with_ipa_count 
(ipa_count);
+         cfun->cfg->count_max = cfun->cfg->count_max.max (bb->count);
        }
-      tmp = tmp * freq_max;
-      profile_count count = profile_count::from_gcov_type (tmp.to_nearest_int 
());
-
-      /* If we have profile feedback in which this function was never
-        executed, then preserve this info.  */
-      if (!(bb->count == profile_count::zero ()))
-       bb->count = count.guessed_local ().combine_with_ipa_count (ipa_count);
-      cfun->cfg->count_max = cfun->cfg->count_max.max (bb->count);
     }
 
   free_aux_for_blocks ();
-- 
2.34.1

Reply via email to