https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118551
--- Comment #2 from Hongtao Liu <liuhongt at gcc dot gnu.org> ---
A hack like below can recove performance and further improved 538.imagick_r by
5% w/ autofdo.
The hack prevents the scaling if ipa_count is zero but function body is hot.
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);
}