Re: [gomp4][PATCH] Handle casts in bound in try_transform_to_exit_first_loop_alt

2015-06-29 Thread Tom de Vries

On 22/06/15 16:36, Richard Biener wrote:

On Thu, 18 Jun 2015, Tom de Vries wrote:


On 13/06/15 16:24, Tom de Vries wrote:

Hi,

this patch allows try_transform_to_exit_first_loop_alt to succeed when
handling cases where the expression representing the number of
iterations contains a cast.

Currently, transform_to_exit_first_loop_alt testcase
gfortran/parloops-exit-first-loop-alt.f95 will fail.

The nit is _19, which is defined as follows:
...
_20 = _6 + -1;
_19 = (unsigned int) _20;
...
And transform_to_exit_first_loop_alt currently only handles nits with
defining stmt 'nit = x - 1', for which it finds alt_bound 'x'.

The patch:
- uses try_get_loop_niter to get nit as a nested tree expression
'(unsigned int) (_6 + -1)'
- strips the outer nops (assuming no change in value)
- uses '(unsigned int)_6' as the alt_bound, and
- gimplifies the expression.

Bootstrapped and reg-tested on x86_64.



Cleaned up whitespace in testcases.

Committed to gomp-4_0-branch as atttached.


OK for trunk?



I assume the above also handles the reverse, (int) (_6 + -1)?


AFAIU, niter.niter is always unsigned.


In this case what happens if _6 == INT_MAX + 1?  nit is INT_MAX
but (int) _6 is INT_MIN.

Likewise what happens if _6 + -1 under-/overflows?



While playing around with underflow/overflow cases, I ran into PR66652, 
which reproduces on trunk.


I've submitted for trunk:
- https://gcc.gnu.org/ml/gcc-patches/2015-06/msg02084.html , which
  fixes PR66652, and should handle all overflow concerns.
- https://gcc.gnu.org/ml/gcc-patches/2015-06/msg02085.html , which deals
  with the case that nit is not defined by assignment nit = n - 1, in
  other words, with the case that this patch is trying to address.

I'll revert this patch on gomp-4_0-branch, and commit these patches 
instead (in addition to 
https://gcc.gnu.org/ml/gcc-patches/2015-06/msg01768.html, which fixes 
low iteration count reduction loops handled by 
transform_to_exit_first_loop_alt).


Thanks,
- Tom


Re: [gomp4][PATCH] Handle casts in bound in try_transform_to_exit_first_loop_alt

2015-06-22 Thread Richard Biener
On Thu, 18 Jun 2015, Tom de Vries wrote:

 On 13/06/15 16:24, Tom de Vries wrote:
  Hi,
  
  this patch allows try_transform_to_exit_first_loop_alt to succeed when
  handling cases where the expression representing the number of
  iterations contains a cast.
  
  Currently, transform_to_exit_first_loop_alt testcase
  gfortran/parloops-exit-first-loop-alt.f95 will fail.
  
  The nit is _19, which is defined as follows:
  ...
  _20 = _6 + -1;
  _19 = (unsigned int) _20;
  ...
  And transform_to_exit_first_loop_alt currently only handles nits with
  defining stmt 'nit = x - 1', for which it finds alt_bound 'x'.
  
  The patch:
  - uses try_get_loop_niter to get nit as a nested tree expression
 '(unsigned int) (_6 + -1)'
  - strips the outer nops (assuming no change in value)
  - uses '(unsigned int)_6' as the alt_bound, and
  - gimplifies the expression.
  
  Bootstrapped and reg-tested on x86_64.
  
 
 Cleaned up whitespace in testcases.
 
 Committed to gomp-4_0-branch as atttached.
 
  OK for trunk?
  

I assume the above also handles the reverse, (int) (_6 + -1)?
In this case what happens if _6 == INT_MAX + 1?  nit is INT_MAX
but (int) _6 is INT_MIN.

Likewise what happens if _6 + -1 under-/overflows?

Richard.

 Thanks,
 - Tom
 
 

-- 
Richard Biener rguent...@suse.de
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Dilip Upmanyu, Graham 
Norton, HRB 21284 (AG Nuernberg)


