aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@ucw.cz>2025-05-28 14:26:11 +0200
committerJan Hubicka <hubicka@ucw.cz>2025-05-28 14:26:11 +0200
commit17f7b6250628c31182fd4f71c9ecdeca9568ffd1 (patch)
treeb1dc53589735af50708418988c7ba23f9541c27e /gcc
parenta4dc4001999a8b504cde468618af12c9b870589b (diff)
downloadgcc-17f7b6250628c31182fd4f71c9ecdeca9568ffd1.zip
gcc-17f7b6250628c31182fd4f71c9ecdeca9568ffd1.tar.gz
gcc-17f7b6250628c31182fd4f71c9ecdeca9568ffd1.tar.bz2
Handle auto-fdo 0 more carefully
This patch fixes few other places where auto-fdo 0 should be be treated as actual 0 (i.e. probably never executed). Overall I think we should end up combining static profile with auto-fdo profile where auto-fdo has 0 counts, but that is something that should be benchmarked and first it is neccessary to get something benchmarkeable out of auto-FDO. gcc/ChangeLog: * cgraph.cc (cgraph_edge::maybe_hot_p): For auto-fdo turn 0 to non-zero. * ipa-cp.cc (cs_interesting_for_ipcp_p): Do not trust auto-fdo 0. * profile-count.cc (profile_count::adjust_for_ipa_scaling): Likewise. (profile_count::from_gcov_type): Fix formating.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cgraph.cc9
-rw-r--r--gcc/ipa-cp.cc8
-rw-r--r--gcc/profile-count.cc30
3 files changed, 31 insertions, 16 deletions
diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc
index ac0f251..3f95ca1 100644
--- a/gcc/cgraph.cc
+++ b/gcc/cgraph.cc
@@ -3019,7 +3019,14 @@ cgraph_edge::maybe_hot_p (sreal scale)
/* Use IPA count and if it s not available appy local heuristics. */
if (c.initialized_p ())
- return maybe_hot_count_p (NULL, c * scale);
+ {
+ /* A special case; AFDO zero means that function may quite possibly
+ be executed few times per execution. If scale is large, we still
+ want to consider the call hot. */
+ if (c.quality () == AFDO)
+ c = c.force_nonzero ();
+ return maybe_hot_count_p (NULL, c * scale);
+ }
if (!count.initialized_p ())
return true;
cgraph_node *where = caller->inlined_to ? caller->inlined_to : caller;
diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc
index f06ac46..73cf904 100644
--- a/gcc/ipa-cp.cc
+++ b/gcc/ipa-cp.cc
@@ -544,8 +544,12 @@ cs_interesting_for_ipcp_p (cgraph_edge *e)
if (e->count.ipa ().nonzero_p ())
return true;
/* If local (possibly guseed or adjusted 0 profile) claims edge is
- not executed, do not propagate. */
- if (e->count.initialized_p () && !e->count.nonzero_p ())
+ not executed, do not propagate.
+ Do not trust AFDO since branch needs to be executed multiple
+ time to count while we want to propagate even call called
+ once during the train run if callee is important. */
+ if (e->count.initialized_p () && !e->count.nonzero_p ()
+ && e->count.quality () != AFDO)
return false;
/* If we have zero IPA profile, still consider edge for cloning
in case we do partial training. */
diff --git a/gcc/profile-count.cc b/gcc/profile-count.cc
index 374f06f..2d9c778 100644
--- a/gcc/profile-count.cc
+++ b/gcc/profile-count.cc
@@ -364,8 +364,12 @@ profile_count::adjust_for_ipa_scaling (profile_count *num,
/* Scaling to zero is always zero. */
if (*num == zero ())
return;
- /* If den is non-zero we are safe. */
- if (den->force_nonzero () == *den)
+ /* If den is non-zero we are safe.
+ However take care of zeros in AFDO profiles since
+ they simply means that no useful samples were collected.
+ Called function still may contain important loop. */
+ if (den->force_nonzero () == *den
+ && num->quality () != AFDO)
return;
/* Force both to non-zero so we do not push profiles to 0 when
both num == 0 and den == 0. */
@@ -417,17 +421,17 @@ profile_count::combine_with_ipa_count_within (profile_count ipa,
profile_count
profile_count::from_gcov_type (gcov_type v, profile_quality quality)
- {
- profile_count ret;
- gcc_checking_assert (v >= 0);
- if (dump_file && v >= (gcov_type)max_count)
- fprintf (dump_file,
- "Capping gcov count %" PRId64 " to max_count %" PRId64 "\n",
- (int64_t) v, (int64_t) max_count);
- ret.m_val = MIN (v, (gcov_type)max_count);
- ret.m_quality = quality;
- return ret;
- }
+{
+ profile_count ret;
+ gcc_checking_assert (v >= 0);
+ if (dump_file && v >= (gcov_type)max_count)
+ fprintf (dump_file,
+ "Capping gcov count %" PRId64 " to max_count %" PRId64 "\n",
+ (int64_t) v, (int64_t) max_count);
+ ret.m_val = MIN (v, (gcov_type)max_count);
+ ret.m_quality = quality;
+ return ret;
+}
/* COUNT1 times event happens with *THIS probability, COUNT2 times OTHER
happens with COUNT2 probability. Return probability that either *THIS or