Commit ae00112b by Eric Botcazou

expr.c (expand_expr_real_1): Force op0 to non-constant memory if it cannot be…

expr.c (expand_expr_real_1): Force op0 to non-constant memory if it cannot be forced to constant memory.

	* expr.c (expand_expr_real_1) <normal_inner_ref>: Force op0 to
	non-constant memory if it cannot be forced to constant memory.
	Overhaul surrounding code and factor out common condition.

From-SVN: r140760
parent 6b5676ce
2008-09-11 Jeff Law <law@redhat.com>
2008-09-29 Eric Botcazou <ebotcazou@adacore.com>
* expr.c (expand_expr_real_1) <normal_inner_ref>: Force op0 to
non-constant memory if it cannot be forced to constant memory.
Overhaul surrounding code and factor out common condition.
2008-09-29 Jeff Law <law@redhat.com>
* reload1.c (alter_reg): Add missing curly braces.
......
......@@ -7744,13 +7744,13 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
case ARRAY_RANGE_REF:
normal_inner_ref:
{
enum machine_mode mode1;
enum machine_mode mode1, mode2;
HOST_WIDE_INT bitsize, bitpos;
tree offset;
int volatilep = 0;
int volatilep = 0, must_force_mem;
tree tem = get_inner_reference (exp, &bitsize, &bitpos, &offset,
&mode1, &unsignedp, &volatilep, true);
rtx orig_op0;
rtx orig_op0, memloc;
/* If we got back the original object, something is wrong. Perhaps
we are evaluating an expression too early. In any event, don't
......@@ -7760,7 +7760,6 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
/* If TEM's type is a union of variable size, pass TARGET to the inner
computation, since it will need a temporary and TARGET is known
to have to do. This occurs in unchecked conversion in Ada. */
orig_op0 = op0
= expand_expr (tem,
(TREE_CODE (TREE_TYPE (tem)) == UNION_TYPE
......@@ -7774,45 +7773,47 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
|| modifier == EXPAND_STACK_PARM)
? modifier : EXPAND_NORMAL);
/* If this is a constant, put it into a register if it is a legitimate
constant, OFFSET is 0, and we won't try to extract outside the
register (in case we were passed a partially uninitialized object
or a view_conversion to a larger size) or a BLKmode piece of it
(e.g. if it is unchecked-converted to a record type in Ada). Force
the constant to memory otherwise. */
if (CONSTANT_P (op0))
{
enum machine_mode mode = TYPE_MODE (TREE_TYPE (tem));
if (mode != BLKmode && LEGITIMATE_CONSTANT_P (op0)
&& offset == 0
&& mode1 != BLKmode
&& bitpos + bitsize <= GET_MODE_BITSIZE (mode))
op0 = force_reg (mode, op0);
else
op0 = validize_mem (force_const_mem (mode, op0));
}
/* Otherwise, if this object not in memory and we either have an
offset, a BLKmode result, or a reference outside the object, put it
there. Such cases can occur in Ada if we have unchecked conversion
of an expression from a scalar type to an array or record type or
for an ARRAY_RANGE_REF whose type is BLKmode. */
else if (!MEM_P (op0)
&& (offset != 0
|| mode1 == BLKmode
|| (bitpos + bitsize
> GET_MODE_BITSIZE (GET_MODE (op0)))))
mode2
= CONSTANT_P (op0) ? TYPE_MODE (TREE_TYPE (tem)) : GET_MODE (op0);
/* If we have either an offset, a BLKmode result, or a reference
outside the underlying object, we must force it to memory.
Such a case can occur in Ada if we have unchecked conversion
of an expression from a scalar type to an aggregate type or
for an ARRAY_RANGE_REF whose type is BLKmode, or if we were
passed a partially uninitialized object or a view-conversion
to a larger size. */
must_force_mem = (offset
|| mode1 == BLKmode
|| bitpos + bitsize > GET_MODE_BITSIZE (mode2));
/* If this is a constant, put it in a register if it is a legitimate
constant and we don't need a memory reference. */
if (CONSTANT_P (op0)
&& mode2 != BLKmode
&& LEGITIMATE_CONSTANT_P (op0)
&& !must_force_mem)
op0 = force_reg (mode2, op0);
/* Otherwise, if this is a constant, try to force it to the constant
pool. Note that back-ends, e.g. MIPS, may refuse to do so if it
is a legitimate constant. */
else if (CONSTANT_P (op0) && (memloc = force_const_mem (mode2, op0)))
op0 = validize_mem (memloc);
/* Otherwise, if this is a constant or the object is not in memory
and need be, put it there. */
else if (CONSTANT_P (op0) || (!MEM_P (op0) && must_force_mem))
{
tree nt = build_qualified_type (TREE_TYPE (tem),
(TYPE_QUALS (TREE_TYPE (tem))
| TYPE_QUAL_CONST));
rtx memloc = assign_temp (nt, 1, 1, 1);
memloc = assign_temp (nt, 1, 1, 1);
emit_move_insn (memloc, op0);
op0 = memloc;
}
if (offset != 0)
if (offset)
{
rtx offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode,
EXPAND_SUM);
......
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