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); }