This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
SECONDARY_MEMORY_NEEDED fix
- From: Jan Hubicka <jh at suse dot cz>
- To: gcc-patches at gcc dot gnu dot org, rth at cygnus dot com, geert at gnat dot com,bernds at redhat dot com
- Date: Mon, 26 Aug 2002 20:54:57 +0200
- Subject: SECONDARY_MEMORY_NEEDED fix
Hi,
this has shown up during adding the x86_64 TImode support. There was
instruction moving data from xmm register subregged to DImode into integer
register and didn't get proper reload, as reload is checking secondary memory
just for regs, not for subregs. I am not 100% sure whether the subregs are not
expected to be elliminated somewhere else, but they don't seem to be.
Again this applies to both 3.2 and mainline tree and bootstraps both.
Honza
Po srp 26 20:30:47 CEST 2002 Jan Hubicka <jh@suse.cz>
* reload.c (push_reload): Handle subregs and secondary memory.
* reload1.c (gen_reload): Likewise.
*** 3/gcc-3.2/gcc/reload.c Thu Jun 13 18:08:12 2002
--- gcc-3.2/gcc/reload.c Mon Aug 26 20:19:03 2002
*************** push_reload (in, out, inloc, outloc, cla
*** 1283,1294 ****
So add an additional reload. */
#ifdef SECONDARY_MEMORY_NEEDED
! /* If a memory location is needed for the copy, make one. */
! if (in != 0 && GET_CODE (in) == REG
! && REGNO (in) < FIRST_PSEUDO_REGISTER
! && SECONDARY_MEMORY_NEEDED (REGNO_REG_CLASS (REGNO (in)),
! class, inmode))
! get_secondary_mem (in, inmode, opnum, type);
#endif
i = n_reloads;
--- 1283,1301 ----
So add an additional reload. */
#ifdef SECONDARY_MEMORY_NEEDED
! {
! unsigned int regno = FIRST_PSEUDO_REGISTER;
! if (in && REG_P (in))
! regno = REGNO (in);
! else if (in && GET_CODE (in) == SUBREG)
! regno = REGNO (SUBREG_REG (in));
!
! /* If a memory location is needed for the copy, make one. */
! if (regno < FIRST_PSEUDO_REGISTER
! && SECONDARY_MEMORY_NEEDED (REGNO_REG_CLASS (regno),
! class, inmode))
! get_secondary_mem (in, inmode, opnum, type);
! }
#endif
i = n_reloads;
*************** push_reload (in, out, inloc, outloc, cla
*** 1314,1324 ****
n_reloads++;
#ifdef SECONDARY_MEMORY_NEEDED
! if (out != 0 && GET_CODE (out) == REG
! && REGNO (out) < FIRST_PSEUDO_REGISTER
! && SECONDARY_MEMORY_NEEDED (class, REGNO_REG_CLASS (REGNO (out)),
! outmode))
! get_secondary_mem (out, outmode, opnum, type);
#endif
}
else
--- 1321,1339 ----
n_reloads++;
#ifdef SECONDARY_MEMORY_NEEDED
! {
! unsigned int regno = FIRST_PSEUDO_REGISTER;
! if (out && REG_P (out))
! regno = REGNO (out);
! else if (out && GET_CODE (out) == SUBREG)
! regno = REGNO (SUBREG_REG (out));
!
! /* If a memory location is needed for the copy, make one. */
! if (regno < FIRST_PSEUDO_REGISTER
! && SECONDARY_MEMORY_NEEDED (class, REGNO_REG_CLASS (regno),
! outmode))
! get_secondary_mem (out, outmode, opnum, type);
! }
#endif
}
else
*** 3/gcc-3.2/gcc/reload1.c Wed May 22 01:42:54 2002
--- gcc-3.2/gcc/reload1.c Mon Aug 26 20:11:39 2002
*************** gen_reload (out, in, opnum, type)
*** 7354,7359 ****
--- 7354,7362 ----
{
rtx last = get_last_insn ();
rtx tem;
+ int inregno = FIRST_PSEUDO_REGISTER;
+ int outregno = FIRST_PSEUDO_REGISTER;
+
/* If IN is a paradoxical SUBREG, remove it and try to put the
opposite SUBREG on OUT. Likewise for a paradoxical SUBREG on OUT. */
*************** gen_reload (out, in, opnum, type)
*** 7368,7373 ****
--- 7371,7385 ----
&& (tem = gen_lowpart_common (GET_MODE (SUBREG_REG (out)), in)) != 0)
out = SUBREG_REG (out), in = tem;
+ if (REG_P (in))
+ inregno = REGNO (in);
+ else if (GET_CODE (in) == SUBREG)
+ inregno = REGNO (SUBREG_REG (in));
+ if (REG_P (out))
+ outregno = REGNO (out);
+ else if (GET_CODE (out) == SUBREG)
+ outregno = REGNO (SUBREG_REG (out));
+
/* How to do this reload can get quite tricky. Normally, we are being
asked to reload a simple operand, such as a MEM, a constant, or a pseudo
register that didn't get a hard register. In that case we can just
*************** gen_reload (out, in, opnum, type)
*** 7516,7535 ****
#ifdef SECONDARY_MEMORY_NEEDED
/* If we need a memory location to do the move, do it that way. */
! else if (GET_CODE (in) == REG && REGNO (in) < FIRST_PSEUDO_REGISTER
! && GET_CODE (out) == REG && REGNO (out) < FIRST_PSEUDO_REGISTER
! && SECONDARY_MEMORY_NEEDED (REGNO_REG_CLASS (REGNO (in)),
! REGNO_REG_CLASS (REGNO (out)),
GET_MODE (out)))
{
/* Get the memory to use and rewrite both registers to its mode. */
rtx loc = get_secondary_mem (in, GET_MODE (out), opnum, type);
if (GET_MODE (loc) != GET_MODE (out))
! out = gen_rtx_REG (GET_MODE (loc), REGNO (out));
if (GET_MODE (loc) != GET_MODE (in))
! in = gen_rtx_REG (GET_MODE (loc), REGNO (in));
gen_reload (loc, in, opnum, type);
gen_reload (out, loc, opnum, type);
--- 7528,7547 ----
#ifdef SECONDARY_MEMORY_NEEDED
/* If we need a memory location to do the move, do it that way. */
! else if (inregno < FIRST_PSEUDO_REGISTER
! && outregno < FIRST_PSEUDO_REGISTER
! && SECONDARY_MEMORY_NEEDED (REGNO_REG_CLASS (inregno),
! REGNO_REG_CLASS (outregno),
GET_MODE (out)))
{
/* Get the memory to use and rewrite both registers to its mode. */
rtx loc = get_secondary_mem (in, GET_MODE (out), opnum, type);
if (GET_MODE (loc) != GET_MODE (out))
! out = gen_rtx_REG (GET_MODE (loc), outregno);
if (GET_MODE (loc) != GET_MODE (in))
! in = gen_rtx_REG (GET_MODE (loc), inregno);
gen_reload (loc, in, opnum, type);
gen_reload (out, loc, opnum, type);