Commit 36e57e16 by Martin Jambor Committed by Martin Jambor

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
parent 051b40ff
2012-04-16 Martin Jambor <mjambor@suse.cz>
* tree-sra.c (build_ref_for_model): Create COMPONENT_REFs only for
bit-fields.
2012-04-16 Ulrich Weigand <ulrich.weigand@linaro.org> 2012-04-16 Ulrich Weigand <ulrich.weigand@linaro.org>
PR target/51819 PR target/51819
......
...@@ -1489,70 +1489,32 @@ build_ref_for_offset (location_t loc, tree base, HOST_WIDE_INT offset, ...@@ -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); 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 /* 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 OFFSET and of the same type as MODEL. In case this is a reference to a
to component, the function will replicate the chain of COMPONENT_REFs of bit-field, the function will replicate the last component_ref of model's
the expression of MODEL to access it. GSI and INSERT_AFTER have the same expr to access it. GSI and INSERT_AFTER have the same meaning as in
meaning as in build_ref_for_offset. */ build_ref_for_offset. */
static tree static tree
build_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset, build_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset,
struct access *model, gimple_stmt_iterator *gsi, struct access *model, gimple_stmt_iterator *gsi,
bool insert_after) bool insert_after)
{ {
tree type = model->type, t; if (TREE_CODE (model->expr) == COMPONENT_REF
VEC(tree,stack) *cr_stack = NULL; && DECL_BIT_FIELD (TREE_OPERAND (model->expr, 1)))
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)
{ {
unsigned i; /* This access represents a bit-field. */
tree expr; tree t, exp_type, fld = TREE_OPERAND (model->expr, 1);
/* Now replicate the chain of COMPONENT_REFs from inner to outer. */ offset -= int_bit_position (fld);
FOR_EACH_VEC_ELT_REVERSE (tree, cr_stack, i, expr) exp_type = TREE_TYPE (TREE_OPERAND (model->expr, 0));
{ t = build_ref_for_offset (loc, base, offset, exp_type, gsi, insert_after);
tree field = TREE_OPERAND (expr, 1); return fold_build3_loc (loc, COMPONENT_REF, TREE_TYPE (fld), t, fld,
t = fold_build3_loc (loc, COMPONENT_REF, TREE_TYPE (field), t, field, NULL_TREE);
TREE_OPERAND (expr, 2));
}
VEC_free (tree, stack, cr_stack);
} }
else
return t; 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 /* Construct a memory reference consisting of component_refs and array_refs to
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment