]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree-ssa-loop-ivopts.c (strip_offset_1): Change parameter type.
authorBin Cheng <bin.cheng@arm.com>
Mon, 28 Oct 2013 03:26:58 +0000 (03:26 +0000)
committerBin Cheng <amker@gcc.gnu.org>
Mon, 28 Oct 2013 03:26:58 +0000 (03:26 +0000)
* tree-ssa-loop-ivopts.c (strip_offset_1): Change parameter type.
Count DECL_FIELD_BIT_OFFSET for COMPONENT_REF.
(strip_offset): Convert offset to unsigned number.

From-SVN: r204116

gcc/ChangeLog
gcc/tree-ssa-loop-ivopts.c

index 8d6147a3188e32b0176e10c0deea4beec3f1ccf4..461439a308b7c273687ad1b0d11312aaf1836d46 100644 (file)
@@ -1,3 +1,9 @@
+2013-10-28  Bin Cheng  <bin.cheng@arm.com>
+
+       * tree-ssa-loop-ivopts.c (strip_offset_1): Change parameter type.
+       Count DECL_FIELD_BIT_OFFSET for COMPONENT_REF.
+       (strip_offset): Convert offset to unsigned number.
+
 2013-10-27  Tom de Vries  <tom@codesourcery.com>
 
        * cfgexpand.c (gimple_expand_cfg): Remove test for parm_birth_insn.
index bd2e6297785525ffa9201df632bbfd3bc054ae3b..0210dbbad3df77299bc5ad12522c798038243ad6 100644 (file)
@@ -2023,12 +2023,12 @@ find_interesting_uses (struct ivopts_data *data)
 
 static tree
 strip_offset_1 (tree expr, bool inside_addr, bool top_compref,
-               unsigned HOST_WIDE_INT *offset)
+               HOST_WIDE_INT *offset)
 {
   tree op0 = NULL_TREE, op1 = NULL_TREE, tmp, step;
   enum tree_code code;
   tree type, orig_type = TREE_TYPE (expr);
-  unsigned HOST_WIDE_INT off0, off1, st;
+  HOST_WIDE_INT off0, off1, st;
   tree orig_expr = expr;
 
   STRIP_NOPS (expr);
@@ -2119,19 +2119,32 @@ strip_offset_1 (tree expr, bool inside_addr, bool top_compref,
       break;
 
     case COMPONENT_REF:
-      if (!inside_addr)
-       return orig_expr;
+      {
+       tree field;
 
-      tmp = component_ref_field_offset (expr);
-      if (top_compref
-         && cst_and_fits_in_hwi (tmp))
-       {
-         /* Strip the component reference completely.  */
-         op0 = TREE_OPERAND (expr, 0);
-         op0 = strip_offset_1 (op0, inside_addr, top_compref, &off0);
-         *offset = off0 + int_cst_value (tmp);
-         return op0;
-       }
+       if (!inside_addr)
+         return orig_expr;
+
+       tmp = component_ref_field_offset (expr);
+       field = TREE_OPERAND (expr, 1);
+       if (top_compref
+           && cst_and_fits_in_hwi (tmp)
+           && cst_and_fits_in_hwi (DECL_FIELD_BIT_OFFSET (field)))
+         {
+           HOST_WIDE_INT boffset, abs_off;
+
+           /* Strip the component reference completely.  */
+           op0 = TREE_OPERAND (expr, 0);
+           op0 = strip_offset_1 (op0, inside_addr, top_compref, &off0);
+           boffset = int_cst_value (DECL_FIELD_BIT_OFFSET (field));
+           abs_off = abs_hwi (boffset) / BITS_PER_UNIT;
+           if (boffset < 0)
+             abs_off = -abs_off;
+
+           *offset = off0 + int_cst_value (tmp) + abs_off;
+           return op0;
+         }
+      }
       break;
 
     case ADDR_EXPR:
@@ -2182,7 +2195,10 @@ strip_offset_1 (tree expr, bool inside_addr, bool top_compref,
 static tree
 strip_offset (tree expr, unsigned HOST_WIDE_INT *offset)
 {
-  return strip_offset_1 (expr, false, false, offset);
+  HOST_WIDE_INT off;
+  tree core = strip_offset_1 (expr, false, false, &off);
+  *offset = off;
+  return core;
 }
 
 /* Returns variant of TYPE that can be used as base for different uses.