OSDN Git Service

2010-02-07 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 7 Feb 2010 13:42:52 +0000 (13:42 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 7 Feb 2010 13:42:52 +0000 (13:42 +0000)
PR middle-end/42956
* gimplify.c (gimple_fold_indirect_ref): Avoid generating
new ARRAY_REFs on variable size element or minimal index arrays.
Complete.
* tree-ssa-loop-ivopts.c (find_interesting_uses_address): Use
gimple_fold_indirect_ref.

* gcc.c-torture/compile/pr42956.c: New testcase.

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

gcc/ChangeLog
gcc/gimplify.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/pr42956.c [new file with mode: 0644]
gcc/tree-ssa-loop-ivopts.c

index d1b5fd3..c05b658 100644 (file)
@@ -1,3 +1,12 @@
+2010-02-07  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/42956
+       * gimplify.c (gimple_fold_indirect_ref): Avoid generating
+       new ARRAY_REFs on variable size element or minimal index arrays.
+       Complete.
+       * tree-ssa-loop-ivopts.c (find_interesting_uses_address): Use
+       gimple_fold_indirect_ref.
+
 2010-02-06  Richard Earnshaw  <rearnsha@arm.com>
 
        PR target/42957
index fac3fda..91dabd1 100644 (file)
@@ -3935,7 +3935,7 @@ gimple_fold_indirect_ref (tree t)
   tree sub = t;
   tree subtype;
 
-  STRIP_USELESS_TYPE_CONVERSION (sub);
+  STRIP_NOPS (sub);
   subtype = TREE_TYPE (sub);
   if (!POINTER_TYPE_P (subtype))
     return NULL_TREE;
@@ -3950,18 +3950,80 @@ gimple_fold_indirect_ref (tree t)
 
       /* *(foo *)&fooarray => fooarray[0] */
       if (TREE_CODE (optype) == ARRAY_TYPE
+         && TREE_CODE (TYPE_SIZE (TREE_TYPE (optype))) == INTEGER_CST
          && useless_type_conversion_p (type, TREE_TYPE (optype)))
        {
          tree type_domain = TYPE_DOMAIN (optype);
          tree min_val = size_zero_node;
          if (type_domain && TYPE_MIN_VALUE (type_domain))
            min_val = TYPE_MIN_VALUE (type_domain);
-         return build4 (ARRAY_REF, type, op, min_val, NULL_TREE, NULL_TREE);
+        if (TREE_CODE (min_val) == INTEGER_CST)
+          return build4 (ARRAY_REF, type, op, min_val, NULL_TREE, NULL_TREE);
        }
+      /* *(foo *)&complexfoo => __real__ complexfoo */
+      else if (TREE_CODE (optype) == COMPLEX_TYPE
+               && useless_type_conversion_p (type, TREE_TYPE (optype)))
+        return fold_build1 (REALPART_EXPR, type, op);
+      /* *(foo *)&vectorfoo => BIT_FIELD_REF<vectorfoo,...> */
+      else if (TREE_CODE (optype) == VECTOR_TYPE
+               && useless_type_conversion_p (type, TREE_TYPE (optype)))
+        {
+          tree part_width = TYPE_SIZE (type);
+          tree index = bitsize_int (0);
+          return fold_build3 (BIT_FIELD_REF, type, op, part_width, index);
+        }
+    }
+
+  /* ((foo*)&vectorfoo)[1] => BIT_FIELD_REF<vectorfoo,...> */
+  if (TREE_CODE (sub) == POINTER_PLUS_EXPR
+      && TREE_CODE (TREE_OPERAND (sub, 1)) == INTEGER_CST)
+    {
+      tree op00 = TREE_OPERAND (sub, 0);
+      tree op01 = TREE_OPERAND (sub, 1);
+      tree op00type;
+
+      STRIP_NOPS (op00);
+      op00type = TREE_TYPE (op00);
+      if (TREE_CODE (op00) == ADDR_EXPR
+         && TREE_CODE (TREE_TYPE (op00type)) == VECTOR_TYPE
+         && useless_type_conversion_p (type, TREE_TYPE (TREE_TYPE (op00type))))
+       {
+         HOST_WIDE_INT offset = tree_low_cst (op01, 0);
+         tree part_width = TYPE_SIZE (type);
+         unsigned HOST_WIDE_INT part_widthi
+           = tree_low_cst (part_width, 0) / BITS_PER_UNIT;
+         unsigned HOST_WIDE_INT indexi = offset * BITS_PER_UNIT;
+         tree index = bitsize_int (indexi);
+         if (offset / part_widthi
+             <= TYPE_VECTOR_SUBPARTS (TREE_TYPE (op00type)))
+           return fold_build3 (BIT_FIELD_REF, type, TREE_OPERAND (op00, 0),
+                               part_width, index);
+       }
+    }
+
+  /* ((foo*)&complexfoo)[1] => __imag__ complexfoo */
+  if (TREE_CODE (sub) == POINTER_PLUS_EXPR
+      && TREE_CODE (TREE_OPERAND (sub, 1)) == INTEGER_CST)
+    {
+      tree op00 = TREE_OPERAND (sub, 0);
+      tree op01 = TREE_OPERAND (sub, 1);
+      tree op00type;
+
+      STRIP_NOPS (op00);
+      op00type = TREE_TYPE (op00);
+      if (TREE_CODE (op00) == ADDR_EXPR
+         && TREE_CODE (TREE_TYPE (op00type)) == COMPLEX_TYPE
+         && useless_type_conversion_p (type, TREE_TYPE (TREE_TYPE (op00type))))
+       {
+         tree size = TYPE_SIZE_UNIT (type);
+         if (tree_int_cst_equal (size, op01))
+           return fold_build1 (IMAGPART_EXPR, type, TREE_OPERAND (op00, 0));
+       }
     }
 
   /* *(foo *)fooarrptr => (*fooarrptr)[0] */
   if (TREE_CODE (TREE_TYPE (subtype)) == ARRAY_TYPE
+      && TREE_CODE (TYPE_SIZE (TREE_TYPE (TREE_TYPE (subtype)))) == INTEGER_CST
       && useless_type_conversion_p (type, TREE_TYPE (TREE_TYPE (subtype))))
     {
       tree type_domain;
@@ -3973,7 +4035,8 @@ gimple_fold_indirect_ref (tree t)
       type_domain = TYPE_DOMAIN (TREE_TYPE (sub));
       if (type_domain && TYPE_MIN_VALUE (type_domain))
         min_val = TYPE_MIN_VALUE (type_domain);
-      return build4 (ARRAY_REF, type, sub, min_val, NULL_TREE, NULL_TREE);
+      if (TREE_CODE (min_val) == INTEGER_CST)
+       return build4 (ARRAY_REF, type, sub, min_val, NULL_TREE, NULL_TREE);
     }
 
   return NULL_TREE;
