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]

[PATCH] -fpic problems on PPC, a different approach


Hi,

after staring at all the -fpic/reload related messages in the archives for a
while and thinking about it, I had an idea how to handle it differently.
Currently 2 known problems are left with -fpic:

1. reload may generate new uses of pic_offset_table_rtx, which may result in
miscompilation (gcc.dg/980523-1.c)
2. some kind of code typical for glibc math routines and it's headers may end up
in trying to setup pic_offset_table_rtx during reload, which then aborts. A
short testcase that shows that this problem still occurs with gcc-2.95pre is as
follows (derived from glibc-2.1.1):

extern   float      __copysignf  (float   __x, float   __y)     __attribute__ (    (__const__)  )  ;
__complex__ float __csinhf (__complex__ float x)
{
  __complex__ float retval;
  float sinix, cosix;

  __real__ retval = __copysignf ((__extension__ ((
                                                  union {
                                                     unsigned __l __attribute__((__mode__(__SI__)));
                                                     float __d; }
                                                 ) { __l: 0x7f800000UL }
                                                 ).__d) , cosix);
  __imag__ retval = __copysignf ((__extension__ ((
                                                  union {
                                                     unsigned __l __attribute__((__mode__(__SI__)));
                                                     float __d; }
                                                 ) { __l: 0x7f800000UL }
                                                ).__d) , sinix);

  return retval;
}

For both problems there's a fix from Geoff Keating, which won't be accepted for
inclusion into gcc. Geoff solved both problems in reload.

After thinking about what's going wrong in reload, I saw another possibility.
Don't look at pic_offset_table_rtx as a regular pseudo, look at it more like a
frame_pointer_rtx, which stays alive during the whole function. The only
difference being that pic_offset_table_rtx may not at all show up, depending on
the code. Now the only important thing to do is to avoid attaching REG_DEAD
notes to any uses of pic_offset_table_rtx. So I introduced a new macro
PSEUDO_REGNO_EVER_LIVE and used it in flow.c/mark_regs_used() and voila, bug#1
was fixed (at least the testcase).

So, now I would like to know a few things:
- is this a valid approach and might it be accepted for gcc?
- I'm not exactly sure about the placement of PSEUDO_REGNO_EVER_LIVE in flow.c
- do I have to handle this in combine.c too? Or in other files/places?

This still leaves us with problem #2, but this might be solvable with some
tweaking of PREFERRED_RELOAD_CLASS and maybe SECONDARY_RELOAD_CLASS?

Franz.


Index: flow.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/flow.c,v
retrieving revision 1.120.4.2
diff -u -p -r1.120.4.2 flow.c
--- flow.c	1999/06/01 21:49:28	1.120.4.2
+++ flow.c	1999/06/06 20:08:12
@@ -3782,6 +3782,10 @@ mark_used_regs (needed, live, x, final, 
 
 	    reg_next_use[regno] = insn;
 
+#ifdef PSEUDO_REGNO_EVER_LIVE
+	    if (!reload_completed && PSEUDO_REGNO_EVER_LIVE (regno))
+	      return;
+#endif
 	    if (regno < FIRST_PSEUDO_REGISTER)
 	      {
 		/* If a hard reg is being used,
Index: config/rs6000/rs6000.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.49
diff -u -p -r1.49 rs6000.h
--- rs6000.h	1999/05/13 12:38:42	1.49
+++ rs6000.h	1999/06/06 20:08:19
@@ -2150,6 +2150,20 @@ do {                                    
 
 #define MACHINE_DEPENDENT_REORG(INSN) rs6000_reorg (INSN)
 
+/* This macro prevents attaching REG_DEAD notes to certain pseudos,
+   making it possible to forcibly spread the lifetime of a pseudo
+   over the whole function.
+
+   On the RS/6000 SYSV ABI we use it to make sure that the lifetime
+   of pic_offset_table_rtx is spread over the whole current function.
+   This is necessary to prevent reload generating new uses of
+   pic_offset_table_rtx, after it's lifetime already would have 
+   expired. */
+
+#define PSEUDO_REGNO_EVER_LIVE(X)				\
+ (flag_pic==1 && pic_offset_table_rtx				\
+  && (X) == REGNO (pic_offset_table_rtx))
+
 
 /* Define this if some processing needs to be done immediately before
    emitting code for an insn.  */




Index: flow.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/flow.c,v
retrieving revision 1.120.4.2
diff -u -p -r1.120.4.2 flow.c
--- flow.c	1999/06/01 21:49:28	1.120.4.2
+++ flow.c	1999/06/06 20:08:12
@@ -3782,6 +3782,10 @@ mark_used_regs (needed, live, x, final, 
 
 	    reg_next_use[regno] = insn;
 
+#ifdef PSEUDO_REGNO_EVER_LIVE
+	    if (!reload_completed && PSEUDO_REGNO_EVER_LIVE (regno))
+	      return;
+#endif
 	    if (regno < FIRST_PSEUDO_REGISTER)
 	      {
 		/* If a hard reg is being used,
Index: config/rs6000/rs6000.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.49
diff -u -p -r1.49 rs6000.h
--- rs6000.h	1999/05/13 12:38:42	1.49
+++ rs6000.h	1999/06/06 20:08:19
@@ -2150,6 +2150,20 @@ do {                                    
 
 #define MACHINE_DEPENDENT_REORG(INSN) rs6000_reorg (INSN)
 
+/* This macro prevents attaching REG_DEAD notes to certain pseudos,
+   making it possible to forcibly spread the lifetime of a pseudo
+   over the whole function.
+
+   On the RS/6000 SYSV ABI we use it to make sure that the lifetime
+   of pic_offset_table_rtx is spread over the whole current function.
+   This is necessary to prevent reload generating new uses of
+   pic_offset_table_rtx, after it's lifetime already would have 
+   expired. */
+
+#define PSEUDO_REGNO_EVER_LIVE(X)				\
+ (flag_pic==1 && pic_offset_table_rtx				\
+  && (X) == REGNO (pic_offset_table_rtx))
+
 
 /* Define this if some processing needs to be done immediately before
    emitting code for an insn.  */

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