Commit e3c8ea67 by Richard Henderson Committed by Richard Henderson

emit-rtl.c (offset_address): Use simplify_gen_binary rather than gen_rtx_PLUS to form the sum.

        * emit-rtl.c (offset_address): Use simplify_gen_binary rather
        than gen_rtx_PLUS to form the sum.
        * explow.c (force_reg): Rearrange to not allocate new pseudo
        when force_operand returns a register.
        * expr.c (expand_assignment): Allow offset_rtx expansion to
        return a sum.  Do not force addresses into registers.
        (expand_expr): Likewise.
        * simplify-rtx.c (simplify_gen_binary): Use simplify_plus_minus
        to canonicalize arithmetic that didn't simpify.
        (simplify_plus_minus): New argument force; update
        all callers.  Don't split CONST unless we can do something with it,
        and wouldn't lose the constness of the operands.

        * config/i386/i386.c (legitimize_pic_address): Recognize UNSPECs
        that we generated earlier.

From-SVN: r49945
parent c1a046e5
2002-02-21 Richard Henderson <rth@redhat.com>
* emit-rtl.c (offset_address): Use simplify_gen_binary rather
than gen_rtx_PLUS to form the sum.
* explow.c (force_reg): Rearrange to not allocate new pseudo
when force_operand returns a register.
* expr.c (expand_assignment): Allow offset_rtx expansion to
return a sum. Do not force addresses into registers.
(expand_expr): Likewise.
* simplify-rtx.c (simplify_gen_binary): Use simplify_plus_minus
to canonicalize arithmetic that didn't simpify.
(simplify_plus_minus): New argument force; update
all callers. Don't split CONST unless we can do something with it,
and wouldn't lose the constness of the operands.
* config/i386/i386.c (legitimize_pic_address): Recognize UNSPECs
that we generated earlier.
2002-02-21 Tom Tromey <tromey@redhat.com> 2002-02-21 Tom Tromey <tromey@redhat.com>
* dwarf2out.c (DWARF_LINE_MIN_INSTR_LENGTH): Removed. * dwarf2out.c (DWARF_LINE_MIN_INSTR_LENGTH): Removed.
......
...@@ -4986,11 +4986,15 @@ legitimize_pic_address (orig, reg) ...@@ -4986,11 +4986,15 @@ legitimize_pic_address (orig, reg)
if (GET_CODE (addr) == CONST) if (GET_CODE (addr) == CONST)
{ {
addr = XEXP (addr, 0); addr = XEXP (addr, 0);
if (GET_CODE (addr) == UNSPEC)
{ /* We must match stuff we generate before. Assume the only
/* Check that the unspec is one of the ones we generate? */ unspecs that can get here are ours. Not that we could do
} anything with them anyway... */
else if (GET_CODE (addr) != PLUS) if (GET_CODE (addr) == UNSPEC
|| (GET_CODE (addr) == PLUS
&& GET_CODE (XEXP (addr, 0)) == UNSPEC))
return orig;
if (GET_CODE (addr) != PLUS)
abort (); abort ();
} }
if (GET_CODE (addr) == PLUS) if (GET_CODE (addr) == PLUS)
......
...@@ -2047,9 +2047,26 @@ offset_address (memref, offset, pow2) ...@@ -2047,9 +2047,26 @@ offset_address (memref, offset, pow2)
rtx offset; rtx offset;
HOST_WIDE_INT pow2; HOST_WIDE_INT pow2;
{ {
rtx new = change_address_1 (memref, VOIDmode, rtx new, addr = XEXP (memref, 0);
gen_rtx_PLUS (Pmode, XEXP (memref, 0),
force_reg (Pmode, offset)), 1); new = simplify_gen_binary (PLUS, Pmode, addr, offset);
/* At this point we don't know _why_ the address is invalid. It
could have secondary memory refereces, multiplies or anything.
However, if we did go and rearrange things, we can wind up not
being able to recognize the magic around pic_offset_table_rtx.
This stuff is fragile, and is yet another example of why it is
bad to expose PIC machinery too early. */
if (! memory_address_p (GET_MODE (memref), new)
&& GET_CODE (addr) == PLUS
&& XEXP (addr, 0) == pic_offset_table_rtx)
{
addr = force_reg (GET_MODE (addr), addr);
new = simplify_gen_binary (PLUS, Pmode, addr, offset);
}
new = change_address_1 (memref, VOIDmode, new, 1);
/* Update the alignment to reflect the offset. Reset the offset, which /* Update the alignment to reflect the offset. Reset the offset, which
we don't know. */ we don't know. */
......
...@@ -732,12 +732,23 @@ force_reg (mode, x) ...@@ -732,12 +732,23 @@ force_reg (mode, x)
if (GET_CODE (x) == REG) if (GET_CODE (x) == REG)
return x; return x;
temp = gen_reg_rtx (mode); if (general_operand (x, mode))
{
if (! general_operand (x, mode)) temp = gen_reg_rtx (mode);
x = force_operand (x, NULL_RTX); insn = emit_move_insn (temp, x);
}
insn = emit_move_insn (temp, x); else
{
temp = force_operand (x, NULL_RTX);
if (GET_CODE (temp) == REG)
insn = get_last_insn ();
else
{
rtx temp2 = gen_reg_rtx (mode);
insn = emit_move_insn (temp2, temp);
temp = temp2;
}
}
/* Let optimizers know that TEMP's value never changes /* Let optimizers know that TEMP's value never changes
and that X can be substituted for it. Don't get confused and that X can be substituted for it. Don't get confused
...@@ -746,6 +757,7 @@ force_reg (mode, x) ...@@ -746,6 +757,7 @@ force_reg (mode, x)
&& (set = single_set (insn)) != 0 && (set = single_set (insn)) != 0
&& SET_DEST (set) == temp) && SET_DEST (set) == temp)
set_unique_reg_note (insn, REG_EQUAL, x); set_unique_reg_note (insn, REG_EQUAL, x);
return temp; return temp;
} }
......
...@@ -3659,7 +3659,7 @@ expand_assignment (to, from, want_value, suggest_reg) ...@@ -3659,7 +3659,7 @@ expand_assignment (to, from, want_value, suggest_reg)
if (offset != 0) if (offset != 0)
{ {
rtx offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode, 0); rtx offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode, EXPAND_SUM);
if (GET_CODE (to_rtx) != MEM) if (GET_CODE (to_rtx) != MEM)
abort (); abort ();
...@@ -3682,15 +3682,7 @@ expand_assignment (to, from, want_value, suggest_reg) ...@@ -3682,15 +3682,7 @@ expand_assignment (to, from, want_value, suggest_reg)
&& (bitsize % GET_MODE_ALIGNMENT (mode1)) == 0 && (bitsize % GET_MODE_ALIGNMENT (mode1)) == 0
&& MEM_ALIGN (to_rtx) == GET_MODE_ALIGNMENT (mode1)) && MEM_ALIGN (to_rtx) == GET_MODE_ALIGNMENT (mode1))
{ {
rtx temp to_rtx = adjust_address (to_rtx, mode1, bitpos / BITS_PER_UNIT);
= adjust_address (to_rtx, mode1, bitpos / BITS_PER_UNIT);
if (GET_CODE (XEXP (temp, 0)) == REG)
to_rtx = temp;
else
to_rtx = (replace_equiv_address
(to_rtx, force_reg (GET_MODE (XEXP (temp, 0)),
XEXP (temp, 0))));
bitpos = 0; bitpos = 0;
} }
...@@ -6852,7 +6844,7 @@ expand_expr (exp, target, tmode, modifier) ...@@ -6852,7 +6844,7 @@ expand_expr (exp, target, tmode, modifier)
if (offset != 0) if (offset != 0)
{ {
rtx offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode, 0); rtx offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode, EXPAND_SUM);
/* If this object is in a register, put it into memory. /* If this object is in a register, put it into memory.
This case can't occur in C, but can in Ada if we have This case can't occur in C, but can in Ada if we have
...@@ -6902,15 +6894,7 @@ expand_expr (exp, target, tmode, modifier) ...@@ -6902,15 +6894,7 @@ expand_expr (exp, target, tmode, modifier)
&& (bitsize % GET_MODE_ALIGNMENT (mode1)) == 0 && (bitsize % GET_MODE_ALIGNMENT (mode1)) == 0
&& MEM_ALIGN (op0) == GET_MODE_ALIGNMENT (mode1)) && MEM_ALIGN (op0) == GET_MODE_ALIGNMENT (mode1))
{ {
rtx temp = adjust_address (op0, mode1, bitpos / BITS_PER_UNIT); op0 = adjust_address (op0, mode1, bitpos / BITS_PER_UNIT);
if (GET_CODE (XEXP (temp, 0)) == REG)
op0 = temp;
else
op0 = (replace_equiv_address
(op0,
force_reg (GET_MODE (XEXP (temp, 0)),
XEXP (temp, 0))));
bitpos = 0; bitpos = 0;
} }
......
...@@ -99,7 +99,8 @@ static rtx neg_const_int PARAMS ((enum machine_mode, rtx)); ...@@ -99,7 +99,8 @@ static rtx neg_const_int PARAMS ((enum machine_mode, rtx));
static int simplify_plus_minus_op_data_cmp PARAMS ((const void *, static int simplify_plus_minus_op_data_cmp PARAMS ((const void *,
const void *)); const void *));
static rtx simplify_plus_minus PARAMS ((enum rtx_code, static rtx simplify_plus_minus PARAMS ((enum rtx_code,
enum machine_mode, rtx, rtx)); enum machine_mode, rtx,
rtx, int));
static void check_fold_consts PARAMS ((PTR)); static void check_fold_consts PARAMS ((PTR));
#if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC) #if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
static void simplify_unary_real PARAMS ((PTR)); static void simplify_unary_real PARAMS ((PTR));
...@@ -137,21 +138,14 @@ simplify_gen_binary (code, mode, op0, op1) ...@@ -137,21 +138,14 @@ simplify_gen_binary (code, mode, op0, op1)
/* If this simplifies, do it. */ /* If this simplifies, do it. */
tem = simplify_binary_operation (code, mode, op0, op1); tem = simplify_binary_operation (code, mode, op0, op1);
if (tem) if (tem)
return tem; return tem;
/* Handle addition and subtraction of CONST_INT specially. Otherwise, /* Handle addition and subtraction specially. Otherwise, just form
just form the operation. */ the operation. */
if (GET_CODE (op1) == CONST_INT if (code == PLUS || code == MINUS)
&& GET_MODE (op0) != VOIDmode return simplify_plus_minus (code, mode, op0, op1, 1);
&& (code == PLUS || code == MINUS))
{
if (code == MINUS)
op1 = neg_const_int (mode, op1);
return plus_constant (op0, INTVAL (op1));
}
else else
return gen_rtx_fmt_ee (code, mode, op0, op1); return gen_rtx_fmt_ee (code, mode, op0, op1);
} }
...@@ -1152,7 +1146,7 @@ simplify_binary_operation (code, mode, op0, op1) ...@@ -1152,7 +1146,7 @@ simplify_binary_operation (code, mode, op0, op1)
&& GET_CODE (XEXP (op0, 0)) == PLUS) && GET_CODE (XEXP (op0, 0)) == PLUS)
|| (GET_CODE (op1) == CONST || (GET_CODE (op1) == CONST
&& GET_CODE (XEXP (op1, 0)) == PLUS)) && GET_CODE (XEXP (op1, 0)) == PLUS))
&& (tem = simplify_plus_minus (code, mode, op0, op1)) != 0) && (tem = simplify_plus_minus (code, mode, op0, op1, 0)) != 0)
return tem; return tem;
break; break;
...@@ -1289,7 +1283,7 @@ simplify_binary_operation (code, mode, op0, op1) ...@@ -1289,7 +1283,7 @@ simplify_binary_operation (code, mode, op0, op1)
&& GET_CODE (XEXP (op0, 0)) == PLUS) && GET_CODE (XEXP (op0, 0)) == PLUS)
|| (GET_CODE (op1) == CONST || (GET_CODE (op1) == CONST
&& GET_CODE (XEXP (op1, 0)) == PLUS)) && GET_CODE (XEXP (op1, 0)) == PLUS))
&& (tem = simplify_plus_minus (code, mode, op0, op1)) != 0) && (tem = simplify_plus_minus (code, mode, op0, op1, 0)) != 0)
return tem; return tem;
/* Don't let a relocatable value get a negative coeff. */ /* Don't let a relocatable value get a negative coeff. */
...@@ -1728,7 +1722,10 @@ simplify_binary_operation (code, mode, op0, op1) ...@@ -1728,7 +1722,10 @@ simplify_binary_operation (code, mode, op0, op1)
Rather than test for specific case, we do this by a brute-force method Rather than test for specific case, we do this by a brute-force method
and do all possible simplifications until no more changes occur. Then and do all possible simplifications until no more changes occur. Then
we rebuild the operation. */ we rebuild the operation.
If FORCE is true, then always generate the rtx. This is used to
canonicalize stuff emitted from simplify_gen_binary. */
struct simplify_plus_minus_op_data struct simplify_plus_minus_op_data
{ {
...@@ -1749,10 +1746,11 @@ simplify_plus_minus_op_data_cmp (p1, p2) ...@@ -1749,10 +1746,11 @@ simplify_plus_minus_op_data_cmp (p1, p2)
} }
static rtx static rtx
simplify_plus_minus (code, mode, op0, op1) simplify_plus_minus (code, mode, op0, op1, force)
enum rtx_code code; enum rtx_code code;
enum machine_mode mode; enum machine_mode mode;
rtx op0, op1; rtx op0, op1;
int force;
{ {
struct simplify_plus_minus_op_data ops[8]; struct simplify_plus_minus_op_data ops[8];
rtx result, tem; rtx result, tem;
...@@ -1786,7 +1784,11 @@ simplify_plus_minus (code, mode, op0, op1) ...@@ -1786,7 +1784,11 @@ simplify_plus_minus (code, mode, op0, op1)
case PLUS: case PLUS:
case MINUS: case MINUS:
if (n_ops == 7) if (n_ops == 7)
return 0; {
if (force)
abort ();
return NULL_RTX;
}
ops[n_ops].op = XEXP (this_op, 1); ops[n_ops].op = XEXP (this_op, 1);
ops[n_ops].neg = (this_code == MINUS) ^ this_neg; ops[n_ops].neg = (this_code == MINUS) ^ this_neg;
...@@ -1804,9 +1806,18 @@ simplify_plus_minus (code, mode, op0, op1) ...@@ -1804,9 +1806,18 @@ simplify_plus_minus (code, mode, op0, op1)
break; break;
case CONST: case CONST:
ops[i].op = XEXP (this_op, 0); if (n_ops < 7
input_consts++; && GET_CODE (XEXP (this_op, 0)) == PLUS
changed = 1; && CONSTANT_P (XEXP (XEXP (this_op, 0), 0))
&& CONSTANT_P (XEXP (XEXP (this_op, 0), 1)))
{
ops[i].op = XEXP (XEXP (this_op, 0), 0);
ops[n_ops].op = XEXP (XEXP (this_op, 0), 1);
ops[n_ops].neg = this_neg;
n_ops++;
input_consts++;
changed = 1;
}
break; break;
case NOT: case NOT:
...@@ -1838,9 +1849,14 @@ simplify_plus_minus (code, mode, op0, op1) ...@@ -1838,9 +1849,14 @@ simplify_plus_minus (code, mode, op0, op1)
while (changed); while (changed);
/* If we only have two operands, we can't do anything. */ /* If we only have two operands, we can't do anything. */
if (n_ops <= 2) if (n_ops <= 2 && !force)
return NULL_RTX; return NULL_RTX;
/* Count the number of CONSTs we didn't split above. */
for (i = 0; i < n_ops; i++)
if (GET_CODE (ops[i].op) == CONST)
input_consts++;
/* Now simplify each pair of operands until nothing changes. The first /* Now simplify each pair of operands until nothing changes. The first
time through just simplify constants against each other. */ time through just simplify constants against each other. */
...@@ -1941,8 +1957,9 @@ simplify_plus_minus (code, mode, op0, op1) ...@@ -1941,8 +1957,9 @@ simplify_plus_minus (code, mode, op0, op1)
sure we count a CONST as two operands. If we have the same sure we count a CONST as two operands. If we have the same
number of operands, but have made more CONSTs than before, this number of operands, but have made more CONSTs than before, this
is also an improvement, so accept it. */ is also an improvement, so accept it. */
if (n_ops + n_consts > input_ops if (!force
|| (n_ops + n_consts == input_ops && n_consts <= input_consts)) && (n_ops + n_consts > input_ops
|| (n_ops + n_consts == input_ops && n_consts <= input_consts)))
return NULL_RTX; return NULL_RTX;
/* Put a non-negated operand first. If there aren't any, make all /* Put a non-negated operand first. If there aren't any, make all
......
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