Commit aa5524a9 by Bernd Schmidt Committed by Bernd Schmidt

Fix suboptimal code generation by register elimination

From-SVN: r32446
parent fb863f62
2000-03-09 Bernd Schmidt <bernds@cygnus.co.uk>
* reload1.c (eliminate_regs_in_insn): Handle additions of eliminable
register and a constant specially.
2000-03-08 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> 2000-03-08 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* libgcc2.h: New file. * libgcc2.h: New file.
......
...@@ -2903,27 +2903,26 @@ eliminate_regs_in_insn (insn, replace) ...@@ -2903,27 +2903,26 @@ eliminate_regs_in_insn (insn, replace)
val = 1; val = 1;
goto done; goto done;
} }
}
/* Check for (set (reg) (plus (reg from) (offset))) where the offset /* We allow one special case which happens to work on all machines we
in the insn is the negative of the offset in FROM. Substitute currently support: a single set with the source being a PLUS of an
(set (reg) (reg to)) for the insn and change its code. eliminable register and a constant. */
if (old_set
We have to do this here, rather than in eliminate_regs, so that we can && GET_CODE (SET_SRC (old_set)) == PLUS
change the insn code. */
if (GET_CODE (SET_SRC (old_set)) == PLUS
&& GET_CODE (XEXP (SET_SRC (old_set), 0)) == REG && GET_CODE (XEXP (SET_SRC (old_set), 0)) == REG
&& GET_CODE (XEXP (SET_SRC (old_set), 1)) == CONST_INT) && GET_CODE (XEXP (SET_SRC (old_set), 1)) == CONST_INT
for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; && REGNO (XEXP (SET_SRC (old_set), 0)) < FIRST_PSEUDO_REGISTER)
ep++) {
if (ep->from_rtx == XEXP (SET_SRC (old_set), 0) rtx reg = XEXP (SET_SRC (old_set), 0);
&& ep->can_eliminate) int offset = INTVAL (XEXP (SET_SRC (old_set), 1));
for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
if (ep->from_rtx == reg && ep->can_eliminate)
{ {
/* We must stop at the first elimination that will be used. offset += ep->offset;
If this one would replace the PLUS with a REG, do it
now. Otherwise, quit the loop and let eliminate_regs if (offset == 0)
do its normal replacement. */
if (ep->offset == - INTVAL (XEXP (SET_SRC (old_set), 1)))
{ {
/* We assume here that we don't need a PARALLEL of /* We assume here that we don't need a PARALLEL of
any CLOBBERs for this assignment. There's not any CLOBBERs for this assignment. There's not
...@@ -2931,12 +2930,29 @@ eliminate_regs_in_insn (insn, replace) ...@@ -2931,12 +2930,29 @@ eliminate_regs_in_insn (insn, replace)
PATTERN (insn) = gen_rtx_SET (VOIDmode, PATTERN (insn) = gen_rtx_SET (VOIDmode,
SET_DEST (old_set), SET_DEST (old_set),
ep->to_rtx); ep->to_rtx);
INSN_CODE (insn) = -1; INSN_CODE (insn) = recog (PATTERN (insn), insn, 0);
val = 1; if (INSN_CODE (insn) < 0)
goto done; abort ();
} }
else
{
new_body = old_body;
if (! replace)
{
new_body = copy_insn (old_body);
if (REG_NOTES (insn))
REG_NOTES (insn) = copy_insn_1 (REG_NOTES (insn));
}
PATTERN (insn) = new_body;
old_set = single_set (insn);
break; XEXP (SET_SRC (old_set), 0) = ep->to_rtx;
XEXP (SET_SRC (old_set), 1) = GEN_INT (offset);
}
val = 1;
/* This can't have an effect on elimination offsets, so skip right
to the end. */
goto done;
} }
} }
......
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