Commit b5ba341f by Richard Sandiford Committed by Richard Sandiford

reload1.c (inherit_piecemeal_p): New function.

	* reload1.c (inherit_piecemeal_p): New function.
	(emit_reload_insns): When reloading a group of hard registers, use
	inherit_piecemeal_p to decide whether the values of individual hard
	registers can be inherited.

From-SVN: r81480
parent 065afdfa
2004-05-04 Richard Sandiford <rsandifo@redhat.com>
* reload1.c (inherit_piecemeal_p): New function.
(emit_reload_insns): When reloading a group of hard registers, use
inherit_piecemeal_p to decide whether the values of individual hard
registers can be inherited.
2004-05-04 H.J. Lu <hongjiu.lu@intel.com> 2004-05-04 H.J. Lu <hongjiu.lu@intel.com>
* config/ia64/t-ia64 (LIB2ADDEH): Remove gthr-gnat.c. * config/ia64/t-ia64 (LIB2ADDEH): Remove gthr-gnat.c.
......
...@@ -417,6 +417,7 @@ static void emit_output_reload_insns (struct insn_chain *, struct reload *, ...@@ -417,6 +417,7 @@ static void emit_output_reload_insns (struct insn_chain *, struct reload *,
int); int);
static void do_input_reload (struct insn_chain *, struct reload *, int); static void do_input_reload (struct insn_chain *, struct reload *, int);
static void do_output_reload (struct insn_chain *, struct reload *, int); static void do_output_reload (struct insn_chain *, struct reload *, int);
static bool inherit_piecemeal_p (int, int);
static void emit_reload_insns (struct insn_chain *); static void emit_reload_insns (struct insn_chain *);
static void delete_output_reload (rtx, int, int); static void delete_output_reload (rtx, int, int);
static void delete_address_reloads (rtx, rtx); static void delete_address_reloads (rtx, rtx);
...@@ -6956,6 +6957,27 @@ do_output_reload (struct insn_chain *chain, struct reload *rl, int j) ...@@ -6956,6 +6957,27 @@ do_output_reload (struct insn_chain *chain, struct reload *rl, int j)
emit_output_reload_insns (chain, rld + j, j); emit_output_reload_insns (chain, rld + j, j);
} }
/* Reload number R reloads from or to a group of hard registers starting at
register REGNO. Return true if it can be treated for inheritance purposes
like a group of reloads, each one reloading a single hard register.
The caller has already checked that the spill register and REGNO use
the same number of registers to store the reload value. */
static bool
inherit_piecemeal_p (int r, int regno)
{
#ifdef CANNOT_CHANGE_MODE_CLASS
return (!REG_CANNOT_CHANGE_MODE_P (reload_spill_index[r],
GET_MODE (rld[r].reg_rtx),
reg_raw_mode[reload_spill_index[r]])
&& !REG_CANNOT_CHANGE_MODE_P (regno,
GET_MODE (rld[r].reg_rtx),
reg_raw_mode[regno]));
#else
return true;
#endif
}
/* Output insns to reload values in and out of the chosen reload regs. */ /* Output insns to reload values in and out of the chosen reload regs. */
static void static void
...@@ -7137,11 +7159,16 @@ emit_reload_insns (struct insn_chain *chain) ...@@ -7137,11 +7159,16 @@ emit_reload_insns (struct insn_chain *chain)
int nnr = (nregno >= FIRST_PSEUDO_REGISTER ? 1 int nnr = (nregno >= FIRST_PSEUDO_REGISTER ? 1
: hard_regno_nregs[nregno] : hard_regno_nregs[nregno]
[GET_MODE (rld[r].reg_rtx)]); [GET_MODE (rld[r].reg_rtx)]);
bool piecemeal;
spill_reg_store[i] = new_spill_reg_store[i]; spill_reg_store[i] = new_spill_reg_store[i];
spill_reg_stored_to[i] = out; spill_reg_stored_to[i] = out;
reg_last_reload_reg[nregno] = rld[r].reg_rtx; reg_last_reload_reg[nregno] = rld[r].reg_rtx;
piecemeal = (nregno < FIRST_PSEUDO_REGISTER
&& nr == nnr
&& inherit_piecemeal_p (r, nregno));
/* If NREGNO is a hard register, it may occupy more than /* If NREGNO is a hard register, it may occupy more than
one register. If it does, say what is in the one register. If it does, say what is in the
rest of the registers assuming that both registers rest of the registers assuming that both registers
...@@ -7151,7 +7178,7 @@ emit_reload_insns (struct insn_chain *chain) ...@@ -7151,7 +7178,7 @@ emit_reload_insns (struct insn_chain *chain)
if (nregno < FIRST_PSEUDO_REGISTER) if (nregno < FIRST_PSEUDO_REGISTER)
for (k = 1; k < nnr; k++) for (k = 1; k < nnr; k++)
reg_last_reload_reg[nregno + k] reg_last_reload_reg[nregno + k]
= (nr == nnr = (piecemeal
? regno_reg_rtx[REGNO (rld[r].reg_rtx) + k] ? regno_reg_rtx[REGNO (rld[r].reg_rtx) + k]
: 0); : 0);
...@@ -7160,7 +7187,7 @@ emit_reload_insns (struct insn_chain *chain) ...@@ -7160,7 +7187,7 @@ emit_reload_insns (struct insn_chain *chain)
{ {
CLEAR_HARD_REG_BIT (reg_reloaded_dead, i + k); CLEAR_HARD_REG_BIT (reg_reloaded_dead, i + k);
reg_reloaded_contents[i + k] reg_reloaded_contents[i + k]
= (nregno >= FIRST_PSEUDO_REGISTER || nr != nnr = (nregno >= FIRST_PSEUDO_REGISTER || !piecemeal
? nregno ? nregno
: nregno + k); : nregno + k);
reg_reloaded_insn[i + k] = insn; reg_reloaded_insn[i + k] = insn;
...@@ -7185,6 +7212,7 @@ emit_reload_insns (struct insn_chain *chain) ...@@ -7185,6 +7212,7 @@ emit_reload_insns (struct insn_chain *chain)
int nregno; int nregno;
int nnr; int nnr;
rtx in; rtx in;
bool piecemeal;
if (GET_CODE (rld[r].in) == REG if (GET_CODE (rld[r].in) == REG
&& REGNO (rld[r].in) >= FIRST_PSEUDO_REGISTER) && REGNO (rld[r].in) >= FIRST_PSEUDO_REGISTER)
...@@ -7201,10 +7229,14 @@ emit_reload_insns (struct insn_chain *chain) ...@@ -7201,10 +7229,14 @@ emit_reload_insns (struct insn_chain *chain)
reg_last_reload_reg[nregno] = rld[r].reg_rtx; reg_last_reload_reg[nregno] = rld[r].reg_rtx;
piecemeal = (nregno < FIRST_PSEUDO_REGISTER
&& nr == nnr
&& inherit_piecemeal_p (r, nregno));
if (nregno < FIRST_PSEUDO_REGISTER) if (nregno < FIRST_PSEUDO_REGISTER)
for (k = 1; k < nnr; k++) for (k = 1; k < nnr; k++)
reg_last_reload_reg[nregno + k] reg_last_reload_reg[nregno + k]
= (nr == nnr = (piecemeal
? regno_reg_rtx[REGNO (rld[r].reg_rtx) + k] ? regno_reg_rtx[REGNO (rld[r].reg_rtx) + k]
: 0); : 0);
...@@ -7220,7 +7252,7 @@ emit_reload_insns (struct insn_chain *chain) ...@@ -7220,7 +7252,7 @@ emit_reload_insns (struct insn_chain *chain)
{ {
CLEAR_HARD_REG_BIT (reg_reloaded_dead, i + k); CLEAR_HARD_REG_BIT (reg_reloaded_dead, i + k);
reg_reloaded_contents[i + k] reg_reloaded_contents[i + k]
= (nregno >= FIRST_PSEUDO_REGISTER || nr != nnr = (nregno >= FIRST_PSEUDO_REGISTER || !piecemeal
? nregno ? nregno
: nregno + k); : nregno + k);
reg_reloaded_insn[i + k] = insn; reg_reloaded_insn[i + k] = insn;
......
2004-05-04 Richard Sandiford <rsandifo@redhat.com>
* gcc.dg/torture/mips-hilo-2.c: New test.
2004-05-03 Giovanni Bajo <giovannibajo@gcc.gnu.org> 2004-05-03 Giovanni Bajo <giovannibajo@gcc.gnu.org>
PR c++/14389 PR c++/14389
......
/* Due to a reload inheritance bug, the asm statement in f() would be passed
the low part of u.ll on little-endian 32-bit targets. */
/* { dg-do run { target mips*-*-* } } */
unsigned int g;
unsigned long long f (unsigned int x)
{
union { unsigned long long ll; unsigned int parts[2]; } u;
u.ll = ((unsigned long long) x * x);
asm ("mflo\t%0" : "=r" (g) : "l" (u.parts[1]));
return u.ll;
}
int main ()
{
union { unsigned long long ll; unsigned int parts[2]; } u;
u.ll = f (0x12345678);
if (g != u.parts[1])
abort ();
exit (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