(fixup_var_refs_insns): If SMALL_REGISTER_CLASSES...
(fixup_var_refs_insns): If SMALL_REGISTER_CLASSES, ensure we don't put any insns between the setting of the function return register and it's use. From-SVN: r3660
This commit is contained in:
parent
c2ae03cb30
commit
02a10449e3
@ -999,6 +999,8 @@ fixup_var_refs_insns (var, promoted_mode, unsignedp, insn, toplevel)
|
||||
rtx insn;
|
||||
int toplevel;
|
||||
{
|
||||
rtx call_dest = 0;
|
||||
|
||||
while (insn)
|
||||
{
|
||||
rtx next = NEXT_INSN (insn);
|
||||
@ -1022,6 +1024,46 @@ fixup_var_refs_insns (var, promoted_mode, unsignedp, insn, toplevel)
|
||||
}
|
||||
else
|
||||
{
|
||||
struct fixup_replacement *replacements = 0;
|
||||
rtx next_insn = NEXT_INSN (insn);
|
||||
|
||||
#ifdef SMALL_REGISTER_CLASSES
|
||||
/* If the insn that copies the results of a CALL_INSN
|
||||
into a pseudo now references VAR, we have to use an
|
||||
intermediate pseudo since we want the life of the
|
||||
return value register to be only a single insn.
|
||||
|
||||
If we don't use an intermediate pseudo, such things as
|
||||
address computations to make the address of VAR valid
|
||||
if it is not can be placed beween the CALL_INSN and INSN.
|
||||
|
||||
To make sure this doesn't happen, we record the destination
|
||||
of the CALL_INSN and see if the next insn uses both that
|
||||
and VAR. */
|
||||
|
||||
if (call_dest != 0 && GET_CODE (insn) == INSN
|
||||
&& reg_mentioned_p (var, PATTERN (insn))
|
||||
&& reg_mentioned_p (call_dest, PATTERN (insn)))
|
||||
{
|
||||
rtx temp = gen_reg_rtx (GET_MODE (call_dest));
|
||||
|
||||
emit_insn_before (gen_move_insn (temp, call_dest), insn);
|
||||
|
||||
PATTERN (insn) = replace_rtx (PATTERN (insn),
|
||||
call_dest, temp);
|
||||
}
|
||||
|
||||
if (GET_CODE (insn) == CALL_INSN
|
||||
&& GET_CODE (PATTERN (insn)) == SET)
|
||||
call_dest = SET_DEST (PATTERN (insn));
|
||||
else if (GET_CODE (insn) == CALL_INSN
|
||||
&& GET_CODE (PATTERN (insn)) == PARALLEL
|
||||
&& GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == SET)
|
||||
call_dest = SET_DEST (XVECEXP (PATTERN (insn), 0, 0));
|
||||
else
|
||||
call_dest = 0;
|
||||
#endif
|
||||
|
||||
/* See if we have to do anything to INSN now that VAR is in
|
||||
memory. If it needs to be loaded into a pseudo, use a single
|
||||
pseudo for the entire insn in case there is a MATCH_DUP
|
||||
@ -1033,9 +1075,6 @@ fixup_var_refs_insns (var, promoted_mode, unsignedp, insn, toplevel)
|
||||
If it allocated a pseudo for any replacement, we copy into
|
||||
it here. */
|
||||
|
||||
struct fixup_replacement *replacements = 0;
|
||||
rtx next_insn = NEXT_INSN (insn);
|
||||
|
||||
fixup_var_refs_1 (var, promoted_mode, &PATTERN (insn), insn,
|
||||
&replacements);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user