[LLVMdev] Accessing arguments in a caller

Carlo Alberto Ferraris cafxx at strayorange.com
Mon Aug 22 13:48:50 PDT 2011


Il 22/08/2011 12:26, Duncan Sands ha scritto:
> Hi Carlo,
>
>> Nella citazione lunedì 22 agosto 2011 11:53:29, Duncan Sands ha scritto:
>>> Hi Carlo, rather than declaring individual stack variables
>>> int x;
>>> int y;
>>> int z;
>>> and so on, which requires you to pass each one, or a pointer to each one,
>>> to your function, declare one stack variable of struct type that holds
>>> them all:
>>> struct StackObjects {
>>> int x;
>>> int y;
>>> int z;
>>> ...
>>> };
>>> ...
>>> struct StackObjects stack;
>>> then pass the address of stack to your function, enabling it to access all
>>> of the objects on the callers stack. This way you only need to copy a single
>>> pointer. This is what GCC's nested function implementation does for example to
>>> enable child functions to access variables on the parent's stack.
>> Hi Duncan,
>> this is what I'm already doing (see
>> http://stackoverflow.com/questions/7144733/argument-forwarding-in-llvm, the code
>> I posted is in pseudo-C but I'm actually working on LLVM-IR in my pass) but this in
>> curs the boxing-unboxing penalty and I was wondering if there is a way to avoid it.
> I didn't read your question carefully enough: I thought you were talking about
> accessing stack variables declared by the parent (in which case there is no cost
> to using the above technique), but in fact you were talking about accessing the
> parent's arguments.  Probably the best you can do is store a pointer to each
> argument in a stack struct object (like above), then pass a pointer to that
> object.  The setup cost is then one pointer store per argument, plus one pointer
> copy (passing the stack object to the callee).  The cost of accessing is one
> pointer dereference per argument.  I'm pretty sure this is what GCC does when
> a nested function wants to access one of its parent's arguments.
>
I see. Just wondering: what if I were to construct F as a function with 
a number of parameters high enough to be able to accept any combination 
of parameters of the other functions? Something like:

void A(int, float, float)
void B(float, struct S)

--> void fastcc F(int, float, float, struct S)

and then calling F with undefs for the unused parameters:

void A(int a, float b, float c) {
   F(a, b, c, undef);
}

void B(float a, struct S b) {
   F(undef, a, undef, b);
}

are the backends able to efficiently handle functions with many 
arguments (the majority of which would be undefs)? could this work?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20110822/531e9c5d/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: cafxx.vcf
Type: text/x-vcard
Size: 230 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20110822/531e9c5d/attachment.vcf>


More information about the llvm-dev mailing list