aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-sra.c
diff options
context:
space:
mode:
authorMartin Jambor <mjambor@suse.cz>2012-04-16 18:04:45 +0200
committerMartin Jambor <jamborm@gcc.gnu.org>2012-04-16 18:04:45 +0200
commit36e57e16d9d4e0e797154b87c6bb2e981982dbc5 (patch)
tree4ef44cc3e760b65794e2ffab8168c26b6b45066d /gcc/tree-sra.c
parent051b40ff6b44e7bfc6518db84ca56ccc10f95f57 (diff)
downloadgcc-36e57e16d9d4e0e797154b87c6bb2e981982dbc5.zip
gcc-36e57e16d9d4e0e797154b87c6bb2e981982dbc5.tar.gz
gcc-36e57e16d9d4e0e797154b87c6bb2e981982dbc5.tar.bz2
tree-sra.c (build_ref_for_model): Create COMPONENT_REFs only for bit-fields.
2012-04-16 Martin Jambor <mjambor@suse.cz> * tree-sra.c (build_ref_for_model): Create COMPONENT_REFs only for bit-fields. From-SVN: r186501
Diffstat (limited to 'gcc/tree-sra.c')
-rw-r--r--gcc/tree-sra.c72
1 files changed, 17 insertions, 55 deletions
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index c9d0159..e69f3ac 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -1489,70 +1489,32 @@ build_ref_for_offset (location_t loc, tree base, HOST_WIDE_INT offset,
return fold_build2_loc (loc, MEM_REF, exp_type, base, off);
}
-DEF_VEC_ALLOC_P_STACK (tree);
-#define VEC_tree_stack_alloc(alloc) VEC_stack_alloc (tree, alloc)
-
/* Construct a memory reference to a part of an aggregate BASE at the given
- OFFSET and of the type of MODEL. In case this is a chain of references
- to component, the function will replicate the chain of COMPONENT_REFs of
- the expression of MODEL to access it. GSI and INSERT_AFTER have the same
- meaning as in build_ref_for_offset. */
+ OFFSET and of the same type as MODEL. In case this is a reference to a
+ bit-field, the function will replicate the last component_ref of model's
+ expr to access it. GSI and INSERT_AFTER have the same meaning as in
+ build_ref_for_offset. */
static tree
build_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset,
struct access *model, gimple_stmt_iterator *gsi,
bool insert_after)
{
- tree type = model->type, t;
- VEC(tree,stack) *cr_stack = NULL;
-
- if (TREE_CODE (model->expr) == COMPONENT_REF)
- {
- tree expr = model->expr;
-
- /* Create a stack of the COMPONENT_REFs so later we can walk them in
- order from inner to outer. */
- cr_stack = VEC_alloc (tree, stack, 6);
-
- do {
- tree field = TREE_OPERAND (expr, 1);
- tree cr_offset = component_ref_field_offset (expr);
- HOST_WIDE_INT bit_pos
- = tree_low_cst (cr_offset, 1) * BITS_PER_UNIT
- + TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (field));
-
- /* We can be called with a model different from the one associated
- with BASE so we need to avoid going up the chain too far. */
- if (offset - bit_pos < 0)
- break;
-
- offset -= bit_pos;
- VEC_safe_push (tree, stack, cr_stack, expr);
-
- expr = TREE_OPERAND (expr, 0);
- type = TREE_TYPE (expr);
- } while (TREE_CODE (expr) == COMPONENT_REF);
- }
-
- t = build_ref_for_offset (loc, base, offset, type, gsi, insert_after);
-
- if (TREE_CODE (model->expr) == COMPONENT_REF)
+ if (TREE_CODE (model->expr) == COMPONENT_REF
+ && DECL_BIT_FIELD (TREE_OPERAND (model->expr, 1)))
{
- unsigned i;
- tree expr;
-
- /* Now replicate the chain of COMPONENT_REFs from inner to outer. */
- FOR_EACH_VEC_ELT_REVERSE (tree, cr_stack, i, expr)
- {
- tree field = TREE_OPERAND (expr, 1);
- t = fold_build3_loc (loc, COMPONENT_REF, TREE_TYPE (field), t, field,
- TREE_OPERAND (expr, 2));
- }
-
- VEC_free (tree, stack, cr_stack);
+ /* This access represents a bit-field. */
+ tree t, exp_type, fld = TREE_OPERAND (model->expr, 1);
+
+ offset -= int_bit_position (fld);
+ exp_type = TREE_TYPE (TREE_OPERAND (model->expr, 0));
+ t = build_ref_for_offset (loc, base, offset, exp_type, gsi, insert_after);
+ return fold_build3_loc (loc, COMPONENT_REF, TREE_TYPE (fld), t, fld,
+ NULL_TREE);
}
-
- return t;
+ else
+ return build_ref_for_offset (loc, base, offset, model->type,
+ gsi, insert_after);
}
/* Construct a memory reference consisting of component_refs and array_refs to