[gomp4][PATCH] Handle casts in bound in try_transform_to_exit_first_loop_alt

2015-06-18 Thread Tom de Vries

On 13/06/15 16:24, Tom de Vries wrote:

Hi,

this patch allows try_transform_to_exit_first_loop_alt to succeed when
handling cases where the expression representing the number of
iterations contains a cast.

Currently, transform_to_exit_first_loop_alt testcase
gfortran/parloops-exit-first-loop-alt.f95 will fail.

The nit is _19, which is defined as follows:
...
_20 = _6 + -1;
_19 = (unsigned int) _20;
...
And transform_to_exit_first_loop_alt currently only handles nits with
defining stmt 'nit = x - 1', for which it finds alt_bound 'x'.

The patch:
- uses try_get_loop_niter to get nit as a nested tree expression
   '(unsigned int) (_6 + -1)'
- strips the outer nops (assuming no change in value)
- uses '(unsigned int)_6' as the alt_bound, and
- gimplifies the expression.

Bootstrapped and reg-tested on x86_64.



Cleaned up whitespace in testcases.

Committed to gomp-4_0-branch as atttached.


OK for trunk?



Thanks,
- Tom

Handle casts in bound in transform_to_exit_first_loop_alt

2015-06-13  Tom de Vries  t...@codesourcery.com

	* tree-parloops.c (transform_to_exit_first_loop_alt): Add update_stmt
	for cond_stmt.
	(try_get_loop_niter): Declare forward.
	(try_transform_to_exit_first_loop_alt): Use try_get_loop_niter to get
	updated number of iterations.  Extract alt_bount, and instantiate it.

	* testsuite/libgomp.fortran/parloops-exit-first-loop-alt-2.f95: New test.
	* testsuite/libgomp.fortran/parloops-exit-first-loop-alt.f95: New test.

	* gfortran.dg/parloops-exit-first-loop-alt-2.f95: New test.
	* gfortran.dg/parloops-exit-first-loop-alt.f95: New test.
---
 .../gfortran.dg/parloops-exit-first-loop-alt-2.f95 | 24 +
 .../gfortran.dg/parloops-exit-first-loop-alt.f95   | 25 +
 gcc/tree-parloops.c| 59 +-
 .../parloops-exit-first-loop-alt-2.f95 | 40 +++
 .../parloops-exit-first-loop-alt.f95   | 41 +++
 5 files changed, 164 insertions(+), 25 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/parloops-exit-first-loop-alt-2.f95
 create mode 100644 gcc/testsuite/gfortran.dg/parloops-exit-first-loop-alt.f95
 create mode 100644 libgomp/testsuite/libgomp.fortran/parloops-exit-first-loop-alt-2.f95
 create mode 100644 libgomp/testsuite/libgomp.fortran/parloops-exit-first-loop-alt.f95

