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]

Re: Reload patch for PA call rewrite.


> On Wed, Oct 23, 2002 at 04:33:50PM -0400, John David Anglin wrote:
> > 	* reload1.c (reload): Make the arg pointer register live if the memory
> > 	address that is used to eliminate a pseudo mentions it.
> 
> This patch isn't correct.  You're doing this too late.  If
> the argument pointer isn't live at this point, you won't have
> allocated a spill slot for it, which means you'll have to add
> one, which means that all your elimination offsets change.

This really isn't a problem although there was a problem with my
backend patch in this respect.  The backend simply has to always
allocate a slot so that that the elimination offsets are independent
of whether the arg pointer is live or not.

> You need to have this happen inside the something_changed
> loop earlier in reload.

I did some further investigation of this and there doesn't appear
to be a simple change to do this.  If I make the arg pointer an
eliminable register that can't be eliminated, spill_hard_reg
unconditionally makes it live.  This causes my backend code to
unconditionally save the arg pointer register, copy the incoming
arg pointer to the arg pointer, and then restore the arg pointer.
The overhead of this is significant in small functions and much
of the benefit in having tail calls is lost.

I experimented with not making the arg pointer unconditionally
live and still spilling it.  However, then I end up with the same
situation as when the arg pointer isn't an eliminable register.
The arg pointer can implicitly become alive when an incoming
argument is copied to a pseudo and that pseudo doesn't get a
hard register.  The only possible solutions to this are 1) somehow
move the final pseudo substition into the something_changed loop,
or 2) allocate slots for incoming arguments using the frame pointer.
I don't think 1) is possible as you don't know whether the pseudo
will get a hard register until the loop completes.  2) wastes stack
space as the PA64 ABI already reserves stack slots for the incoming
arguments in registers, albeit relative to the arg pointer.

So, I'm back to more or less my original patch with some modified
commentary.  I would argue that it can't be wrong to set regs_ever_live
for the arg pointer when the arg pointer is in fact live at some point
in the function.  If this somehow changes elimination offsets, that's
really a problem in the backend.  We could abort if this happens and
insist that the arg pointer be in the set of eliminable registers.
This would ensure that it is always spilled and alive when it can't
be eliminated.  However, I then would have to do a brute force scan
in the prologue to determine if the arg pointer is ever used.

Do you see any other approach?

Dave
-- 
J. David Anglin                                  dave.anglin@nrc.ca
National Research Council of Canada              (613) 990-0752 (FAX: 952-6605)

2002-10-30  John David Anglin  <dave@hiauly1.hia.nrc.ca>

	* reload1.c (reload): Make the arg pointer live if it used in a
	substituted MEM.
	* doc/tm.texi (ARG_POINTER_REGNUM): Document that elimination offsets
	should not depend on the aliveness of the arg pointer when it is not
	an eliminable register.

Index: reload1.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/reload1.c,v
retrieving revision 1.363
diff -u -3 -p -r1.363 reload1.c
--- reload1.c	29 Oct 2002 17:47:12 -0000	1.363
+++ reload1.c	30 Oct 2002 19:17:16 -0000
@@ -1167,6 +1167,15 @@ reload (first, global)
 		    = MEM_SCALAR_P (reg) = 0;
 		  MEM_ATTRS (reg) = 0;
 		}
+
+	      /* The substitution may have made the arg pointer live if
+		 it isn't an eliminable register.  The target must ensure
+		 that the elimination offsets do not change when this
+		 happens as we are past the point where the offsets can
+		 change.  */
+	      if (!regs_ever_live[ARG_POINTER_REGNUM]
+		  && reg_mentioned_p (arg_pointer_rtx, addr))
+		regs_ever_live[ARG_POINTER_REGNUM] = 1;
 	    }
 	  else if (reg_equiv_mem[i])
 	    XEXP (reg_equiv_mem[i], 0) = addr;
Index: doc/tm.texi
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/doc/tm.texi,v
retrieving revision 1.179
diff -u -3 -p -r1.179 tm.texi
--- doc/tm.texi	20 Oct 2002 18:52:01 -0000	1.179
+++ doc/tm.texi	30 Oct 2002 19:17:22 -0000
@@ -3103,7 +3103,10 @@ frame pointer register.  On some machine
 register this is.  On other machines, you can choose any register you
 wish for this purpose.  If this is not the same register as the frame
 pointer register, then you must mark it as a fixed register according to
-@code{FIXED_REGISTERS}, or arrange to be able to eliminate it
+@code{FIXED_REGISTERS}, or arrange to be able to eliminate it.  If you
+don't define it as an eliminable register in @code{ELIMINABLE_REGS},
+then the backend must ensure that the elimination offsets do not depend
+on the liveness of the register
 (@pxref{Elimination}).
 
 @findex RETURN_ADDRESS_POINTER_REGNUM


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