summaryrefslogtreecommitdiff
path: root/gcc/tree-parloops.c
diff options
context:
space:
mode:
authorTom de Vries <tom@codesourcery.com>2015-06-30 08:35:57 +0000
committerTom de Vries <vries@gcc.gnu.org>2015-06-30 08:35:57 +0000
commit4f75d60893e092cffcbe422825ce4dc092d3fb9e (patch)
treeca50ebb2d0d7f8b30b28938281260d4d17f52bd2 /gcc/tree-parloops.c
parent4fe651724763ce1a438b5497621510a4185e069e (diff)
Use max_loop_iterations in transform_to_exit_first_loop_alt
2015-06-30 Tom de Vries <tom@codesourcery.com> PR tree-optimization/66652 * tree-parloops.c (try_transform_to_exit_first_loop_alt): Use max_loop_iterations to determine if nit + 1 overflows. * testsuite/libgomp.c/parloops-exit-first-loop-alt-3.c (f): Rewrite using restrict pointers. (main): Add arguments to calls to f. * testsuite/libgomp.c/parloops-exit-first-loop-alt.c: Same. * gcc.dg/parloops-exit-first-loop-alt-pr66652.c: New test. * gcc.dg/parloops-exit-first-loop-alt-3.c (f): Rewrite using restrict pointers. * gcc.dg/parloops-exit-first-loop-alt.c: Same. From-SVN: r225162
Diffstat (limited to 'gcc/tree-parloops.c')
-rw-r--r--gcc/tree-parloops.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/gcc/tree-parloops.c b/gcc/tree-parloops.c
index ec708c67ac9..21ed17b4caf 100644
--- a/gcc/tree-parloops.c
+++ b/gcc/tree-parloops.c
@@ -1801,8 +1801,39 @@ try_transform_to_exit_first_loop_alt (struct loop *loop,
gcc_assert (TREE_CODE (nit) == SSA_NAME);
+ /* Variable nit is the loop bound as returned by canonicalize_loop_ivs, for an
+ iv with base 0 and step 1 that is incremented in the latch, like this:
+
+ <bb header>:
+ # iv_1 = PHI <0 (preheader), iv_2 (latch)>
+ ...
+ if (iv_1 < nit)
+ goto <bb latch>;
+ else
+ goto <bb exit>;
+
+ <bb latch>:
+ iv_2 = iv_1 + 1;
+ goto <bb header>;
+
+ The range of iv_1 is [0, nit]. The latch edge is taken for
+ iv_1 == [0, nit - 1] and the exit edge is taken for iv_1 == nit. So the
+ number of latch executions is equal to nit.
+
+ The function max_loop_iterations gives us the maximum number of latch
+ executions, so it gives us the maximum value of nit. */
+ widest_int nit_max;
+ if (!max_loop_iterations (loop, &nit_max))
+ return false;
+
+ /* Check if nit + 1 overflows. */
+ widest_int type_max = wi::to_widest (TYPE_MAXVAL (nit_type));
+ if (!wi::lts_p (nit_max, type_max))
+ return false;
+
gimple def = SSA_NAME_DEF_STMT (nit);
+ /* Try to find nit + 1, in the form of n in an assignment nit = n - 1. */
if (def
&& is_gimple_assign (def)
&& gimple_assign_rhs_code (def) == PLUS_EXPR)