[LLVMdev] PSA: Perfectly forwarding thunks can now be expressed in LLVM IR with musttail and varargs

Reid Kleckner rnk at google.com
Thu Oct 9 11:02:26 PDT 2014


On Thu, Oct 9, 2014 at 1:51 AM, David Chisnall <David.Chisnall at cl.cam.ac.uk>
wrote:

> On 8 Oct 2014, at 18:19, Reid Kleckner <rnk at google.com> wrote:
>
> > The one target I know about where varargs are passed differently from
> normal arguments is aarch64-apple-ios/macosx. After thinking a bit more, I
> think this forwarding thunk representation works fine even on that target.
> Typically a forwarding thunk is called indirectly, or at least through a
> bitcast, so the LLVM IR call site would look like:
>
> MIPS also has some subtle (and annoying) differences between variadic and
> non-variadic function calls.  Most notably (o32-only) that the stack
> pointer will be in a different place in the callee for variadic and
> non-variadic calls.
>
> The variadic calling convention that we're using for our extension
> currently requires all variadic arguments to be spilled to the stack (we
> found this actually improves performance very slightly, as most things that
> use variadic functions call a function that takes a va_list argument and
> you can construct the va_list by just saving the stack pointer, but we did
> it for correctness and simplicity originally).
>
> Implementing perfect forwarding would require that the caller calls the
> thunk with the non-variadic calling convention and that the thunk is aware
> that it must (potentially) preserve some more registers.  In particular, it
> mustn't touch any of the argument registers for the specified calling
> convention, unless explicitly modifying those arguments.
>

This sounds similar to the aarch64 case. We just need to copy all
unconsumed physical register parameters to virtual registers in the
prologue, and copy them back into physical registers before a variadic
musttail call.

As long as the thunk does not intend to read and modify arguments in the
va_list, this approach should work. It just means we'll preserve more
registers than we need to if the thunk target is actually a variadic
function.

Again, my use case is C++ adjustor thunks, where the 'this' parameter is
always "prototyped" and never part of the va_list.

----

As an aside, the Windows x64 calling convention has an interesting solution
to this problem. They require the caller to allocate stack space for all
the register parameters that might be passed. If it turns out that the
callee is variadic, it can simply spill the register parameters in order to
the stack and use a simple char * for the va_list type. It has the downside
that vectors cannot be passed directly in xmm registers, because a vector
argument is bigger than the normal 8-byte register parameter stack slot,
hence the recent addition of __vectorcall.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20141009/1b735dc0/attachment.html>


More information about the llvm-dev mailing list