diff mbox

Restrict fixes

Message ID 20110930084051.GB2687@tyan-ft48-01.lab.bos.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek Sept. 30, 2011, 8:40 a.m. UTC
On Fri, Sep 30, 2011 at 09:50:09AM +0200, Richard Guenther wrote:
> Hmm, in fwprop can you limit your change to non-invariant addresses? 
> That is, we do want to propagate invariant addresses over
> restrict casts, because that will give us _more_ precise alias info
> than restrict.

Will it?

I'd think we instead want add the non-restrict -> restrict check
in another spot (ssa_forward_propagate_and_combine) below.
Without that I'm afraid it is harder to disambiguate the accesses
(though, it still fails).  Or should PTA be able to disambiguate
it even without the ssa_forward_propagate_and_combine hunk?
One store will be through p1 + variableoffset with PT { a, <restrict decl for p1> } (restr)
and the other either with the hunk to p2 + constoffset with PT { a, <restrict decl for p2> } (restr)
or without the hunk a + constoffset.

2011-09-30  Jakub Jelinek  <jakub@redhat.com>

	* fold-const.c (fold_unary_loc): Don't optimize
	POINTER_PLUS_EXPR casted to TYPE_RESTRICT pointer by
	casting the inner pointer if it isn't TYPE_RESTRICT.
	* tree-ssa-forwprop.c (forward_propagate_addr_expr_1): Don't through
	casts from non-TYPE_RESTRICT pointer to TYPE_RESTRICT pointer.

	* gcc.dg/tree-ssa/restrict-4.c: New test.
	* gcc.dg/tree-ssa/restrict-5.c: New test.



	Jakub

Comments

Richard Biener Sept. 30, 2011, 8:57 a.m. UTC | #1
On Fri, 30 Sep 2011, Jakub Jelinek wrote:

> On Fri, Sep 30, 2011 at 09:50:09AM +0200, Richard Guenther wrote:
> > Hmm, in fwprop can you limit your change to non-invariant addresses? 
> > That is, we do want to propagate invariant addresses over
> > restrict casts, because that will give us _more_ precise alias info
> > than restrict.
> 
> Will it?

Definitely.  Seeing a decl will enable better offset-based
disambiguation.

> I'd think we instead want add the non-restrict -> restrict check
> in another spot (ssa_forward_propagate_and_combine) below.
> Without that I'm afraid it is harder to disambiguate the accesses
> (though, it still fails).  Or should PTA be able to disambiguate
> it even without the ssa_forward_propagate_and_combine hunk?
> One store will be through p1 + variableoffset with PT { a, <restrict decl for p1> } (restr)
> and the other either with the hunk to p2 + constoffset with PT { a, <restrict decl for p2> } (restr)
> or without the hunk a + constoffset.

But that points-to sets means the pointers are based on a common
pointer (&a), thus they will not be disambiguated.

I fear that we won't ever get

 int * restrict x = p;
 int * restrict y = p + 10;

optimized but not "optimize" a following

 int * restrict x1 = x + 1;

that's the whole point of adding the restrict tags - to be able to
follow to a common base-object conservatively.

Richard.

