diff options
author | vries <vries@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-06-30 08:35:57 +0000 |
---|---|---|
committer | vries <vries@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-06-30 08:35:57 +0000 |
commit | 5d4f3ed8fef038c3a16e962831119564c8094cb0 (patch) | |
tree | ca50ebb2d0d7f8b30b28938281260d4d17f52bd2 /gcc | |
parent | c539ca6d154190665f81482c5dc9cae5b861f636 (diff) | |
download | gcc-5d4f3ed8fef038c3a16e962831119564c8094cb0.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@225162 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt-3.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt-pr66652.c | 31 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt.c | 19 | ||||
-rw-r--r-- | gcc/tree-parloops.c | 31 |
6 files changed, 84 insertions, 13 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 00954b1ef08..9b8c7cff399 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +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. + 2015-06-30 Richard Biener <rguenther@suse.de> * tree-vrp.c (register_edge_assert_for_2): Also register diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9c2f20b2c72..f249a7d7ded 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2015-06-30 Tom de Vries <tom@codesourcery.com> + + PR tree-optimization/66652 + * 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. + 2015-06-29 Paolo Carlini <paolo.carlini@oracle.com> PR c++/65977 diff --git a/gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt-3.c b/gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt-3.c index b0fde372a14..fec53a19628 100644 --- a/gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt-3.c +++ b/gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt-3.c @@ -7,7 +7,7 @@ unsigned int *a; unsigned int -f (unsigned int n) +f (unsigned int n, unsigned int *__restrict__ a) { int i; unsigned int sum = 1; diff --git a/gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt-pr66652.c b/gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt-pr66652.c new file mode 100644 index 00000000000..2ea097d06f9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt-pr66652.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target pthread } */ +/* { dg-options "-O2 -ftree-parallelize-loops=2 -fdump-tree-parloops" } */ + +#include <stdio.h> +#include <stdlib.h> +#include <limits.h> + +unsigned int +f (unsigned int n, unsigned int sum) +{ + unsigned int i; + + i = UINT_MAX; + do + { + sum += i % 13; + i++; + } + while (i < n - 1); + + return sum; +} + +/* Four times % 13: + - once in f._loopfn.0 + - once in the parallel + - once in the low iteration count loop + - once for a peeled off last iteration following the parallel. + In other words, we want try_transform_to_exit_first_loop_alt to fail. */ +/* { dg-final { scan-tree-dump-times "(?n)% 13" 4 "parloops" } } */ diff --git a/gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt.c b/gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt.c index b36f01b8f8f..e088fa110b3 100644 --- a/gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt.c +++ b/gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt.c @@ -4,14 +4,9 @@ /* Variable bound, vector addition. */ -#define N 1000 - -unsigned int a[N]; -unsigned int b[N]; -unsigned int c[N]; - void -f (unsigned int n) +f (unsigned int n, unsigned int *__restrict__ a, unsigned int *__restrict__ b, + unsigned int *__restrict__ c) { int i; @@ -19,9 +14,9 @@ f (unsigned int n) c[i] = a[i] + b[i]; } -/* Three times three array accesses: - - three in f._loopfn.0 - - three in the parallel - - three in the low iteration count loop +/* Three times a store: + - one in f._loopfn.0 + - one in the parallel + - one in the low iteration count loop Crucially, none for a peeled off last iteration following the parallel. */ -/* { dg-final { scan-tree-dump-times "(?n)\\\[i" 9 "parloops" } } */ +/* { dg-final { scan-tree-dump-times "(?n)^ \\*_\[0-9\]*" 3 "parloops" } } */ 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) |