aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-loop-ivcanon.c
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@ucw.cz>2016-05-30 19:58:19 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2016-05-30 17:58:19 +0000
commita448ff403b72f8e9d914a63d89ebca8246dad0ef (patch)
tree1618933ba1605bd935706f18f0ece6f212807cf5 /gcc/tree-ssa-loop-ivcanon.c
parent83e0b73912068e0f42204df117e5f7a2a2e349e1 (diff)
downloadgcc-a448ff403b72f8e9d914a63d89ebca8246dad0ef.zip
gcc-a448ff403b72f8e9d914a63d89ebca8246dad0ef.tar.gz
gcc-a448ff403b72f8e9d914a63d89ebca8246dad0ef.tar.bz2
invoke.texi (-fpeel-loops,-O3): Update documentation.
* doc/invoke.texi (-fpeel-loops,-O3): Update documentation. * opts.c (default_options): Enable peel loops at -O3. * tree-ssa-loop-ivcanon.c (peeled_loops): New static var. (try_peel_loop): Do not re-peel already peeled loops; use likely upper bounds; fix profile updating. (pass_complete_unroll::execute): Initialize peeled_loops. * gcc.dg/tree-ssa/peel1.c: New testcase. * gcc.dg/tree-ssa/pr61743-1.c: Disable loop peeling. * gcc.dg/tree-ssa/pr61743-2.c: Disable loop peeling. From-SVN: r236892
Diffstat (limited to 'gcc/tree-ssa-loop-ivcanon.c')
-rw-r--r--gcc/tree-ssa-loop-ivcanon.c44
1 files changed, 31 insertions, 13 deletions
diff --git a/gcc/tree-ssa-loop-ivcanon.c b/gcc/tree-ssa-loop-ivcanon.c
index 4cfdb27..319a410 100644
--- a/gcc/tree-ssa-loop-ivcanon.c
+++ b/gcc/tree-ssa-loop-ivcanon.c
@@ -594,6 +594,8 @@ remove_redundant_iv_tests (struct loop *loop)
/* Stores loops that will be unlooped after we process whole loop tree. */
static vec<loop_p> loops_to_unloop;
static vec<int> loops_to_unloop_nunroll;
+/* Stores loops that has been peeled. */
+static bitmap peeled_loops;
/* Cancel all fully unrolled loops by putting __builtin_unreachable
on the latch edge.
@@ -962,14 +964,17 @@ try_peel_loop (struct loop *loop,
vec<edge> to_remove = vNULL;
edge e;
- /* If the iteration bound is known and large, then we can safely eliminate
- the check in peeled copies. */
- if (TREE_CODE (niter) != INTEGER_CST)
- exit = NULL;
-
- if (!flag_peel_loops || PARAM_VALUE (PARAM_MAX_PEEL_TIMES) <= 0)
+ if (!flag_peel_loops || PARAM_VALUE (PARAM_MAX_PEEL_TIMES) <= 0
+ || !peeled_loops)
return false;
+ if (bitmap_bit_p (peeled_loops, loop->num))
+ {
+ if (dump_file)
+ fprintf (dump_file, "Not peeling: loop is already peeled\n");
+ return false;
+ }
+
/* Peel only innermost loops.
While the code is perfectly capable of peeling non-innermost loops,
the heuristics would probably need some improvements. */
@@ -990,6 +995,8 @@ try_peel_loop (struct loop *loop,
/* Check if there is an estimate on the number of iterations. */
npeel = estimated_loop_iterations_int (loop);
if (npeel < 0)
+ npeel = likely_max_loop_iterations_int (loop);
+ if (npeel < 0)
{
if (dump_file)
fprintf (dump_file, "Not peeling: number of iterations is not "
@@ -1036,8 +1043,7 @@ try_peel_loop (struct loop *loop,
&& wi::leu_p (npeel, wi::to_widest (niter)))
{
bitmap_ones (wont_exit);
- if (wi::eq_p (wi::to_widest (niter), npeel))
- bitmap_clear_bit (wont_exit, 0);
+ bitmap_clear_bit (wont_exit, 0);
}
else
{
@@ -1074,14 +1080,14 @@ try_peel_loop (struct loop *loop,
}
if (loop->any_upper_bound)
{
- if (wi::ltu_p (npeel, loop->nb_iterations_estimate))
+ if (wi::ltu_p (npeel, loop->nb_iterations_upper_bound))
loop->nb_iterations_upper_bound -= npeel;
else
loop->nb_iterations_upper_bound = 0;
}
if (loop->any_likely_upper_bound)
{
- if (wi::ltu_p (npeel, loop->nb_iterations_estimate))
+ if (wi::ltu_p (npeel, loop->nb_iterations_likely_upper_bound))
loop->nb_iterations_likely_upper_bound -= npeel;
else
{
@@ -1107,6 +1113,7 @@ try_peel_loop (struct loop *loop,
else if (loop->header->frequency)
scale = RDIV (entry_freq * REG_BR_PROB_BASE, loop->header->frequency);
scale_loop_profile (loop, scale, 0);
+ bitmap_set_bit (peeled_loops, loop->num);
return true;
}
/* Adds a canonical induction variable to LOOP if suitable.
@@ -1519,9 +1526,20 @@ pass_complete_unroll::execute (function *fun)
if (number_of_loops (fun) <= 1)
return 0;
- return tree_unroll_loops_completely (flag_unroll_loops
- || flag_peel_loops
- || optimize >= 3, true);
+ /* If we ever decide to run loop peeling more than once, we will need to
+ track loops already peeled in loop structures themselves to avoid
+ re-peeling the same loop multiple times. */
+ if (flag_peel_loops)
+ peeled_loops = BITMAP_ALLOC (NULL);
+ int val = tree_unroll_loops_completely (flag_unroll_loops
+ || flag_peel_loops
+ || optimize >= 3, true);
+ if (peeled_loops)
+ {
+ BITMAP_FREE (peeled_loops);
+ peeled_loops = NULL;
+ }
+ return val;
}
} // anon namespace