This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] pdp11: Fix bad code for no frame pointer case
On Nov 19, 2010, at 12:33 PM, Richard Henderson wrote:
> On 11/18/2010 06:04 PM, Paul Koning wrote:
>> -#define FIRST_PARM_OFFSET(FNDECL) 4
>> +#define FIRST_PARM_OFFSET(FNDECL) ((frame_pointer_needed) ? 4 : 2)
>
> This is a sign of broken register elimination. This macro is used very early
> in the rtl optimization path -- virtual register instantiation. At that point,
> the final value of frame_pointer_needed has not been set.
>
> The position of ARG_POINTER_REGNUM needs to be completely above the local stack
> frame in order to properly address the arguments. So either you need to position
> FRAME_POINTER_REGNUM at the top of the frame, or you need to create a "soft"
> ARG_POINTER_REGNUM that is always eliminated to either the FRAME_POINTER_REGNUM
> or to STACK_POINTER_REGNUM.
>
> Quite often, ports also create a "soft" FRAME_POINTER_REGNUM, which is always
> eliminated to HARD_FRAME_POINTER_REGNUM. The soft frame pointer will always
> point to the area for the local variables, whereas the hard frame pointer is
> somewhere else, generally within the area for the saved registers.
>
> For instance, for i386:
>
> void f(int a, int b)
> {
> int x[10];
> int y[a];
> g(a, x, y);
> }
>
>
> b
> a
> --------------- arg_pointer
> return addr
> save ebp
> --------------- hard_frame_pointer
> save ebx
> save esi
> save edi
> --------------- frame_pointer
> x[10] (local variable area)
> ---------------
> y[a] (alloca area)
> ---------------
> &y
> &x (outgoing arguments)
> a
> --------------- stack_pointer
>
> Before register allocation, the fixed positions that we have are
> arg_pointer, frame_pointer, and stack_pointer (for outgoing arguments).
>
> During register allocation, the ELIMINABLE_REGS, TARGET_CAN_ELIMINATE
> and INITIAL_ELIMINATION_OFFSET macros determine which eliminations are
> possible, and what offsets to apply when doing so.
>
> The pieces of information needed in order to compute these offsets are
>
> (1) whether frame pointer is required (frame_pointer_needed),
> (2) the size of the register save area (some cpu.c function),
> (3) the size of the local stack frame (get_frame_size ()),
> (4) the size of the outgoing arguments (ctrl->outgoing_args_size).
>
> Exactly how you apply these depends on exactly how you lay out the
> entire local stack frame.
That's helpful. I noticed that this "fix" helps some cases and breaks others, depending on whether a frame pointer appears or not. I'll dig into i386 and those other macros to make this right.
paul