Hi,

With profile-feedback, the run-times used for opportunity evaluations
is not currently scaled to the total measured run time of the
program/compilation unit, which is an obvious mistake.  This patch
adds such scaling by run-time which is however itself also scaled down
so that the resulting scores rougly fall in line with the scores on
hot loops we get using guessed profile.

Kugan, please have a look if this helps addressing the issues you see
with AutoFDO (though I have not looked at whether the default value of
ipa-cp-profile-runtime-scaling is appropriate also for AutoFDO).

I have bootstrapped and tested this on an x86_64-linux in a normal way
and then also did a bootstrap with LTO, PGO and -O3 optimization level.
OK for master?

Martin



gcc/ChangeLog:

2026-05-15  Martin Jambor  <[email protected]>

        * ipa-cp.cc (overall_scaled_runtime): New.
        (good_cloning_opportunity_p): Scale PGO evaluations by
        overall_scaled_runtime.
        (ipcp_propagate_stage): Calculate also overall_scaled_runtime and
        print it and unscaled time.
        (ipa_cp_cc_finalize): Set overall_scaled_runtime to zero.
        * params.opt (ipa-cp-profile-runtime-scaling): New.
        * doc/params.texi (ipa-cp-profile-runtime-scaling): New.
---
 gcc/doc/params.texi |  5 +++++
 gcc/ipa-cp.cc       | 40 ++++++++++++++++++++++++++++++++++------
 gcc/params.opt      |  4 ++++
 3 files changed, 43 insertions(+), 6 deletions(-)

diff --git a/gcc/doc/params.texi b/gcc/doc/params.texi
index e69be2d2923..2c2e1abef57 100644
--- a/gcc/doc/params.texi
+++ b/gcc/doc/params.texi
@@ -1292,6 +1292,11 @@ of iterations of a loop known, it adds a bonus of
 @option{ipa-cp-loop-hint-bonus} to the profitability score of
 the candidate.
 
+@paindex ipa-cp-profile-runtime-scaling
+@item ipa-cp-profile-runtime-scaling
+When using profile feedback, by how many bits to shift the run-time
+before it is used as the basis for IPA-CP evaluations.
+
 @paindex ipa-max-loop-predicates
 @item ipa-max-loop-predicates
 The maximum number of different predicates IPA uses to describe when
diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc
index d0428d04684..78a3891d811 100644
--- a/gcc/ipa-cp.cc
+++ b/gcc/ipa-cp.cc
@@ -153,6 +153,12 @@ object_allocator<ipcp_agg_lattice> ipcp_agg_lattice_pool
 
 static long overall_size, orig_overall_size;
 
+/* Overall run-time of the part of the program or the compilation unit for
+   which profile information is available, scaled by
+   param_ipa_cp_min_recursive_probability.  */
+
+static sreal overall_scaled_runtime;
+
 /* The maximum number of IPA-CP decision sweeps that any node requested in its
    param.  */
 static int max_number_sweeps;
@@ -3474,8 +3480,8 @@ good_cloning_opportunity_p (struct cgraph_node *node, 
sreal time_benefit,
   if (count_sum.nonzero_p ())
     {
       profile_count saved_time = count_sum * time_benefit;
-      sreal evaluation = saved_time.to_sreal_scale (profile_count::one ())
-                             / size_cost;
+      sreal evaluation = (saved_time.to_sreal_scale (profile_count::one ())
+                         / overall_scaled_runtime) / size_cost;
       evaluation = incorporate_penalties (node, info, evaluation);
 
       if (dump_file && (dump_flags & TDF_DETAILS))
@@ -4079,6 +4085,8 @@ static void
 ipcp_propagate_stage (class ipa_topo_info *topo)
 {
   struct cgraph_node *node;
+  sreal overall_runtime = 0;
+  overall_scaled_runtime = 0;
 
   if (dump_file)
     fprintf (dump_file, "\n Propagating constants:\n\n");
@@ -4100,15 +4108,34 @@ ipcp_propagate_stage (class ipa_topo_info *topo)
        if (max_number_sweeps < num_sweeps)
          max_number_sweeps = num_sweeps;
       }
-    ipa_size_summary *s = ipa_size_summaries->get (node);
-    if (node->definition && !node->alias && s != NULL)
-      overall_size += s->self_size;
+
+    if (!node->alias)
+      {
+       ipa_size_summary *szs = ipa_size_summaries->get (node);
+       if (szs)
+         overall_size += szs->self_size;
+       ipa_fn_summary *fns = ipa_fn_summaries->get (node);
+       if (fns)
+         {
+           int shift = opt_for_fn (node->decl,
+                                   param_ipa_cp_profile_runtime_scaling);
+           sreal frt = fns->time;
+           overall_runtime += frt;
+           overall_scaled_runtime += frt.shift(-shift);
+         }
+      }
   }
 
   orig_overall_size = overall_size;
 
   if (dump_file)
-    fprintf (dump_file, "\noverall_size: %li\n", overall_size);
+    {
+      fprintf (dump_file, "\noverall_size: %li\n", overall_size);
+      fprintf (dump_file, "overall_runtime: %.2e\n",
+              overall_runtime.to_double ());
+      fprintf (dump_file, "overall_scaled_runtime: %.2e\n",
+              overall_scaled_runtime.to_double ());
+    }
 
   propagate_constants_topo (topo);
   if (flag_checking)
@@ -6869,6 +6896,7 @@ ipa_cp_cc_finalize (void)
 {
   overall_size = 0;
   orig_overall_size = 0;
+  overall_scaled_runtime = 0;
   ipcp_free_transformation_sum ();
 }
 
diff --git a/gcc/params.opt b/gcc/params.opt
index 0c6a3e51457..cda19a04b7f 100644
--- a/gcc/params.opt
+++ b/gcc/params.opt
@@ -261,6 +261,10 @@ Threshold ipa-cp opportunity evaluation that is still 
considered beneficial to c
 Common Joined UInteger Var(param_ipa_cp_loop_hint_bonus) Init(64) Param 
Optimization
 Compile-time bonus IPA-CP assigns to candidates which make loop bounds or 
strides known.
 
+-param=ipa-cp-profile-runtime-scaling=
+Common Joined UInteger Var(param_ipa_cp_profile_runtime_scaling) Init(19) 
Param Optimization
+With profile feedback, by how many bits to shift the run-time before it is 
used as the basis for IPA-CP evaluations.
+
 -param=ipa-cp-max-recursive-depth=
 Common Joined UInteger Var(param_ipa_cp_max_recursive_depth) Init(8) Param 
Optimization
 Maximum depth of recursive cloning for self-recursive function.
-- 
2.55.0

Reply via email to