> 2011-09-30  Jakub Jelinek  <jakub@redhat.com>
> 
> 	* fold-const.c (fold_unary_loc): Don't optimize
> 	POINTER_PLUS_EXPR casted to TYPE_RESTRICT pointer by
> 	casting the inner pointer if it isn't TYPE_RESTRICT.
> 	* tree-ssa-forwprop.c (forward_propagate_addr_expr_1): Don't through
> 	casts from non-TYPE_RESTRICT pointer to TYPE_RESTRICT pointer.
> 
> 	* gcc.dg/tree-ssa/restrict-4.c: New test.
> 	* gcc.dg/tree-ssa/restrict-5.c: New test.
> 
> --- gcc/fold-const.c.jj	2011-09-29 14:25:46.000000000 +0200
> +++ gcc/fold-const.c	2011-09-29 18:20:04.000000000 +0200
> @@ -7929,6 +7929,7 @@ fold_unary_loc (location_t loc, enum tre
>  	 that this happens when X or Y is NOP_EXPR or Y is INTEGER_CST. */
>        if (POINTER_TYPE_P (type)
>  	  && TREE_CODE (arg0) == POINTER_PLUS_EXPR
> +	  && (!TYPE_RESTRICT (type) || TYPE_RESTRICT (TREE_TYPE (arg0)))
>  	  && (TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
>  	      || TREE_CODE (TREE_OPERAND (arg0, 0)) == NOP_EXPR
>  	      || TREE_CODE (TREE_OPERAND (arg0, 1)) == NOP_EXPR))
> --- gcc/tree-ssa-forwprop.c.jj	2011-09-15 12:18:54.000000000 +0200
> +++ gcc/tree-ssa-forwprop.c	2011-09-30 10:02:46.000000000 +0200
> @@ -804,6 +804,10 @@ forward_propagate_addr_expr_1 (tree name
>        && ((rhs_code == SSA_NAME && rhs == name)
>  	  || CONVERT_EXPR_CODE_P (rhs_code)))
>      {
> +      /* Don't propagate restrict pointer's RHS.  */
> +      if (TYPE_RESTRICT (TREE_TYPE (lhs))
> +	  && !TYPE_RESTRICT (TREE_TYPE (name)))
> +	return false;
>        /* Only recurse if we don't deal with a single use or we cannot
>  	 do the propagation to the current statement.  In particular
>  	 we can end up with a conversion needed for a non-invariant
> @@ -2392,7 +2396,9 @@ ssa_forward_propagate_and_combine (void)
>  		 as well, as this is valid gimple.  */
>  	      || (CONVERT_EXPR_CODE_P (code)
>  		  && TREE_CODE (rhs) == ADDR_EXPR
> -		  && POINTER_TYPE_P (TREE_TYPE (lhs))))
> +		  && POINTER_TYPE_P (TREE_TYPE (lhs))
> +		  && (!TYPE_RESTRICT (TREE_TYPE (lhs))
> +		      || TYPE_RESTRICT (TREE_TYPE (rhs)))))
>  	    {
>  	      tree base = get_base_address (TREE_OPERAND (rhs, 0));
>  	      if ((!base
> --- gcc/testsuite/gcc.dg/tree-ssa/restrict-4.c.jj	2011-09-29 20:21:00.000000000 +0200
> +++ gcc/testsuite/gcc.dg/tree-ssa/restrict-4.c	2011-09-29 20:21:57.000000000 +0200
> @@ -0,0 +1,26 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized" } */
> +
> +int
> +foo (int *x, int y)
> +{
> +  int *__restrict p1 = x;
> +  int *__restrict p2 = x + 32;
> +  p1[y] = 1;
> +  p2[4] = 2;
> +  return p1[y];
> +}
> +
> +int
> +bar (int *x, int y)
> +{
> +  int *__restrict p1 = x;
> +  int *p3 = x + 32;
> +  int *__restrict p2 = p3;
> +  p1[y] = 1;
> +  p2[4] = 2;
> +  return p1[y];
> +}
> +
> +/* { dg-final { scan-tree-dump-times "return 1;" 2 "optimized" } } */
> +/* { dg-final { cleanup-tree-dump "optimized" } } */
> --- gcc/testsuite/gcc.dg/tree-ssa/restrict-5.c.jj	2011-09-30 10:04:45.000000000 +0200
> +++ gcc/testsuite/gcc.dg/tree-ssa/restrict-5.c	2011-09-30 10:05:11.000000000 +0200
> @@ -0,0 +1,17 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized" } */
> +
> +int a[64];
> +
> +int
> +foo (int x)
> +{
> +  int *__restrict p1 = a + 4;
> +  int *__restrict p2 = a + 16;
> +  p1[x] = 1;
> +  p2[2] = 2;
> +  return p1[x];
> +}
> +
> +/* { dg-final { scan-tree-dump-times "return 1;" 1 "optimized" } } */
> +/* { dg-final { cleanup-tree-dump "optimized" } } */
> 
> 
> 	Jakub
> 
>
diff mbox

Patch

--- gcc/fold-const.c.jj	2011-09-29 14:25:46.000000000 +0200
+++ gcc/fold-const.c	2011-09-29 18:20:04.000000000 +0200
@@ -7929,6 +7929,7 @@  fold_unary_loc (location_t loc, enum tre
 	 that this happens when X or Y is NOP_EXPR or Y is INTEGER_CST. */
       if (POINTER_TYPE_P (type)
 	  && TREE_CODE (arg0) == POINTER_PLUS_EXPR
+	  && (!TYPE_RESTRICT (type) || TYPE_RESTRICT (TREE_TYPE (arg0)))
 	  && (TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
 	      || TREE_CODE (TREE_OPERAND (arg0, 0)) == NOP_EXPR
 	      || TREE_CODE (TREE_OPERAND (arg0, 1)) == NOP_EXPR))
--- gcc/tree-ssa-forwprop.c.jj	2011-09-15 12:18:54.000000000 +0200
+++ gcc/tree-ssa-forwprop.c	2011-09-30 10:02:46.000000000 +0200
@@ -804,6 +804,10 @@  forward_propagate_addr_expr_1 (tree name
       && ((rhs_code == SSA_NAME && rhs == name)
 	  || CONVERT_EXPR_CODE_P (rhs_code)))
     {
+      /* Don't propagate restrict pointer's RHS.  */
+      if (TYPE_RESTRICT (TREE_TYPE (lhs))
+	  && !TYPE_RESTRICT (TREE_TYPE (name)))
+	return false;
       /* Only recurse if we don't deal with a single use or we cannot
 	 do the propagation to the current statement.  In particular
 	 we can end up with a conversion needed for a non-invariant
@@ -2392,7 +2396,9 @@  ssa_forward_propagate_and_combine (void)
 		 as well, as this is valid gimple.  */
 	      || (CONVERT_EXPR_CODE_P (code)
 		  && TREE_CODE (rhs) == ADDR_EXPR
-		  && POINTER_TYPE_P (TREE_TYPE (lhs))))
+		  && POINTER_TYPE_P (TREE_TYPE (lhs))
+		  && (!TYPE_RESTRICT (TREE_TYPE (lhs))
+		      || TYPE_RESTRICT (TREE_TYPE (rhs)))))
 	    {
 	      tree base = get_base_address (TREE_OPERAND (rhs, 0));
 	      if ((!base
--- gcc/testsuite/gcc.dg/tree-ssa/restrict-4.c.jj	2011-09-29 20:21:00.000000000 +0200
+++ gcc/testsuite/gcc.dg/tree-ssa/restrict-4.c	2011-09-29 20:21:57.000000000 +0200
@@ -0,0 +1,26 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int
+foo (int *x, int y)
+{
+  int *__restrict p1 = x;
+  int *__restrict p2 = x + 32;
+  p1[y] = 1;
+  p2[4] = 2;
+  return p1[y];
+}
+
+int
+bar (int *x, int y)
+{
+  int *__restrict p1 = x;
+  int *p3 = x + 32;
+  int *__restrict p2 = p3;
+  p1[y] = 1;
+  p2[4] = 2;
+  return p1[y];
+}
+
+/* { dg-final { scan-tree-dump-times "return 1;" 2 "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
--- gcc/testsuite/gcc.dg/tree-ssa/restrict-5.c.jj	2011-09-30 10:04:45.000000000 +0200
+++ gcc/testsuite/gcc.dg/tree-ssa/restrict-5.c	2011-09-30 10:05:11.000000000 +0200
@@ -0,0 +1,17 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int a[64];
+
+int
+foo (int x)
+{
+  int *__restrict p1 = a + 4;
+  int *__restrict p2 = a + 16;
+  p1[x] = 1;
+  p2[2] = 2;
+  return p1[x];
+}
+
+/* { dg-final { scan-tree-dump-times "return 1;" 1 "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */