This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Revised patch: Re: PATCH 1: Re: BOOTSTRAP FAILURE: segementation fault in genattrtab
- To: law at redhat dot com
- Subject: Revised patch: Re: PATCH 1: Re: BOOTSTRAP FAILURE: segementation fault in genattrtab
- From: "John David Anglin" <dave at hiauly1 dot hia dot nrc dot ca>
- Date: Sun, 26 Nov 2000 12:14:04 -0500 (EST)
- Cc: gcc-bugs at gcc dot gnu dot org, gcc-patches at gcc dot gnu dot org
> > The following patch resolves the above issue (ie, after reload starts,
> > gen_rtx_REG should should not return the frame_pointer_rtx for the frame
> > pointer register number). Tested with a full bootstrap and check under
> > hpux 10.20.
> >
> > Please review for installation.
> It seems to me that we should return the hard frame pointer if it is
> being used that way. Else we should not.
>
> ie, if we did not eliminate the frame pointer, then returning frame_pointer_rtx
> would be the right thing to do.
>
> If we did eliminate the frame pointer, then we do not want to return
> frame_pointer_rtx.
Here is a revised patch. Tested with a bootstrap and check under hpux
10.20. Please review and install if OK.
Dave
--
J. David Anglin dave.anglin@nrc.ca
National Research Council of Canada (613) 990-0752 (FAX: 952-6605)
2000-11-24 John David Anglin <dave@hiauly1.hia.nrc.ca>
* emit-rtl.c (gen_rtx_REG): Don't return frame_pointer_rtx or
arg_pointer_rtx after reload unless they are needed.
* flags.h: Declare new flag arg_pointer_needed.
* function.c (prepare_function_start): Initialize arg_pointer_needed.
* reload1.c (update_eliminables): Determine if the arg pointer can
be eliminated when the port uses a distinct register for it.
(init_elim_table): Set arg_pointer_needed to one if the port uses
a distinct register for the arg pointer.
* final.c: Define flag arg_pointer_needed.
--- emit-rtl.c.orig Thu Nov 23 14:34:37 2000
+++ emit-rtl.c Fri Nov 24 16:49:05 2000
@@ -299,7 +299,7 @@
Also don't do this when we are making new REGs in reload, since
we don't want to get confused with the real pointers. */
- if (mode == Pmode && !reload_in_progress)
+ if (mode == Pmode && !reload_in_progress && !reload_completed)
{
if (regno == FRAME_POINTER_REGNUM)
return frame_pointer_rtx;
@@ -319,6 +319,26 @@
return stack_pointer_rtx;
}
+ if (mode == Pmode && reload_completed)
+ {
+ if (regno == FRAME_POINTER_REGNUM && frame_pointer_needed)
+ return frame_pointer_rtx;
+#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
+ if (regno == HARD_FRAME_POINTER_REGNUM)
+ return hard_frame_pointer_rtx;
+#endif
+#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM && HARD_FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
+ if (regno == ARG_POINTER_REGNUM && arg_pointer_needed)
+ return arg_pointer_rtx;
+#endif
+#ifdef RETURN_ADDRESS_POINTER_REGNUM
+ if (regno == RETURN_ADDRESS_POINTER_REGNUM)
+ return return_address_pointer_rtx;
+#endif
+ if (regno == STACK_POINTER_REGNUM)
+ return stack_pointer_rtx;
+ }
+
return gen_rtx_raw_REG (mode, regno);
}
--- flags.h.orig Sun Oct 29 14:34:52 2000
+++ flags.h Fri Nov 24 16:53:20 2000
@@ -551,6 +551,10 @@
extern int frame_pointer_needed;
+/* Nonzero means current function must be given an arg pointer. */
+
+extern int arg_pointer_needed;
+
/* Nonzero if GCC must add code to check memory access (used by Checker). */
extern int flag_check_memory_usage;
--- function.c.orig Fri Nov 24 16:26:18 2000
+++ function.c Fri Nov 24 16:56:15 2000
@@ -6009,6 +6009,9 @@
/* Indicate we have no need of a frame pointer yet. */
frame_pointer_needed = 0;
+ /* Indicate we have no need of an arg pointer yet. */
+ arg_pointer_needed = 0;
+
/* By default assume not varargs or stdarg. */
current_function_varargs = 0;
current_function_stdarg = 0;
--- reload1.c.save Fri Nov 24 16:23:55 2000
+++ reload1.c Fri Nov 24 17:10:05 2000
@@ -3377,12 +3377,20 @@
no elimination of the frame pointer that we can perform. */
frame_pointer_needed = 1;
+#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM && HARD_FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
+ arg_pointer_needed = 1;
+#endif
for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++)
{
if (ep->can_eliminate && ep->from == FRAME_POINTER_REGNUM
&& ep->to != HARD_FRAME_POINTER_REGNUM)
frame_pointer_needed = 0;
+#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM && HARD_FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
+ if (ep->can_eliminate && ep->from == ARG_POINTER_REGNUM)
+ arg_pointer_needed = 0;
+#endif
+
if (! ep->can_eliminate && ep->can_eliminate_previous)
{
ep->can_eliminate_previous = 0;
@@ -3427,6 +3435,12 @@
#endif
|| FRAME_POINTER_REQUIRED);
+ /* Does this function require an arg pointer? */
+
+#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM && HARD_FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
+ arg_pointer_needed = 1;
+#endif
+
num_eliminable = 0;
#ifdef ELIMINABLE_REGS
--- final.c.orig Thu Nov 23 14:34:39 2000
+++ final.c Fri Nov 24 18:25:05 2000
@@ -206,6 +206,10 @@
int frame_pointer_needed;
+/* Nonzero means current function must be given an arg pointer. */
+
+int arg_pointer_needed;
+
/* Assign unique numbers to labels generated for profiling. */
int profile_label_no;