This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
fix goto out of nested function on Darwin
- From: Geoffrey Keating <gkeating at apple dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 20 Sep 2002 11:36:59 -0700 (PDT)
- Subject: fix goto out of nested function on Darwin
A goto out of a nested function, on Darwin, produces RTL like this on
one testcase to restore the stack pointer (r1) and frame pointer (r30
on darwin):
(insn 6 5 7 0x0 (set (reg:SI 120)
(reg:SI 11 r11)) -1 (nil)
(nil))
(insn 15 13 16 0x0 (set (reg:SI 122)
(reg:SI 120)) -1 (nil)
(nil))
(insn 17 16 18 0x0 (set (reg/f:SI 30 r30)
(reg:SI 122)) -1 (nil)
(nil))
(insn 21 20 22 0x0 (set (reg/f:SI 1 r1)
(mem:SI (plus:SI (reg:SI 122)
(const_int 12 [0xc])) [0 S4 A8])) -1 (nil)
(nil))
CSE helpfully notices that insn 21 can be simplified to:
(insn 21 20 22 1 0x0 (set (reg/f:SI 1 r1)
(mem:SI (plus:SI (reg/f:SI 30 r30)
(const_int 12 [0xc])) [0 S4 A8])) 300
{*movsi_internal1} (nil)
(nil))
Now, on AIX and SVR4, r30 is the PIC register, and the elimination
machinery is used to detect whether r30 is being used and fix up some
register-allocation problems. A side effect of this is that when
reload sees insn 17, it considers it a store to a register that is
being eliminated, and deletes it (because it must be dead, right?).
Naturally, this doesn't work very well.
Bootstrapped & tested on powerpc-darwin.
--
- Geoffrey Keating <geoffk@apple.com>
===File ~/patches/darwin-nestedgotofix.patch================
2002-09-20 Geoffrey Keating <geoffk@apple.com>
* config/rs6000/rs6000.h (ELIMINABLE_REGS): Use
RS6000_PIC_OFFSET_TABLE_REGNUM rather than hardcoding 30.
(CAN_ELIMINATE): Likewise.
(INITIAL_ELIMINATION_OFFSET): Likewise.
(TOC_REGISTER): Likewise.
Index: config/rs6000/rs6000.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.226
diff -u -p -r1.226 rs6000.h
--- config/rs6000/rs6000.h 14 Sep 2002 13:12:54 -0000 1.226
+++ config/rs6000/rs6000.h 20 Sep 2002 18:30:06 -0000
@@ -1893,7 +1893,7 @@ typedef struct rs6000_args
{{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
{ ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \
- { 30, 30} }
+ { RS6000_PIC_OFFSET_TABLE_REGNUM, RS6000_PIC_OFFSET_TABLE_REGNUM } }
/* Given FROM and TO register numbers, say whether this elimination is allowed.
Frame pointer elimination is automatically handled.
@@ -1904,10 +1904,11 @@ typedef struct rs6000_args
We need r30 if -mminimal-toc was specified, and there are constant pool
references. */
-#define CAN_ELIMINATE(FROM, TO) \
- ((FROM) == ARG_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM \
- ? ! frame_pointer_needed \
- : (FROM) == 30 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0 \
+#define CAN_ELIMINATE(FROM, TO) \
+ ((FROM) == ARG_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM \
+ ? ! frame_pointer_needed \
+ : (FROM) == RS6000_PIC_OFFSET_TABLE_REGNUM \
+ ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0 \
: 1)
/* Define the offset between two registers, one to be eliminated, and the other
@@ -1922,7 +1923,7 @@ typedef struct rs6000_args
(OFFSET) = info->total_size; \
else if ((FROM) == ARG_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM) \
(OFFSET) = (info->push_p) ? info->total_size : 0; \
- else if ((FROM) == 30) \
+ else if ((FROM) == RS6000_PIC_OFFSET_TABLE_REGNUM) \
(OFFSET) = 0; \
else \
abort (); \
@@ -2187,7 +2188,7 @@ do { \
#define RS6000_PIC_OFFSET_TABLE_REGNUM 30
#define PIC_OFFSET_TABLE_REGNUM (flag_pic ? RS6000_PIC_OFFSET_TABLE_REGNUM : INVALID_REGNUM)
-#define TOC_REGISTER (TARGET_MINIMAL_TOC ? 30 : 2)
+#define TOC_REGISTER (TARGET_MINIMAL_TOC ? RS6000_PIC_OFFSET_TABLE_REGNUM : 2)
/* Define this macro if the register defined by
`PIC_OFFSET_TABLE_REGNUM' is clobbered by calls. Do not define
============================================================