diff options
author | Jan Hubicka <hubicka@ucw.cz> | 2018-04-13 10:59:05 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2018-04-13 08:59:05 +0000 |
commit | 65739a688542b637b6a9f99aed2de84d9b84460c (patch) | |
tree | bd43bc965dff5590c78fb5d6d802b3cbda1f4332 /gcc/cfgloopanal.c | |
parent | 2fdb5a23a3a65f949de21bdc3256a72029fd290d (diff) | |
download | gcc-65739a688542b637b6a9f99aed2de84d9b84460c.zip gcc-65739a688542b637b6a9f99aed2de84d9b84460c.tar.gz gcc-65739a688542b637b6a9f99aed2de84d9b84460c.tar.bz2 |
re PR tree-optimization/82965 (gcc.dg/vect/pr79347.c starts failing after r254379)
PR tree-optimization/82965
PR tree-optimization/83991
* cfgloopanal.c (expected_loop_iterations_unbounded): Add
by_profile_only parameter.
* cfgloopmanip.c (scale_loop_profile): Further scale loop's profile
information if the loop was predicted to iterate too many times.
* cfgloop.h (expected_loop_iterations_unbounded): Update prototype
Co-Authored-By: Bin Cheng <bin.cheng@arm.com>
From-SVN: r259368
Diffstat (limited to 'gcc/cfgloopanal.c')
-rw-r--r-- | gcc/cfgloopanal.c | 44 |
1 files changed, 34 insertions, 10 deletions
diff --git a/gcc/cfgloopanal.c b/gcc/cfgloopanal.c index 9151a33..3af0b2d 100644 --- a/gcc/cfgloopanal.c +++ b/gcc/cfgloopanal.c @@ -230,12 +230,17 @@ average_num_loop_insns (const struct loop *loop) } /* Returns expected number of iterations of LOOP, according to - measured or guessed profile. No bounding is done on the - value. */ + measured or guessed profile. + + This functions attempts to return "sane" value even if profile + information is not good enough to derive osmething. + If BY_PROFILE_ONLY is set, this logic is bypassed and function + return -1 in those scenarios. */ gcov_type expected_loop_iterations_unbounded (const struct loop *loop, - bool *read_profile_p) + bool *read_profile_p, + bool by_profile_only) { edge e; edge_iterator ei; @@ -246,7 +251,11 @@ expected_loop_iterations_unbounded (const struct loop *loop, /* If we have no profile at all, use AVG_LOOP_NITER. */ if (profile_status_for_fn (cfun) == PROFILE_ABSENT) - expected = PARAM_VALUE (PARAM_AVG_LOOP_NITER); + { + if (by_profile_only) + return -1; + expected = PARAM_VALUE (PARAM_AVG_LOOP_NITER); + } else if (loop->latch && (loop->latch->count.initialized_p () || loop->header->count.initialized_p ())) { @@ -260,9 +269,17 @@ expected_loop_iterations_unbounded (const struct loop *loop, count_in += e->count (); if (!count_latch.initialized_p ()) - expected = PARAM_VALUE (PARAM_AVG_LOOP_NITER); + { + if (by_profile_only) + return -1; + expected = PARAM_VALUE (PARAM_AVG_LOOP_NITER); + } else if (!count_in.nonzero_p ()) - expected = count_latch.to_gcov_type () * 2; + { + if (by_profile_only) + return -1; + expected = count_latch.to_gcov_type () * 2; + } else { expected = (count_latch.to_gcov_type () + count_in.to_gcov_type () @@ -273,11 +290,18 @@ expected_loop_iterations_unbounded (const struct loop *loop, } } else - expected = PARAM_VALUE (PARAM_AVG_LOOP_NITER); + { + if (by_profile_only) + return -1; + expected = PARAM_VALUE (PARAM_AVG_LOOP_NITER); + } - HOST_WIDE_INT max = get_max_loop_iterations_int (loop); - if (max != -1 && max < expected) - return max; + if (!by_profile_only) + { + HOST_WIDE_INT max = get_max_loop_iterations_int (loop); + if (max != -1 && max < expected) + return max; + } return expected; } |