https://gcc.gnu.org/g:17f7b6250628c31182fd4f71c9ecdeca9568ffd1

commit r16-930-g17f7b6250628c31182fd4f71c9ecdeca9568ffd1
Author: Jan Hubicka <hubi...@ucw.cz>
Date:   Wed May 28 14:26:11 2025 +0200

    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.

Diff:
---
 gcc/cgraph.cc        |  9 ++++++++-
 gcc/ipa-cp.cc        |  8 ++++++--
 gcc/profile-count.cc | 30 +++++++++++++++++-------------
 3 files changed, 31 insertions(+), 16 deletions(-)

diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc
index ac0f2519361b..3f95ca1fa85c 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 f06ac46dfffb..73cf9040fad7 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 374f06f4c083..2d9c778b3758 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

Reply via email to