diff options
author | amker <amker@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-10-28 03:26:58 +0000 |
---|---|---|
committer | amker <amker@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-10-28 03:26:58 +0000 |
commit | 9ea161a31419c6b0460dd885b5f08794c89b1a6d (patch) | |
tree | 38cdfd7e7a7dee8c0659010ec6aae19ac9d32a29 /gcc/tree-ssa-loop-ivopts.c | |
parent | f00d11dd45a582d1bbe09dc6f30f43db8e3f258d (diff) | |
download | gcc-9ea161a31419c6b0460dd885b5f08794c89b1a6d.tar.gz |
* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@204116 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-ssa-loop-ivopts.c')
-rw-r--r-- | gcc/tree-ssa-loop-ivopts.c | 46 |
1 files changed, 31 insertions, 15 deletions
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c index bd2e6297785..0210dbbad3d 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. |