This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] -fpic problems on PPC, a different approach
- To: egcs-patches at egcs dot cygnus dot com
- Subject: [PATCH] -fpic problems on PPC, a different approach
- From: Franz Sirl <Franz dot Sirl-kernel at lauterbach dot com>
- Date: Mon, 7 Jun 1999 22:32:40 +0200
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. */