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,41 +2903,57 @@ eliminate_regs_in_insn (insn, replace) ...@@ -2903,41 +2903,57 @@ 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
&& GET_CODE (SET_SRC (old_set)) == PLUS
&& GET_CODE (XEXP (SET_SRC (old_set), 0)) == REG
&& GET_CODE (XEXP (SET_SRC (old_set), 1)) == CONST_INT
&& REGNO (XEXP (SET_SRC (old_set), 0)) < FIRST_PSEUDO_REGISTER)
{
rtx reg = XEXP (SET_SRC (old_set), 0);
int offset = INTVAL (XEXP (SET_SRC (old_set), 1));
We have to do this here, rather than in eliminate_regs, so that we can for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
change the insn code. */ if (ep->from_rtx == reg && ep->can_eliminate)
{
offset += ep->offset;
if (GET_CODE (SET_SRC (old_set)) == PLUS if (offset == 0)
&& GET_CODE (XEXP (SET_SRC (old_set), 0)) == REG {
&& GET_CODE (XEXP (SET_SRC (old_set), 1)) == CONST_INT) /* We assume here that we don't need a PARALLEL of
for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; any CLOBBERs for this assignment. There's not
ep++) much we can do if we do need it. */
if (ep->from_rtx == XEXP (SET_SRC (old_set), 0) PATTERN (insn) = gen_rtx_SET (VOIDmode,
&& ep->can_eliminate) SET_DEST (old_set),
{ ep->to_rtx);
/* We must stop at the first elimination that will be used. INSN_CODE (insn) = recog (PATTERN (insn), insn, 0);
If this one would replace the PLUS with a REG, do it if (INSN_CODE (insn) < 0)
now. Otherwise, quit the loop and let eliminate_regs abort ();
do its normal replacement. */ }
if (ep->offset == - INTVAL (XEXP (SET_SRC (old_set), 1))) else
{ {
/* We assume here that we don't need a PARALLEL of new_body = old_body;
any CLOBBERs for this assignment. There's not if (! replace)
much we can do if we do need it. */ {
PATTERN (insn) = gen_rtx_SET (VOIDmode, new_body = copy_insn (old_body);
SET_DEST (old_set), if (REG_NOTES (insn))
ep->to_rtx); REG_NOTES (insn) = copy_insn_1 (REG_NOTES (insn));
INSN_CODE (insn) = -1; }
val = 1; PATTERN (insn) = new_body;
goto done; 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;
}
} }
/* Determine the effects of this insn on elimination offsets. */ /* Determine the effects of this insn on elimination offsets. */
...@@ -2990,7 +3006,7 @@ eliminate_regs_in_insn (insn, replace) ...@@ -2990,7 +3006,7 @@ eliminate_regs_in_insn (insn, replace)
for (i = 0; i < recog_data.n_dups; i++) for (i = 0; i < recog_data.n_dups; i++)
*recog_data.dup_loc[i] *recog_data.dup_loc[i]
= *recog_data.operand_loc[(int)recog_data.dup_num[i]]; = *recog_data.operand_loc[(int)recog_data.dup_num[i]];
/* If any eliminable remain, they aren't eliminable anymore. */ /* If any eliminable remain, they aren't eliminable anymore. */
check_eliminable_occurrences (old_body); check_eliminable_occurrences (old_body);
......
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