Hi,

this winter I have had a long look at the effects of different values
of parameter param_ipa_cp_eval_threshold on performance on SPEC 2017
and on how they affect code size - and how quickly we reach growth
size limit in param_ipa_cp_unit_growth - when compiling these
benchmarks bit also, cc1 in an -O3 bootstrap and clang.

After going through the numbers, it turns out that we tend to clone a
bit too much and especially that we hit the overall growth limit way
too quickly.  As a result this patch does two things.  First, it
raises the heuristics cost/benefit threshold to 1100 (from 500) which
is the value at which I started to see cloning benefits.

Second, it reverts a recent change to get_max_overall_size where the
size limit also depended on the current call-graph sweep.  We only
want the threshold to gradually come down (now to 1100), not the size
constraints also, it turned out to defeat the initial purpose.

Bootstrapped and tested on x86_64-linux, approved by Honza in person,
committed.

Thanks,

Martin


gcc/ChangeLog:

2026-04-07  Martin Jambor  <[email protected]>

        * ipa-cp.cc (get_max_overall_size): Remove parameter CUR_SWEEP and
        its use.
        (decide_about_value): Adjust the call to get_max_overall_size.
        (decide_whether_version_node): Likewise.
        * params.opt (param_ipa_cp_eval_threshold): Initialize to 1100.

libgomp/ChangeLog:

2026-04-07  Martin Jambor  <[email protected]>

        * testsuite/libgomp.c/ipcp-cb-spec1.c: Set lower param
        ipa-cp-eval-threshold.

gcc/testsuite/ChangeLog:

2026-04-07  Martin Jambor  <[email protected]>

        * gcc.dg/ipa/ipa-5.c: Adjust dump.
        * gcc.dg/independent-cloneids-1.c: Set lower param
        ipa-cp-eval-threshold.
        * gcc.dg/vla-1.c: Likewise.
        * g++.dg/ipa/devirt-2.C: Add an extra caller of the to-be-cloned
        function.
---
 gcc/ipa-cp.cc                                 | 23 ++++++++-----------
 gcc/params.opt                                |  2 +-
 gcc/testsuite/g++.dg/ipa/devirt-2.C           | 10 ++++++++
 gcc/testsuite/gcc.dg/independent-cloneids-1.c |  2 +-
 gcc/testsuite/gcc.dg/ipa/ipa-5.c              |  2 +-
 gcc/testsuite/gcc.dg/vla-1.c                  |  2 +-
 libgomp/testsuite/libgomp.c/ipcp-cb-spec1.c   |  2 +-
 7 files changed, 24 insertions(+), 19 deletions(-)

diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc
index c1b1f6201fd..ce77acf8e0d 100644
--- a/gcc/ipa-cp.cc
+++ b/gcc/ipa-cp.cc
@@ -3620,25 +3620,21 @@ perform_estimation_of_a_value (cgraph_node *node,
   val->local_size_cost = size;
 }
 
-/* Get the overall limit of growth based on parameters extracted from growth,
-   and CUR_SWEEP, which is the number of the current sweep of IPA-CP over the
-   call-graph in the decision stage.  It does not really make sense to mix
-   functions with different overall growth limits or even number of sweeps but
-   it is possible and if it happens, we do not want to select one limit at
-   random, so get the limits from NODE.  */
+/* Get the overall limit of growth based on parameters extracted from NODE.  It
+   does not really make sense to mix functions with different overall growth
+   limits or even number of sweeps but it is possible and if it happens, we do
+   not want to select one limit at random, so get the limits from NODE.  */
 
 static long
-get_max_overall_size (cgraph_node *node, int cur_sweep)
+get_max_overall_size (cgraph_node *node)
 {
   long max_new_size = orig_overall_size;
   long large_unit = opt_for_fn (node->decl, param_ipa_cp_large_unit_insns);
   if (max_new_size < large_unit)
     max_new_size = large_unit;
-  int num_sweeps = opt_for_fn (node->decl, param_ipa_cp_sweeps);
-  gcc_assert (cur_sweep <= num_sweeps);
   int unit_growth = opt_for_fn (node->decl, param_ipa_cp_unit_growth);
-  max_new_size += ((max_new_size * unit_growth * cur_sweep)
-                  / num_sweeps) / 100 + 1;
+  max_new_size += max_new_size * unit_growth / 100 + 1;
+
   return max_new_size;
 }
 
@@ -5958,8 +5954,7 @@ decide_about_value (struct cgraph_node *node, int index, 
HOST_WIDE_INT offset,
       perhaps_add_new_callers (node, val);
       return false;
     }
