Hello. During investigation of an IVOPTs issue, I noticed that tree-ssa-loop-ivopts.c uses a hard-coded constant AVG_LOOP_NITER. Very similar constant can be seen in cfgloopanal.c. Thus, I've changed that to a new param.
Apart from that, I would like to change the default value to 10. As numbers of SPEC CPU2006 show: Loop count: 18236 avg. # of iter: 11908.46 median # of iter: 10.00 avg. (1% cutoff) # of iter: 1003.87 avg. (5% cutoff) # of iter: 449.78 avg. (10% cutoff) # of iter: 209.46 avg. (20% cutoff) # of iter: 62.24 avg. (30% cutoff) # of iter: 42.69 Even though the average number of loop iteration is quite high, let's start to increase it conservatively to 10. Benchmark results are within a noise level (-Ofast runs faster by 0.47%). Patch survives regression tests and bootstraps on x86_64-linux-gnu. Ready for trunk? Thanks, Martin
>From 604637de550a9d23b8a509cdbf493a7212a186f0 Mon Sep 17 00:00:00 2001 From: marxin <mli...@suse.cz> Date: Tue, 21 Jun 2016 14:52:31 +0200 Subject: [PATCH] Introduce new param: AVG_LOOP_NITER gcc/ChangeLog: 2016-06-21 Martin Liska <mli...@suse.cz> * params.def: Add avg-loop niter. * tree-ssa-loop-ivopts.c (avg_loop_niter): Use the param. * cfgloopanal.c (expected_loop_iterations_unbounded): Likewise. --- gcc/cfgloopanal.c | 9 ++++----- gcc/params.def | 5 +++++ gcc/tree-ssa-loop-ivopts.c | 7 +++---- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/gcc/cfgloopanal.c b/gcc/cfgloopanal.c index c163986..2739f44 100644 --- a/gcc/cfgloopanal.c +++ b/gcc/cfgloopanal.c @@ -241,10 +241,9 @@ expected_loop_iterations_unbounded (const struct loop *loop, if (read_profile_p) *read_profile_p = false; - /* Average loop rolls about 3 times. If we have no profile at all, it is - best we can do. */ + /* If we have no profile at all, use AVG_LOOP_NITER. */ if (profile_status_for_fn (cfun) == PROFILE_ABSENT) - expected = 3; + expected = PARAM_VALUE (PARAM_AVG_LOOP_NITER); else if (loop->latch->count || loop->header->count) { gcov_type count_in, count_latch; @@ -282,9 +281,9 @@ expected_loop_iterations_unbounded (const struct loop *loop, if (freq_in == 0) { - /* If we have no profile at all, expect 3 iterations. */ + /* If we have no profile at all, use AVG_LOOP_NITER iterations. */ if (!freq_latch) - expected = 3; + expected = PARAM_VALUE (PARAM_AVG_LOOP_NITER); else expected = freq_latch * 2; } diff --git a/gcc/params.def b/gcc/params.def index 894b7f3..b86d592 100644 --- a/gcc/params.def +++ b/gcc/params.def @@ -527,6 +527,11 @@ DEFPARAM(PARAM_IV_ALWAYS_PRUNE_CAND_SET_BOUND, "If number of candidates in the set is smaller, we always try to remove unused ivs during its optimization.", 10, 0, 0) +DEFPARAM(PARAM_AVG_LOOP_NITER, + "avg-loop-niter", + "Average number of iterations of a loop.", + 10, 1, 0) + DEFPARAM(PARAM_SCEV_MAX_EXPR_SIZE, "scev-max-expr-size", "Bound on size of expressions used in the scalar evolutions analyzer.", diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c index 6b403f5..d401c41 100644 --- a/gcc/tree-ssa-loop-ivopts.c +++ b/gcc/tree-ssa-loop-ivopts.c @@ -115,8 +115,6 @@ along with GCC; see the file COPYING3. If not see /* The infinite cost. */ #define INFTY 10000000 -#define AVG_LOOP_NITER(LOOP) 5 - /* Returns the expected number of loop iterations for LOOP. The average trip count is computed from profile data if it exists. */ @@ -128,8 +126,9 @@ avg_loop_niter (struct loop *loop) if (niter == -1) { niter = likely_max_stmt_executions_int (loop); - if (niter == -1 || niter > AVG_LOOP_NITER (loop)) - return AVG_LOOP_NITER (loop); + + if (niter == -1 || niter > PARAM_VALUE (PARAM_AVG_LOOP_NITER)) + return PARAM_VALUE (PARAM_AVG_LOOP_NITER); } return niter; -- 2.8.4