Thanks Ian,

On Mon, Jan 28, 2013 at 4:32 PM, Ian Lance Taylor <i...@google.com> wrote:
> On Sat, Jan 26, 2013 at 5:44 PM, Matt Davis <mattdav...@gmail.com> wrote:
>> This question is similar to my last; however, I think it provides a
>> bit more clarity as to how I am obtaining offsets from the frame
>> pointer.  I have an RTL pass that is processed after expand passes.  I
>> keep track of a list of stack allocated variables.  For each VAR_DECL,
>> I obtain the DECL_RTL rtx.  Since these variables are local, the RTL
>> expression reflects an offset from the stack frame pointer.  For
>> instance, the variable 'matt':
>>
>> (mem/f/c:DI (plus:DI (reg/f:DI 20 frame)
>>         (const_int -8 [0xfffffffffffffff8])) [0 matt+0 S8 A64])
>>
>> I interpret this as being -8 bytes away from the frame pointer, when
>> the function 'matt' has scope in is executing.  Since 'matt' is a
>> pointer, and the stack grows downward (x86), and this is a 64-bit
>> machine, the contents of 'matt' end at the frame pointer and span 8
>> bytes below the frame pointer to where the first byte of 'matt'
>> begins.  This is fine in some cases, but if I were to rewrite the
>> source and add a few more variables.  It seems that there might be a
>> few words of padding before the data for the first variable from the
>> stack pointer begins.  If I were to add a 4 byte integer to this
>> function, 'matt' would still be declared in RTL as above, but instead
>> of really being -8 it is actually -32.  Where do the 24 bytes of
>> padding between the frame pointer and the last byte of 'matt' come
>> from?   Further, how can I find this initial padding offset at compile
>> time?  I originally thought that the offset in the rtx, as above,
>> would reflect this stack realignment, but it appears not to.
>
> The frame pointer in RTL is a notional frame pointer.  It need not
> correspond to any actual hardware register.  In fact most processors
> distinguish the soft frame pointer from the hard frame pointer, and
> most permit eliminating the frame pointer entirely and just using the
> stack pointer.
>
> I'm not sure how to answer the rest of your paragraph because I'm not
> sure which frame pointer you are talking about.  E.g., which one do
> you mean when you mention -32?  If you are talking about x86_64 then I
> guess you are seeing the fact that the stack must be aligned according
> to -mpreferred-stack-boundary, which defaults to a 16 byte boundary.

To clarify, the RTL tells me that the frame pointer is -8 bytes from
the notional RTL frame pointer.  The -32 is the actual distance from
the the hardware register at runtime on my x86_64.  Actually, looking
at my test now, the RTL tells me that the 'matt' pointer -8 bytes from
RTL's notional frame pointer, and the next integer stack variable 'x'
is -12 away.  At runtime 'matt' is in fact -24 bytes away and 'x' is
-28.  So there are two words between the actual hardware frame pointer
and the data for the first  local on the stack. So my hunch was right,
it does seem to be an effect of stack alignment.  If I were to look at
the final RTL dump, I do not see an -8 as what the VAR_DECL's RTL data
told me, but I do see in the final RTL dump the -24, which is what I
expect:

(insn 5 2 6 4 (set (mem/f/c:DI (plus:DI (reg/f:DI 6 bp)
                (const_int -24 [0xffffffffffffffe8])) [0 matt+0 S8 A64])
        (const_int 0 [0])) test.go:4 62 {*movdi_internal_rex64}
     (nil))

It seems that I have made a bad assumption; that the notional RTL soft
frame pointer represents the stack alignment.  Anyways, I'm  hoping
that there is a way, during my RTL pass using just the VAR_DECL, that
I can determine where the local is from the frame pointer.  I just
need to figure out how the RTL block just above is calculated, and use
that offset in my RTL pass instead of the data in VAR_DECL's RTL node.

Thanks again Ian for your reply.


-Matt

Reply via email to