From: Eric Botcazou Date: Mon, 29 Sep 2008 18:15:28 +0000 (+0000) Subject: expr.c (expand_expr_real_1): Force op0 to non-constant memory if it cannot be forced... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ae00112bf06e9156d783fc4ff0ca6db7901f061a;p=gcc.git 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) : 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7eff8160678..a8d787bd86b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,4 +1,10 @@ -2008-09-11 Jeff Law +2008-09-29 Eric Botcazou + + * expr.c (expand_expr_real_1) : 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 * reload1.c (alter_reg): Add missing curly braces. diff --git a/gcc/expr.c b/gcc/expr.c index ae0daf0b251..32c8d01fe7f 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -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);