[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