-  else if (val->local_size_cost + overall_size
-          > get_max_overall_size (node, cur_sweep))
+  else if (val->local_size_cost + overall_size > get_max_overall_size (node))
     {
       if (dump_file && (dump_flags & TDF_DETAILS))
        fprintf (dump_file, "   Ignoring candidate value because "
@@ -6337,7 +6332,7 @@ decide_whether_version_node (struct cgraph_node *node, 
int cur_sweep)
                                           stats.called_without_ipa_profile,
                                           cur_sweep))
        {
-         if (size + overall_size <= get_max_overall_size (node, cur_sweep))
+         if (size + overall_size <= get_max_overall_size (node))
            {
              if (!dbg_cnt (ipa_cp_values))
                return ret;
diff --git a/gcc/params.opt b/gcc/params.opt
index 9eeb1f3fa64..90f9943c8cb 100644
--- a/gcc/params.opt
+++ b/gcc/params.opt
@@ -250,7 +250,7 @@ Common Joined UInteger Var(param_integer_share_limit) 
Init(251) IntegerRange(2,
 The upper bound for sharing integer constants.
 
 -param=ipa-cp-eval-threshold=
-Common Joined UInteger Var(param_ipa_cp_eval_threshold) Init(500) Param 
Optimization
+Common Joined UInteger Var(param_ipa_cp_eval_threshold) Init(1100) Param 
Optimization
 Threshold ipa-cp opportunity evaluation that is still considered beneficial to 
clone.
 
 -param=ipa-cp-loop-hint-bonus=
diff --git a/gcc/testsuite/g++.dg/ipa/devirt-2.C 
b/gcc/testsuite/g++.dg/ipa/devirt-2.C
index 3fffe278ece..6a81140e03d 100644
--- a/gcc/testsuite/g++.dg/ipa/devirt-2.C
+++ b/gcc/testsuite/g++.dg/ipa/devirt-2.C
@@ -48,6 +48,16 @@ int __attribute__ ((noinline,noclone,noipa)) get_input(void)
   return 1;
 }
 
+int extra (int init)
+{
+  class B b;
+  int i;
+  for (i = init; i < get_input(); i++)
+    if (b.middleman (get_input ()) != 3)
+      abort ();
+  return 0;
+}
+
 int main (int argc, char *argv[])
 {
   class B b;
diff --git a/gcc/testsuite/gcc.dg/independent-cloneids-1.c 
b/gcc/testsuite/gcc.dg/independent-cloneids-1.c
index efbc1c51da0..c6e9581cbce 100644
--- a/gcc/testsuite/gcc.dg/independent-cloneids-1.c
+++ b/gcc/testsuite/gcc.dg/independent-cloneids-1.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O3 -fipa-cp -fipa-cp-clone -fdump-rtl-final"  } */
+/* { dg-options "-O3 -fipa-cp -fipa-cp-clone -fdump-rtl-final --param 
ipa-cp-eval-threshold=500"  } */
 /* { dg-skip-if "Odd label definition syntax" { mmix-*-* } } */
 
 extern int printf (const char *, ...);
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-5.c b/gcc/testsuite/gcc.dg/ipa/ipa-5.c
index e4f77a96768..a6678b12c7c 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-5.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-5.c
@@ -27,6 +27,6 @@ int main ()
   return 0;
 }
 
-/* { dg-final { scan-ipa-dump-times "Creating a specialized node" 3 "cp"  } } 
*/
+/* { dg-final { scan-ipa-dump-times "Creating a specialized node" 2 "cp"  } } 
*/
 /* { dg-final { scan-ipa-dump "replacing param .1 c with const 3" "cp"  } } */
 /* { dg-final { scan-ipa-dump "replacing param .0 a with const 7" "cp"  } } */
diff --git a/gcc/testsuite/gcc.dg/vla-1.c b/gcc/testsuite/gcc.dg/vla-1.c
index 2ab2b7a48ac..52a1d9772d9 100644
--- a/gcc/testsuite/gcc.dg/vla-1.c
+++ b/gcc/testsuite/gcc.dg/vla-1.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-g -O3 -fdump-tree-optimized -fvar-tracking-assignments 
-fno-selective-scheduling -fno-selective-scheduling2 -fno-ipa-vrp" } */
+/* { dg-options "-g -O3 -fdump-tree-optimized -fvar-tracking-assignments 
-fno-selective-scheduling -fno-selective-scheduling2 -fno-ipa-vrp --param 
ipa-cp-eval-threshold=1" } */
 
 int __attribute__((noinline))
 f1 (int i)
diff --git a/libgomp/testsuite/libgomp.c/ipcp-cb-spec1.c 
b/libgomp/testsuite/libgomp.c/ipcp-cb-spec1.c
index ff82f4c2f29..a2ab03f692a 100644
--- a/libgomp/testsuite/libgomp.c/ipcp-cb-spec1.c
+++ b/libgomp/testsuite/libgomp.c/ipcp-cb-spec1.c
@@ -1,7 +1,7 @@
 /* Test that GOMP_task is special cased when cpyfn is NULL.  */
 
 /* { dg-do run } */
-/* { dg-options "-O3 -fopenmp -std=gnu99 -fdump-ipa-cp-details" } */
+/* { dg-options "-O3 -fopenmp -std=gnu99 -fdump-ipa-cp-details --param 
ipa-cp-eval-threshold=1" } */
 /* { dg-require-effective-target fopenmp } */
 
 void test(int c) {
-- 
2.54.0

Reply via email to