This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
reload patch to fix compile/20000804-1.c on powerpc
- To: gcc-patches at gcc dot gnu dot org
- Subject: reload patch to fix compile/20000804-1.c on powerpc
- From: Geoff Keating <geoffk at cygnus dot com>
- Date: Thu, 10 Aug 2000 01:11:22 -0700
We started with:
(insn 35 34 37 (set (concat:CDI (reg:DI 88)
(reg:DI 89))
(asm_operands ("") ("=r") 0[
(reg:SI 90)
(reg:SI 91)
(concat:CDI (reg:DI 88)
(reg:DI 89))
]
[
(asm_input:SI ("r"))
(asm_input:SI ("r"))
(asm_input:CDI ("0"))
] ("/home/geoffk/cygnus/co/egcs-mainline/egcs/gcc/testsuite/gcc.c-t
orture/compile/20000804-1.c") 8)) -1 (nil)
(expr_list:REG_DEAD (reg:SI 91)
(expr_list:REG_DEAD (reg:SI 90)
(nil))))
and global-alloc decided to put the CONCAT into
(concat:CDI (reg:DI 32 f0) (reg:DI 45 f13))
[this is probably a bug in regclass, or something]
and then reload had to deal with the resulting mess, which it did by
generating a reload:
Reload 0: reload_in (CDI) = (concat:CDI (reg:DI 32 f0)
(reg:DI 45 f13))
reload_out (CDI) = (concat:CDI (reg:DI 32 f0)
(reg:DI 45 f13))
GENERAL_REGS, RELOAD_OTHER (opnum = 0)
reload_in_reg: (concat:CDI (reg:DI 32 f0)
(reg:DI 45 f13))
reload_out_reg: (concat:CDI (reg:DI 32 f0)
(reg:DI 45 f13))
reload_reg_rtx: (reg:CDI 5 r5)
very cool, but unfortunately it needs secondary memory to
copy between int and FP registers, and it wasn't allocating it
(or using it).
I'll commit this when it finishes a bootstrap and test on
powerpc-linux. I believe that in the absence of CONCAT it is
equivalent to the existing code.
There are some interesting bugs in the whole SECONDARY_MEMORY_NEEDED
thing, mostly related to matching push_reload and gen_reload. IMHO,
it's a bug that gen_reload looks at SECONDARY_MEMORY_NEEDED at all;
instead, push_reload should do the work and only generate reloads
that are valid. One day I may even fix it :-).
--
- Geoffrey Keating <geoffk@cygnus.com>
===File ~/patches/cygnus/rs6000-cmplxLLreload.patch=========
2000-08-10 Geoff Keating <geoffk@cygnus.com>
* reload1.c (rtx_reg_class): New function.
(gen_reload): Use rtx_reg_class to determine the class
of hard registers, even if they are inside a CONCAT.
* reload.c (push_reload): Change to match above change to
gen_reload.
* reload.h: Prototype rtx_reg_class.
Index: gcc/reload.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/reload.c,v
retrieving revision 1.117
diff -p -u -u -p -r1.117 reload.c
--- reload.c 2000/08/04 20:28:05 1.117
+++ reload.c 2000/08/10 07:44:16
@@ -1218,6 +1218,9 @@ push_reload (in, out, inloc, outloc, cla
if (i == n_reloads)
{
+#ifdef SECONDARY_MEMORY_NEEDED
+ enum reg_class inclass, outclass;
+#endif
/* See if we need a secondary reload register to move between CLASS
and IN or CLASS and OUT. Get the icode and push any required reloads
needed for each of them if so. */
@@ -1241,10 +1244,9 @@ push_reload (in, out, inloc, outloc, cla
#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))
+ if (in != 0
+ && (inclass = rtx_reg_class (in)) != NO_REGS
+ && SECONDARY_MEMORY_NEEDED (inclass, class, inmode))
get_secondary_mem (in, inmode, opnum, type);
#endif
@@ -1271,10 +1273,9 @@ push_reload (in, out, inloc, outloc, cla
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))
+ if (out != 0
+ && (outclass = rtx_reg_class (out)) != NO_REGS
+ && SECONDARY_MEMORY_NEEDED (class, outclass, outmode))
get_secondary_mem (out, outmode, opnum, type);
#endif
}
Index: gcc/reload.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/reload.h,v
retrieving revision 1.29
diff -p -u -u -p -r1.29 reload.h
--- reload.h 2000/07/28 17:46:17 1.29
+++ reload.h 2000/08/10 07:44:17
@@ -358,6 +358,9 @@ extern void mark_home_live PARAMS ((int)
replacement (such as sp), plus an offset. */
extern rtx eliminate_regs PARAMS ((rtx, enum machine_mode, rtx));
+/* Determine the class of the hard register(s) R is stored in, if any. */
+extern enum reg_class rtx_reg_class PARAMS ((rtx r));
+
/* Emit code to perform a reload from IN (which may be a reload register) to
OUT (which may also be a reload register). IN or OUT is from operand
OPNUM with reload type TYPE. */
Index: gcc/reload1.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/reload1.c,v
retrieving revision 1.221
diff -p -u -u -p -r1.221 reload1.c
--- reload1.c 2000/08/08 23:07:10 1.221
+++ reload1.c 2000/08/10 07:44:42
@@ -7143,6 +7143,29 @@ emit_reload_insns (chain)
IOR_HARD_REG_SET (reg_reloaded_dead, reg_reloaded_died);
}
+/* Given a RTX R, determine the class of the hard register(s) it is
+ stored in, or return NO_REGS if it is not necessarily stored in a
+ hard register.
+*/
+enum reg_class
+rtx_reg_class (r)
+ rtx r;
+{
+ /* We need not deal with SUBREGs here because there shouldn't
+ be any SUBREGs of hard regs. */
+
+ if (GET_CODE (r) == REG && REGNO (r) < FIRST_PSEUDO_REGISTER)
+ return REGNO_REG_CLASS (REGNO (r));
+
+ else if (GET_CODE (r) == CONCAT)
+ return (reg_class_superunion
+ [rtx_reg_class (XEXP (r, 0))]
+ [rtx_reg_class (XEXP (r, 1))]);
+
+ else
+ return NO_REGS;
+}
+
/* Emit code to perform a reload from IN (which may be a reload register) to
OUT (which may also be a reload register). IN or OUT is from operand
OPNUM with reload type TYPE.
@@ -7158,6 +7181,9 @@ gen_reload (out, in, opnum, type)
{
rtx last = get_last_insn ();
rtx tem;
+#ifdef SECONDARY_MEMORY_NEEDED
+ enum reg_class inclass, outclass;
+#endif
/* If IN is a paradoxical SUBREG, remove it and try to put the
opposite SUBREG on OUT. Likewise for a paradoxical SUBREG on OUT. */
@@ -7320,10 +7346,9 @@ gen_reload (out, in, opnum, type)
#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)),
+ else if ((inclass = rtx_reg_class (in)) != NO_REGS
+ && (outclass = rtx_reg_class (out)) != NO_REGS
+ && SECONDARY_MEMORY_NEEDED (inclass, outclass,
GET_MODE (out)))
{
/* Get the memory to use and rewrite both registers to its mode. */
============================================================