[LLVMdev] Proposing a new 'alloca' parameter attribute to implement the Microsoft C++ ABI

Reid Kleckner rnk at google.com
Mon Jul 29 07:52:06 PDT 2013


On Mon, Jul 29, 2013 at 10:45 AM, Duncan Sands <baldrick at free.fr> wrote:

> Hi Reid,
>
>
> On 29/07/13 16:36, Reid Kleckner wrote:
>
>> On Mon, Jul 29, 2013 at 9:40 AM, Duncan Sands <baldrick at free.fr
>> <mailto:baldrick at free.fr>> wrote:
>>
>>     On 29/07/13 15:30, Anton Korobeynikov wrote:
>>
>>                 object in place on the stack or at least call its copy
>> constructor.
>>
>>
>>
>>             what does GCC do?
>>
>>         Nothing. It does not support MSVC ABI.
>>
>>
>>     Maybe we shouldn't either :)  So the ABI requires the struct to be
>> pushed on the
>>     stack by the caller along with the other parameters, and what's more
>> it requires
>>     the caller to execute some code on that copy, in place on the stack,
>> before
>>     performing the call.  Is that right?
>>
>>
>> Just calling the copy ctor is the bare minimum needed to support the ABI.
>>   cl.exe uses a more efficient lowering that evaluates the arguments
>> right to
>> left directly into the outgoing argument stack slots.  It lowers
>> following call
>> to bar to something like:
>>
>> struct A {int x; int y;};
>> A foo();
>> void bar(int, A, int);
>> ...
>> bar(0xdead, foo(), 0xbeef);
>>
>> x86_32 pseudo intel asm:
>>
>> push 0xdead
>> sub esp, 8
>> push esp  # sret arg for foo
>> call foo
>> add esp, 4 # clear sret arg
>> push 0xbeef
>> call bar
>>
>
> I got confused by your example.  Is the struct passed on the stack,
> amongst the
> other parameters, or can it be allocated somewhere else and a pointer to it
> passed?  Because in your example it isn't clear to me how the return value
> of
> foo() is being passed to bar().
>

Yes, the struct is passed amongst the other parameters.  LLVM already
supports passing C structs this way using byval, but it emits a memcpy in
the backend, which breaks C++ objects.

foo() is returning an A struct via the usual hidden sret parameter.  The
"push esp" is taking the address of the struct's outgoing arg slot and
passing it to foo().
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130729/ce817775/attachment.html>


More information about the llvm-dev mailing list