Commit 51f0c3b7 by Jim Wilson

(emit_reload_insns): Call reload_reg_reaches_end_p for every reg of multi-reg spill register.

(emit_reload_insns): Call reload_reg_reaches_end_p for
every reg of multi-reg spill register.  Invalidate old info for multi
reg spill registers when only part survives to the end.

From-SVN: r11801
parent 9cca6a99
...@@ -6588,107 +6588,139 @@ emit_reload_insns (insn) ...@@ -6588,107 +6588,139 @@ emit_reload_insns (insn)
/* I is nonneg if this reload used one of the spill regs. /* I is nonneg if this reload used one of the spill regs.
If reload_reg_rtx[r] is 0, this is an optional reload If reload_reg_rtx[r] is 0, this is an optional reload
that we opted to ignore. that we opted to ignore. */
Also ignore reloads that don't reach the end of the insn,
since we will eventually see the one that does. */
if (i >= 0 && reload_reg_rtx[r] != 0 if (i >= 0 && reload_reg_rtx[r] != 0)
&& reload_reg_reaches_end_p (spill_regs[i], reload_opnum[r],
reload_when_needed[r]))
{ {
/* First, clear out memory of what used to be in this spill reg.
If consecutive registers are used, clear them all. */
int nr int nr
= HARD_REGNO_NREGS (spill_regs[i], GET_MODE (reload_reg_rtx[r])); = HARD_REGNO_NREGS (spill_regs[i], GET_MODE (reload_reg_rtx[r]));
int k; int k;
int part_reaches_end = 0;
int all_reaches_end = 1;
/* For a multi register reload, we need to check if all or part
of the value lives to the end. */
for (k = 0; k < nr; k++) for (k = 0; k < nr; k++)
{ {
reg_reloaded_contents[spill_reg_order[spill_regs[i] + k]] = -1; if (reload_reg_reaches_end_p (spill_regs[i] + k, reload_opnum[r],
reg_reloaded_insn[spill_reg_order[spill_regs[i] + k]] = 0; reload_when_needed[r]))
part_reaches_end = 1;
else
all_reaches_end = 0;
} }
/* Maybe the spill reg contains a copy of reload_out. */ /* Ignore reloads that don't reach the end of the insn in
if (reload_out[r] != 0 && GET_CODE (reload_out[r]) == REG) entirety. */
if (all_reaches_end)
{ {
register int nregno = REGNO (reload_out[r]); /* First, clear out memory of what used to be in this spill reg.
int nnr = (nregno >= FIRST_PSEUDO_REGISTER ? 1 If consecutive registers are used, clear them all. */
: HARD_REGNO_NREGS (nregno,
GET_MODE (reload_reg_rtx[r])));
spill_reg_store[i] = new_spill_reg_store[i];
reg_last_reload_reg[nregno] = reload_reg_rtx[r];
/* If NREGNO is a hard register, it may occupy more than
one register. If it does, say what is in the
rest of the registers assuming that both registers
agree on how many words the object takes. If not,
invalidate the subsequent registers. */
if (nregno < FIRST_PSEUDO_REGISTER)
for (k = 1; k < nnr; k++)
reg_last_reload_reg[nregno + k]
= (nr == nnr ? gen_rtx (REG,
reg_raw_mode[REGNO (reload_reg_rtx[r]) + k],
REGNO (reload_reg_rtx[r]) + k)
: 0);
/* Now do the inverse operation. */
for (k = 0; k < nr; k++) for (k = 0; k < nr; k++)
{ {
reg_reloaded_contents[spill_reg_order[spill_regs[i] + k]] reg_reloaded_contents[spill_reg_order[spill_regs[i] + k]] = -1;
= (nregno >= FIRST_PSEUDO_REGISTER || nr != nnr ? nregno reg_reloaded_insn[spill_reg_order[spill_regs[i] + k]] = 0;
: nregno + k);
reg_reloaded_insn[spill_reg_order[spill_regs[i] + k]] = insn;
} }
}
/* Maybe the spill reg contains a copy of reload_in. Only do
something if there will not be an output reload for
the register being reloaded. */
else if (reload_out[r] == 0
&& reload_in[r] != 0
&& ((GET_CODE (reload_in[r]) == REG
&& ! reg_has_output_reload[REGNO (reload_in[r])])
|| (GET_CODE (reload_in_reg[r]) == REG
&& ! reg_has_output_reload[REGNO (reload_in_reg[r])])))
{
register int nregno;
int nnr;
if (GET_CODE (reload_in[r]) == REG) /* Maybe the spill reg contains a copy of reload_out. */
nregno = REGNO (reload_in[r]); if (reload_out[r] != 0 && GET_CODE (reload_out[r]) == REG)
else {
nregno = REGNO (reload_in_reg[r]); register int nregno = REGNO (reload_out[r]);
int nnr = (nregno >= FIRST_PSEUDO_REGISTER ? 1
nnr = (nregno >= FIRST_PSEUDO_REGISTER ? 1 : HARD_REGNO_NREGS (nregno,
: HARD_REGNO_NREGS (nregno, GET_MODE (reload_reg_rtx[r])));
GET_MODE (reload_reg_rtx[r])));
spill_reg_store[i] = new_spill_reg_store[i];
reg_last_reload_reg[nregno] = reload_reg_rtx[r];
/* If NREGNO is a hard register, it may occupy more than
one register. If it does, say what is in the
rest of the registers assuming that both registers
agree on how many words the object takes. If not,
invalidate the subsequent registers. */
if (nregno < FIRST_PSEUDO_REGISTER)
for (k = 1; k < nnr; k++)
reg_last_reload_reg[nregno + k]
= (nr == nnr
? gen_rtx (REG,
reg_raw_mode[REGNO (reload_reg_rtx[r]) + k],
REGNO (reload_reg_rtx[r]) + k)
: 0);
/* Now do the inverse operation. */
for (k = 0; k < nr; k++)
{
reg_reloaded_contents[spill_reg_order[spill_regs[i] + k]]
= (nregno >= FIRST_PSEUDO_REGISTER || nr != nnr
? nregno
: nregno + k);
reg_reloaded_insn[spill_reg_order[spill_regs[i] + k]] = insn;
}
}
reg_last_reload_reg[nregno] = reload_reg_rtx[r]; /* Maybe the spill reg contains a copy of reload_in. Only do
something if there will not be an output reload for
the register being reloaded. */
else if (reload_out[r] == 0
&& reload_in[r] != 0
&& ((GET_CODE (reload_in[r]) == REG
&& ! reg_has_output_reload[REGNO (reload_in[r])])
|| (GET_CODE (reload_in_reg[r]) == REG
&& ! reg_has_output_reload[REGNO (reload_in_reg[r])])))
{
register int nregno;
int nnr;
if (nregno < FIRST_PSEUDO_REGISTER) if (GET_CODE (reload_in[r]) == REG)
for (k = 1; k < nnr; k++) nregno = REGNO (reload_in[r]);
reg_last_reload_reg[nregno + k] else
= (nr == nnr ? gen_rtx (REG, nregno = REGNO (reload_in_reg[r]);
reg_raw_mode[REGNO (reload_reg_rtx[r]) + k],
REGNO (reload_reg_rtx[r]) + k)
: 0);
/* Unless we inherited this reload, show we haven't nnr = (nregno >= FIRST_PSEUDO_REGISTER ? 1
recently done a store. */ : HARD_REGNO_NREGS (nregno,
if (! reload_inherited[r]) GET_MODE (reload_reg_rtx[r])));
spill_reg_store[i] = 0;
reg_last_reload_reg[nregno] = reload_reg_rtx[r];
if (nregno < FIRST_PSEUDO_REGISTER)
for (k = 1; k < nnr; k++)
reg_last_reload_reg[nregno + k]
= (nr == nnr
? gen_rtx (REG,
reg_raw_mode[REGNO (reload_reg_rtx[r]) + k],
REGNO (reload_reg_rtx[r]) + k)
: 0);
/* Unless we inherited this reload, show we haven't
recently done a store. */
if (! reload_inherited[r])
spill_reg_store[i] = 0;
for (k = 0; k < nr; k++)
{
reg_reloaded_contents[spill_reg_order[spill_regs[i] + k]]
= (nregno >= FIRST_PSEUDO_REGISTER || nr != nnr
? nregno
: nregno + k);
reg_reloaded_insn[spill_reg_order[spill_regs[i] + k]]
= insn;
}
}
}
/* However, if part of the reload reaches the end, then we must
invalidate the old info for the part that survives to the end. */
else if (part_reaches_end)
{
for (k = 0; k < nr; k++) for (k = 0; k < nr; k++)
{ if (reload_reg_reaches_end_p (spill_regs[i] + k,
reg_reloaded_contents[spill_reg_order[spill_regs[i] + k]] reload_opnum[r],
= (nregno >= FIRST_PSEUDO_REGISTER || nr != nnr ? nregno reload_when_needed[r]))
: nregno + k); {
reg_reloaded_insn[spill_reg_order[spill_regs[i] + k]] reg_reloaded_contents[spill_reg_order[spill_regs[i] + k]] = -1;
= insn; reg_reloaded_insn[spill_reg_order[spill_regs[i] + k]] = 0;
} }
} }
} }
......
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