This is the mail archive of the
mailing list for the GCC project.
how can RETURN_ADDR_RTX possibly do its work?
- From: "Dave Korn" <dk at artimi dot com>
- To: <gcc at gcc dot gnu dot org>
- Date: Tue, 25 May 2004 13:33:04 +0100
- Subject: how can RETURN_ADDR_RTX possibly do its work?
This one's a little curious. The gcc internals manual says:
"`RETURN_ADDR_RTX (COUNT, FRAMEADDR)'
A C expression whose value is RTL representing the value of the
return address for the frame COUNT steps up from the current
frame, after the prologue. FRAMEADDR is the frame pointer of the
COUNT frame, or the frame pointer of the COUNT - 1 frame if
`RETURN_ADDR_IN_PREVIOUS_FRAME' is defined.
The value of the expression must always be the correct address when
COUNT is zero, but may be `NULL_RTX' if there is not way to
determine the return address of other frames."
Now, ISTM that knowing whether your return address is still stored in your
link register or has been saved in a stack slot requires you to have done
the stack frame layout first. And probably also the register allocation /
But if you call __builtin_return_address in a function, RETURN_ADDR_RTX
will be invoked at the point the function call is being compiled.
This is long before gcc calls INITIAL_FRAME_POINTER_OFFSET and starts
working out the stack variables size that it has to pass to your layout code
in the md function prolog/epilog routines. It's almost certainly before
regs_ever_live has been completely calculated too.
So how is RETURN_ADDR_RTX supposed to know whether the stack frame layout
code is going to decide to spill your link register if it doesn't have the
final value of regs_ever_live or anything else it would need to make that
kind of decision?
I've had a look at the rs6000 code, and what it does is that
RETURN_ADDR_RTX sets a flag that forces the epilog to emit a frame and spill
the link register to stack whether it was going to or not. I looked at the
mips port and it goes through some hairy gymnastics with an eliminable
pseudo hard reg that it pretends contains the return address. I looked at
various ports and they all had comments like "Fixme" and "This doesn't
really work properly in all cases". Frex the mips port fails in leaf
functions, according to a comment that doesn't explain why. I _think_ it's
because the port is attempting to use leaf_function_p to decide if the
return address is going to be held live in the link register throughout the
function or if there's a stack save slot for it, but then a leaf function
that nonetheless allocates the link register as a temporary will also save
it to stack, and RETURN_ADDR_RTX doesn't yet have that information from
Is there some better solution to this problem that I'm overlooking? The
rs6000 solution of setting a flag to force the epilog generator to save the
link register whether it thinks it needs to or not seems like the most
robust to me, and I guess it's only a very tiny pessimisation in only those
leaf functions that call __builtin_return_address, but it still seems
inelegant to me.
Can't think of a witty .sigline today....