index d50b950..f9508f0 100644 (file)
@@ -1,3 +1,8 @@
+2010-02-07  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/42956
+       * gcc.c-torture/compile/pr42956.c: New testcase.
+
 2010-02-06  Jerry DeLisle  <jvdelisle@gcc.gnu.org>
 
        PR libfortran/42742
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr42956.c b/gcc/testsuite/gcc.c-torture/compile/pr42956.c
new file mode 100644 (file)
index 0000000..f592d4b
--- /dev/null
@@ -0,0 +1,33 @@
+typedef const int cint;
+typedef struct {
+} Bounds;
+int ndim_, ncomp_, selectedcomp_, nregions_;
+void *voidregion_;
+typedef struct {
+    double diff, err, spread;
+} Errors;
+typedef const Errors cErrors;
+void Split(int iregion, int depth, int xregion)
+{
+  typedef struct {
+      double avg, err, spread, chisq;
+      double xmin[ndim_], xmax[ndim_];
+  } Result;
+  typedef struct region {
+      Result result[ncomp_];
+  } Region;
+  Errors errors[ncomp_];
+  int comp, ireg, xreg;
+  for( ireg = iregion, xreg = xregion; ireg < nregions_; ireg = xreg++ )
+    {
+      Result *result = ((Region *)voidregion_)[ireg].result;
+      for( comp = 0; comp < ncomp_; ++comp )
+       {
+         Result *r = &result[comp];
+         cErrors *e = &errors[comp];
+         double c = e->diff;
+         if( r->err > 0 ) r->err = r->err*e->err + c;
+       }
+    }
+}
+
index 759edb1..436e6ce 100644 (file)
@@ -1686,7 +1686,11 @@ find_interesting_uses_address (struct ivopts_data *data, gimple stmt, tree *op_p
          while (handled_component_p (*ref))
            ref = &TREE_OPERAND (*ref, 0);
          if (TREE_CODE (*ref) == INDIRECT_REF)
-           *ref = fold_indirect_ref (*ref);
+           {
+             tree tem = gimple_fold_indirect_ref (TREE_OPERAND (*ref, 0));
+             if (tem)
+               *ref = tem;
+           }
        }
     }