This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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
============================================================


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]