diff --git a/gcc/testsuite/gfortran.dg/parloops-exit-first-loop-alt-2.f95 b/gcc/testsuite/gfortran.dg/parloops-exit-first-loop-alt-2.f95
new file mode 100644
index 000..f26a6e3
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/parloops-exit-first-loop-alt-2.f95
@@ -0,0 +1,24 @@
+! { dg-additional-options -O2 }
+! { dg-require-effective-target pthread }
+! { dg-additional-options -ftree-parallelize-loops=2 }
+! { dg-additional-options -fdump-tree-parloops }
+
+! Constant bound, vector addition.
+
+subroutine foo ()
+  integer, parameter :: n = 1000
+  integer, dimension (0:n-1) :: a, b, c
+  common a, b, c
+  integer :: ii
+
+  do ii = 0, n - 1
+ c(ii) = a(ii) + b(ii) + 25
+  end do
+end subroutine foo
+
+! Three times plus 25:
+! - once in f._loopfn.0
+! - once in the parallel
+! - once in the low iteration count loop
+! Crucially, none for a peeled off last iteration following the parallel.
+! { dg-final { scan-tree-dump-times (?n) \\+ 25; 3 parloops } }
diff --git a/gcc/testsuite/gfortran.dg/parloops-exit-first-loop-alt.f95 b/gcc/testsuite/gfortran.dg/parloops-exit-first-loop-alt.f95
new file mode 100644
index 000..6dc8a38
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/parloops-exit-first-loop-alt.f95
@@ -0,0 +1,25 @@
+! { dg-additional-options -O2 }
+! { dg-require-effective-target pthread }
+! { dg-additional-options -ftree-parallelize-loops=2 }
+! { dg-additional-options -fdump-tree-parloops }
+
+! Variable bound, vector addition.
+
+subroutine foo (nr)
+  integer, intent(in) :: nr
+  integer, parameter :: n = 1000
+  integer, dimension (0:n-1) :: a, b, c
+  common a, b, c
+  integer :: ii
+
+  do ii = 0, nr - 1
+ c(ii) = a(ii) + b(ii) + 25
+  end do
+end subroutine foo
+
+! Three times plus 25:
+! - once in f._loopfn.0
+! - once in the parallel
+! - once in the low iteration count loop
+! Crucially, none for a peeled off last iteration following the parallel.
+! { dg-final { scan-tree-dump-times (?n) \\+ 25; 3 parloops } }
diff --git a/gcc/tree-parloops.c b/gcc/tree-parloops.c
index 209cf0c..678e458 100644
--- a/gcc/tree-parloops.c
+++ b/gcc/tree-parloops.c
@@ -1684,6 +1684,7 @@ transform_to_exit_first_loop_alt (struct loop *loop,
 
   /* Set the new loop bound.  */
   gimple_cond_set_rhs (cond_stmt, bound);
+  update_stmt (cond_stmt);
 
   /* Repair the ssa.  */
   vecedge_var_map *v = redirect_edge_var_map_vector (post_inc_edge);
@@ -1761,6 +1762,8 @@ transform_to_exit_first_loop_alt (struct loop *loop,
   calculate_dominance_info (CDI_DOMINATORS);
 }
 
+static bool try_get_loop_niter (loop_p, struct tree_niter_desc *);
+
 /* Tries to moves the exit condition of LOOP to the beginning of its 

[PATCH] Handle casts in bound in try_transform_to_exit_first_loop_alt

2015-06-13 Thread Tom de Vries

Hi,

this patch allows try_transform_to_exit_first_loop_alt to succeed when 
handling cases where the expression representing the number of 
iterations contains a cast.


Currently, transform_to_exit_first_loop_alt testcase 
gfortran/parloops-exit-first-loop-alt.f95 will fail.


The nit is _19, which is defined as follows:
...
_20 = _6 + -1;
_19 = (unsigned int) _20;
...
And transform_to_exit_first_loop_alt currently only handles nits with 
defining stmt 'nit = x - 1', for which it finds alt_bound 'x'.


The patch:
- uses try_get_loop_niter to get nit as a nested tree expression
  '(unsigned int) (_6 + -1)'
- strips the outer nops (assuming no change in value)
- uses '(unsigned int)_6' as the alt_bound, and
- gimplifies the expression.

Bootstrapped and reg-tested on x86_64.

OK for trunk?

Thanks,
- Tom
Handle casts in bound in transform_to_exit_first_loop_alt

2015-06-13  Tom de Vries  t...@codesourcery.com

	* tree-parloops.c (transform_to_exit_first_loop_alt): Add update_stmt
	for cond_stmt.
	(try_get_loop_niter): Declare forward.
	(try_transform_to_exit_first_loop_alt): Use try_get_loop_niter to get
	updated number of iterations.  Extract alt_bount, and instantiate it.

	* testsuite/libgomp.fortran/parloops-exit-first-loop-alt-2.f95: New test.
	* testsuite/libgomp.fortran/parloops-exit-first-loop-alt.f95: New test.

	* gfortran.dg/parloops-exit-first-loop-alt-2.f95: New test.
	* gfortran.dg/parloops-exit-first-loop-alt.f95: New test.
---
 .../gfortran.dg/parloops-exit-first-loop-alt-2.f95 | 24 +
 .../gfortran.dg/parloops-exit-first-loop-alt.f95   | 25 +
 gcc/tree-parloops.c| 59 +-
 .../parloops-exit-first-loop-alt-2.f95 | 40 +++
 .../parloops-exit-first-loop-alt.f95   | 41 +++
 5 files changed, 164 insertions(+), 25 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/parloops-exit-first-loop-alt-2.f95
 create mode 100644 gcc/testsuite/gfortran.dg/parloops-exit-first-loop-alt.f95
 create mode 100644 libgomp/testsuite/libgomp.fortran/parloops-exit-first-loop-alt-2.f95
 create mode 100644 libgomp/testsuite/libgomp.fortran/parloops-exit-first-loop-alt.f95

diff --git a/gcc/testsuite/gfortran.dg/parloops-exit-first-loop-alt-2.f95 b/gcc/testsuite/gfortran.dg/parloops-exit-first-loop-alt-2.f95
new file mode 100644
index 000..a785bf9
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/parloops-exit-first-loop-alt-2.f95
@@ -0,0 +1,24 @@
+! { dg-additional-options -O2 }
+! { dg-require-effective-target pthread }
+! { dg-additional-options -ftree-parallelize-loops=2 }
+! { dg-additional-options -fdump-tree-parloops }
+
+! Constant bound, vector addition.
+
+subroutine foo()
+  integer, parameter :: n = 1000
+  integer, dimension (0:n-1) :: a, b, c
+  common a, b, c
+  integer:: ii
+
+  do ii = 0, n - 1
+ c(ii) = a(ii) + b(ii) + 25
+  end do
+end subroutine foo
+
+! Three times plus 25:
+! - once in f._loopfn.0
+! - once in the parallel
+! - once in the low iteration count loop
+! Crucially, none for a peeled off last iteration following the parallel.
+! { dg-final { scan-tree-dump-times (?n) \\+ 25; 3 parloops } }
diff --git a/gcc/testsuite/gfortran.dg/parloops-exit-first-loop-alt.f95 b/gcc/testsuite/gfortran.dg/parloops-exit-first-loop-alt.f95
new file mode 100644
index 000..3873ca2a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/parloops-exit-first-loop-alt.f95
@@ -0,0 +1,25 @@
+! { dg-additional-options -O2 }
+! { dg-require-effective-target pthread }
+! { dg-additional-options -ftree-parallelize-loops=2 }
+! { dg-additional-options -fdump-tree-parloops }
+
+! Variable bound, vector addition.
+
+subroutine foo(nr)
+  integer, intent(in)   :: nr
+  integer, parameter :: n = 1000
+  integer, dimension (0:n-1) :: a, b, c
+  common a, b, c
+  integer:: ii
+
+  do ii = 0, nr - 1
+ c(ii) = a(ii) + b(ii) + 25
+  end do
+end subroutine foo
+
+! Three times plus 25:
+! - once in f._loopfn.0
+! - once in the parallel
+! - once in the low iteration count loop
+! Crucially, none for a peeled off last iteration following the parallel.
+! { dg-final { scan-tree-dump-times (?n) \\+ 25; 3 parloops } }
diff --git a/gcc/tree-parloops.c b/gcc/tree-parloops.c
index 3495ac1..6e10901 100644
--- a/gcc/tree-parloops.c
+++ b/gcc/tree-parloops.c
@@ -1678,6 +1678,7 @@ transform_to_exit_first_loop_alt (struct loop *loop,
 
   /* Set the new loop bound.  */
   gimple_cond_set_rhs (cond_stmt, bound);
+  update_stmt (cond_stmt);
 
   /* Repair the ssa.  */
   vecedge_var_map *v = redirect_edge_var_map_vector (post_inc_edge);
@@ -1755,6 +1756,8 @@ transform_to_exit_first_loop_alt (struct loop *loop,
   calculate_dominance_info (CDI_DOMINATORS);
 }
 
+static bool try_get_loop_niter (loop_p, struct tree_niter_desc *);
+
 /* Tries to moves the exit condition of LOOP to the beginning of its header
without duplication of the loop body.  NIT is the