OSDN Git Service

2009-04-09 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 9 Apr 2009 08:05:43 +0000 (08:05 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 9 Apr 2009 08:05:43 +0000 (08:05 +0000)
* tree-ssa-ccp.c (maybe_fold_stmt_addition): Move non-constant
indices into an array reference if possible.
* tree-ssa-forwprop.c (tree_ssa_forward_propagate_single_use_vars):
Fold POINTER_PLUS_EXPR statements with invariant address.

* gcc.dg/tree-ssa/ssa-ccp-25.c: New testcase.
* gcc.dg/tree-ssa/ssa-ccp-26.c: Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@145799 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-25.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-26.c [new file with mode: 0644]
gcc/tree-ssa-ccp.c
gcc/tree-ssa-forwprop.c

index 581337c..f9ffe70 100644 (file)
@@ -1,3 +1,10 @@
+2009-04-09  Richard Guenther  <rguenther@suse.de>
+
+       * tree-ssa-ccp.c (maybe_fold_stmt_addition): Move non-constant
+       indices into an array reference if possible.
+       * tree-ssa-forwprop.c (tree_ssa_forward_propagate_single_use_vars):
+       Fold POINTER_PLUS_EXPR statements with invariant address.
+
 2009-04-09  Alan Modra  <amodra@bigpond.net.au>
 
        PR target/39634
index 2734327..e56170e 100644 (file)
@@ -1,3 +1,8 @@
+2009-04-09  Richard Guenther  <rguenther@suse.de>
+
+       * gcc.dg/tree-ssa/ssa-ccp-25.c: New testcase.
+       * gcc.dg/tree-ssa/ssa-ccp-26.c: Likewise.
+
 2009-04-09  Joseph Myers  <joseph@codesourcery.com>
 
        PR c/39613
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-25.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-25.c
new file mode 100644 (file)
index 0000000..c6e76a2
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-ccp1 -fdump-tree-forwprop1" } */
+
+int a[256];
+int foo(int i)
+{
+  int *p = &a[0];
+  return *(p + i);
+}
+
+/* { dg-final { scan-tree-dump "&a\\\[D\\\." "ccp1" } } */
+/* { dg-final { scan-tree-dump "= a\\\[D\\\." "forwprop1" } } */
+/* { dg-final { cleanup-tree-dump "ccp1" } } */
+/* { dg-final { cleanup-tree-dump "forwprop1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-26.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-26.c
new file mode 100644 (file)
index 0000000..542c429
--- /dev/null
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-forwprop1" } */
+
+int a[256];
+int foo(int i)
+{
+  return (a + 1)[i];
+}
+
+/* { dg-final { scan-tree-dump "= a\\\[D\\\." "forwprop1" } } */
+/* { dg-final { cleanup-tree-dump "forwprop1" } } */
index a678504..226fd3d 100644 (file)
@@ -2114,14 +2114,47 @@ maybe_fold_stmt_addition (tree res_type, tree op0, tree op1)
   tree ptd_type;
   tree t;
 
-  /* It had better be a constant.  */
-  if (TREE_CODE (op1) != INTEGER_CST)
-    return NULL_TREE;
   /* The first operand should be an ADDR_EXPR.  */
   if (TREE_CODE (op0) != ADDR_EXPR)
     return NULL_TREE;
   op0 = TREE_OPERAND (op0, 0);
 
+  /* It had better be a constant.  */
+  if (TREE_CODE (op1) != INTEGER_CST)
+    {
+      /* Or op0 should now be A[0] and the non-constant offset defined
+        via a multiplication by the array element size.  */
+      if (TREE_CODE (op0) == ARRAY_REF
+         && integer_zerop (TREE_OPERAND (op0, 1))
+         && TREE_CODE (op1) == SSA_NAME
+         && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (op0)), 1))
+       {
+         gimple offset_def = SSA_NAME_DEF_STMT (op1);
+         if (!is_gimple_assign (offset_def))
+           return NULL_TREE;
+
+         if (gimple_assign_rhs_code (offset_def) == MULT_EXPR
+             && TREE_CODE (gimple_assign_rhs2 (offset_def)) == INTEGER_CST
+             && tree_int_cst_equal (gimple_assign_rhs2 (offset_def),
+                                    TYPE_SIZE_UNIT (TREE_TYPE (op0))))
+           return build1 (ADDR_EXPR, res_type,
+                          build4 (ARRAY_REF, TREE_TYPE (op0),
+                                  TREE_OPERAND (op0, 0),
+                                  gimple_assign_rhs1 (offset_def),
+                                  TREE_OPERAND (op0, 2),
+                                  TREE_OPERAND (op0, 3)));
+         else if (integer_onep (TYPE_SIZE_UNIT (TREE_TYPE (op0)))
+                  && gimple_assign_rhs_code (offset_def) != MULT_EXPR)
+           return build1 (ADDR_EXPR, res_type,
+                          build4 (ARRAY_REF, TREE_TYPE (op0),
+                                  TREE_OPERAND (op0, 0),
+                                  op1,
+                                  TREE_OPERAND (op0, 2),
+                                  TREE_OPERAND (op0, 3)));
+       }
+      return NULL_TREE;
+    }
+
   /* If the first operand is an ARRAY_REF, expand it so that we can fold
      the offset into it.  */
   while (TREE_CODE (op0) == ARRAY_REF)
index ff6bda0..f75e0af 100644 (file)
@@ -1256,6 +1256,15 @@ tree_ssa_forward_propagate_single_use_vars (void)
                  else
                    gsi_next (&gsi);
                }
+             else if (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR
+                      && is_gimple_min_invariant (rhs))
+               {
+                 /* Make sure to fold &a[0] + off_1 here.  */
+                 fold_stmt_inplace (stmt);
+                 update_stmt (stmt);
+                 if (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR)
+                   gsi_next (&gsi);
+               }
              else if ((gimple_assign_rhs_code (stmt) == BIT_NOT_EXPR
                        || gimple_assign_rhs_code (stmt) == NEGATE_EXPR)
                       && TREE_CODE (rhs) == SSA_NAME)