2012-03-09 Jiangning Liu <jiangning.liu@arm.com>
authorliujiangning <liujiangning@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 9 Mar 2012 08:45:14 +0000 (08:45 +0000)
committerliujiangning <liujiangning@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 9 Mar 2012 08:45:14 +0000 (08:45 +0000)
* tree-scalar-evolution (interpret_rhs_expr): generate chrec for
array reference and component reference.
(analyze_scalar_evolution_for_address_of): New.

2012-03-09  Jiangning Liu  <jiangning.liu@arm.com>

* gcc.dg/tree-ssa/scev-3.c: New.
* gcc.dg/tree-ssa/scev-4.c: New.

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

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/scev-3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/scev-4.c [new file with mode: 0644]
gcc/tree-scalar-evolution.c

index 10a099d..31bad53 100644 (file)
@@ -1,3 +1,9 @@
+2012-03-09  Jiangning Liu  <jiangning.liu@arm.com>
+
+       * tree-scalar-evolution (interpret_rhs_expr): generate chrec for
+       array reference and component reference.
+       (analyze_scalar_evolution_for_address_of): New.
+
 2012-03-08  Jie Zhang  <jzhang918@gmail.com>
 
        PR target/49862
index 42ce310..ad8c218 100644 (file)
@@ -1,3 +1,8 @@
+2012-03-09  Jiangning Liu  <jiangning.liu@arm.com>
+
+       * gcc.dg/tree-ssa/scev-3.c: New.
+       * gcc.dg/tree-ssa/scev-4.c: New.
+
 2012-03-08  Tobias Burnus  <burnus@net-b.de>
 
        PR fortran/52469
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/scev-3.c b/gcc/testsuite/gcc.dg/tree-ssa/scev-3.c
new file mode 100644 (file)
index 0000000..28d5c93
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int *a_p;
+int a[1000];
+
+f(int k)
+{
+       int i;
+
+       for (i=k; i<1000; i+=k) {
+               a_p = &a[i];
+               *a_p = 100;
+        }
+}
+
+/* { dg-final { scan-tree-dump-times "&a" 1 "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/scev-4.c b/gcc/testsuite/gcc.dg/tree-ssa/scev-4.c
new file mode 100644 (file)
index 0000000..6c1e530
--- /dev/null
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+typedef struct {
+       int x;
+       int y;
+} S;
+
+int *a_p;
+S a[1000];
+
+f(int k)
+{
+       int i;
+
+       for (i=k; i<1000; i+=k) {
+               a_p = &a[i].y;
+               *a_p = 100;
+        }
+}
+
+/* { dg-final { scan-tree-dump-times "&a" 1 "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
index 2077c8d..c719984 100644 (file)
@@ -266,6 +266,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "params.h"
 
 static tree analyze_scalar_evolution_1 (struct loop *, tree, tree);
+static tree analyze_scalar_evolution_for_address_of (struct loop *loop,
+                                                    tree var);
 
 /* The cached information about an SSA name VAR, claiming that below
    basic block INSTANTIATED_BELOW, the value of VAR can be expressed
@@ -1712,16 +1714,59 @@ interpret_rhs_expr (struct loop *loop, gimple at_stmt,
   switch (code)
     {
     case ADDR_EXPR:
-      /* Handle &MEM[ptr + CST] which is equivalent to POINTER_PLUS_EXPR.  */
-      if (TREE_CODE (TREE_OPERAND (rhs1, 0)) != MEM_REF)
-       {
-         res = chrec_dont_know;
-         break;
-       }
+      if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == MEM_REF
+         || handled_component_p (TREE_OPERAND (rhs1, 0)))
+        {
+         enum machine_mode mode;
+         HOST_WIDE_INT bitsize, bitpos;
+         int unsignedp;
+         int volatilep = 0;
+         tree base, offset;
+         tree chrec3;
+         tree unitpos;
+
+         base = get_inner_reference (TREE_OPERAND (rhs1, 0),
+                                     &bitsize, &bitpos, &offset,
+                                     &mode, &unsignedp, &volatilep, false);
+
+         if (TREE_CODE (base) == MEM_REF)
+           {
+             rhs2 = TREE_OPERAND (base, 1);
+             rhs1 = TREE_OPERAND (base, 0);
+
+             chrec1 = analyze_scalar_evolution (loop, rhs1);
+             chrec2 = analyze_scalar_evolution (loop, rhs2);
+             chrec1 = chrec_convert (type, chrec1, at_stmt);
+             chrec2 = chrec_convert (TREE_TYPE (rhs2), chrec2, at_stmt);
+             res = chrec_fold_plus (type, chrec1, chrec2);
+           }
+         else
+           {
+             chrec1 = analyze_scalar_evolution_for_address_of (loop, base);
+             chrec1 = chrec_convert (type, chrec1, at_stmt);
+             res = chrec1;
+           }
+
+         if (offset != NULL_TREE)
+           {
+             chrec2 = analyze_scalar_evolution (loop, offset);
+             chrec2 = chrec_convert (TREE_TYPE (offset), chrec2, at_stmt);
+             res = chrec_fold_plus (type, res, chrec2);
+           }
+
+         if (bitpos != 0)
+           {
+             gcc_assert ((bitpos % BITS_PER_UNIT) == 0);
 
-      rhs2 = TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1);
-      rhs1 = TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0);
-      /* Fall through.  */
+             unitpos = size_int_kind (bitpos / BITS_PER_UNIT, SIZETYPE);
+             chrec3 = analyze_scalar_evolution (loop, unitpos);
+             chrec3 = chrec_convert (TREE_TYPE (unitpos), chrec3, at_stmt);
+             res = chrec_fold_plus (type, res, chrec3);
+           }
+        }
+      else
+       res = chrec_dont_know;
+      break;
 
     case POINTER_PLUS_EXPR:
       chrec1 = analyze_scalar_evolution (loop, rhs1);
@@ -1961,6 +2006,14 @@ analyze_scalar_evolution (struct loop *loop, tree var)
   return res;
 }
 
+/* Analyzes and returns the scalar evolution of VAR address in LOOP.  */
+
+static tree
+analyze_scalar_evolution_for_address_of (struct loop *loop, tree var)
+{
+  return analyze_scalar_evolution (loop, build_fold_addr_expr (var));
+}
+
 /* Analyze scalar evolution of use of VERSION in USE_LOOP with respect to
    WRTO_LOOP (which should be a superloop of USE_LOOP)