[LLVMdev] First-class aggregate semantics

Kenneth Uildriks kennethuil at gmail.com
Fri Jan 8 14:05:21 PST 2010

On Fri, Jan 8, 2010 at 12:24 AM, Duncan Sands <baldrick at free.fr> wrote:
> Hi Dustin,
>> I think I'm missing something basic about the semantics of returning an
>> aggregate type (in my case, a structure) from a function.  Returning a
>> structure containing only compile-time constants is simple enough.  But
>> I don't quite get how this works with a struct composed at run-time.  If
>> I constructed it on the stack with alloca, would I be letting a stack
>> variable escape to to a context where it doesn't exist if I return it?
> first class aggregates are basically implemented by sticking the value of each
> struct field in a register.  For example, returning a struct with two i32
> fields amounts to placing each of the fields in a machine register (eg: EAX,
> ECX) then returning from the function.  The caller gets hold of the values
> by reading EAX and ECX.  Note that it doesn't return a pointer to the struct,
> it returns the value of the struct.  Suppose you have stored the struct in
> an alloca.  Then to get it as a first class aggregate, you first need to do
> a load of the alloca (this results in an LLVM register of aggregate type,
> equivalent to two machine registers of type i32), then return the loaded value.
> At the machine code level, this corresponds to loading the first field from
> the stack into EAX, loading the second field from the stack into EDX then
> returning.
>> Or does the return semantics guarantee it will be copied (or space
>> allocated in the caller) appropriately?  Otherwise I should abandon the
>> idea of returning such a struct and simply pass in a pointer to space
>> allocated in the caller.
> If the struct is so big that there aren't enough machine registers available
> to return it, then the code generator will automagically allocate some stack
> space in the caller, pass a pointer to it into the called function, and have
> the callee return the struct by copying it into the passed stack space [*].

There are small target hooks that need to be implemented for each
target to get this to work.  As far as I know, the only hook
implemented was for x86.

More information about the llvm-dev mailing list