https://gcc.gnu.org/g:f9b60a8bd7569f59534a42d1383c1f66a37542cf

commit r17-4901-gf9b60a8bd7569f59534a42d1383c1f66a37542cf
Author: Martin Jambor <[email protected]>
Date:   Mon Oct 5 16:59:12 2026 +0200

    ipa-cp: Adjust PGO IPA-CP cloning heuristics
    
    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.
    
    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.

Diff:
---
 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 8d8e5926cb10..7393711a92ea 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 574b109bad52..cecc8d17f17c 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;
@@ -3477,8 +3483,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))
@@ -4082,6 +4088,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");
@@ -4103,15 +4111,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)
@@ -6872,6 +6899,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 053fdfdb97c2..29a5c7018a80 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.

Reply via email to