aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorBin Cheng <bin.cheng@arm.com>2013-10-28 03:26:58 +0000
committerBin Cheng <amker@gcc.gnu.org>2013-10-28 03:26:58 +0000
commit58fe50d5c90eb14e3cecacf66035751fcc06dd3b (patch)
tree38cdfd7e7a7dee8c0659010ec6aae19ac9d32a29 /gcc
parentb72631e8518562d44530a1a96de427ac6eeca1eb (diff)
downloadgcc-58fe50d5c90eb14e3cecacf66035751fcc06dd3b.zip
gcc-58fe50d5c90eb14e3cecacf66035751fcc06dd3b.tar.gz
gcc-58fe50d5c90eb14e3cecacf66035751fcc06dd3b.tar.bz2
tree-ssa-loop-ivopts.c (strip_offset_1): Change parameter type.
* 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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/tree-ssa-loop-ivopts.c46
2 files changed, 37 insertions, 15 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 8d6147a..461439a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
index bd2e629..0210dbb 100644
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -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.