[LLVMdev] First-class aggregate semantics

Dustin Laurence dllaurence at dslextreme.com
Thu Jan 7 13:56:11 PST 2010

On 01/07/2010 01:38 PM, David Greene wrote:

> The way this works on many targets is that the caller allocates stack
> space in its frame for the returned struct and passes a pointer to it
> as a first "hidden" argument to the callee.  The callee then copies
> that data into the space pointed to by the address.


> Long-term, first-class status means that returns of structs should
> "just work" and you don't need to worry about getting a pointer to
> invalid memory.

OK, so my thought of constructing the object on the stack was correct?
What I originally wanted to do was roughly

    %Token = type {%c_int, %i8*}

    define %Token @foo()

        ret %Token {%c_int %token, %i8* %value}

but the compiler complains about the invalid usage of a local name.  So
I decided the problem was that I was thinking in terms of languages that
would create a temporary implicitly, and in IR I need to do it
explicitly.  So it occurred to me to create the struct on the stack, as
I mentioned.

What bothers me about that is the explicit specification with alloca
that the space is reserved in the callee's frame.  Do I just trust the
optimizer to eliminate that and turn the reference to alloca'd memory
into a reference to the space reserved by the caller?  Or is that going
to create an unnecessary copy from the alloca'd memory to that reserved
by the caller?  From what you said my guess is the former (optimizer
eliminates the pointless temporary), but us premature optimizers like to
be reassured we haven't given up an all-important microsecond. :-)

> ...I believe right now, however, only structs up to a
> certain size are supported, perhaps because under some ABIs, small
> structs can be returned in registers and one doesn't need to worry
> about generating the hidden argument.

In the case that prompted the question the struct isn't going to be
bigger than two of whatever the architecture regards as a word, which
surely should be fine, but in principle shouldn't LLVM and not the
front-end programmer be making the decision about whether the struct is
big enough to spill into memory?


More information about the llvm-dev mailing list