This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Re: leaf functions are broken on SPARC
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Richard Henderson <rth at redhat dot com>
- Cc: Dan Nicolaescu <dann at godzilla dot ICS dot UCI dot EDU>, gcc-patches at gcc dot gnu dot org
- Date: Sun, 10 Mar 2002 22:33:50 +0100
- Subject: [PATCH] Re: leaf functions are broken on SPARC
- References: <200203100840.aa28789@gremlin-relay.ics.uci.edu> <20020310204632.H2204@sunsite.ms.mff.cuni.cz>
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
> On Sun, Mar 10, 2002 at 08:40:35AM -0800, Dan Nicolaescu wrote:
> > GCC CVS does not generate leaf functions anymore on SPARC
> > (sparc-sun-solaris2.7):
> >
> >
> > void foo (void)
> > {
> > }
> >
> >
> > compiles to (with -O2):
> >
> > .file "p.c"
> > .section ".text"
> > .align 4
> > .global foo
> > .type foo,#function
> > .proc 020
> > foo:
> > !#PROLOGUE# 0
> > save %sp, -112, %sp <=== ???
> > !#PROLOGUE# 1
> > ret
> > restore
> >
> > This is a regression from 3.0.x
> > Is this a SPARC specific problem?
This looks like a consequence of Richard's 2002-02-04 %sfp patch.
If ELIMINABLE_REGS is defined, then the default fp->sp elimination
is not done.
Something like the following fixes this on trivial testcases I have tried
(gave the same output as gcc 3.0 with -m64 -O2; the tests had
some automatic arrays and were passing more than 6 integer arguments
around), but I need to fix some glibc 2.2.5 issues on sparc64 before I
can do a sparc64 bootstrap.
INITIAL_ELIMINATION_OFFSET might actually need to be
do {
(OFFSET) = 0;
if ((TO) == STACK_POINTER_REGNUM)
INITIAL_FRAME_POINTER_OFFSET (OFFSET);
(OFFSET) += SPARC_STACK_BIAS;
} while (0)
instead.
2002-03-10 Jakub Jelinek <jakub@redhat.com>
* config/sparc/sparc.h (ELIMINABLE_REGS): Add sfp->sp.
(INITIAL_ELIMINATION_OFFSET): For sfp->sp use
INITIAL_FRAME_POINTER_OFFSET.
--- gcc/config/sparc/sparc.h.jj Tue Feb 26 10:33:19 2002
+++ gcc/config/sparc/sparc.h Tue Feb 26 10:33:19 2002
@@ -1589,12 +1589,20 @@ extern const char leaf_reg_remap[];
/* ??? In TARGET_FLAT mode we needn't have a hard frame pointer. */
#define ELIMINABLE_REGS \
- {{ FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}}
+ {{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
+ { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM} }
#define CAN_ELIMINATE(FROM, TO) 1
-#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
- ((OFFSET) = SPARC_STACK_BIAS)
+#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
+ do { \
+ if ((TO) == HARD_FRAME_POINTER_REGNUM) \
+ (OFFSET) = SPARC_STACK_BIAS; \
+ else if ((TO) == STACK_POINTER_REGNUM) \
+ INITIAL_FRAME_POINTER_OFFSET (OFFSET); \
+ else \
+ abort (); \
+ } while (0)
/* Keep the stack pointer constant throughout the function.
This is both an optimization and a necessity: longjmp
Jakub