[LLVMdev] Structs as first class values.

David Greene dag at cray.com
Wed Jul 23 11:57:01 PDT 2008


On Wednesday 23 July 2008 12:22, Chris Lattner wrote:

> and both produce this machine code:
>
> _test:
> 	movq	(%rsi), %rax
> 	movsd	(%rdi), %xmm0
> 	ret

Ok, that's good.

> >> right thing.  However, returning a {i64, i64, i64, i64} by value and
> >> having it automatically be returned "by pointer" is less interesting,
> >
> > What do you mean by "less interesting?"
>
> There are already other ways to handle this, rather than returning the
> entire aggregate by value.  For example, we compile:
>
> struct foo { double X; long Y, Z; };
> struct foo test(double *P1, long *P2) {
>    struct foo F;
>    F.X = *P1;
>    F.Y = *P2;
>    return F;
> }
>
> into:
>
> 	%struct.foo = type { double, i64, i64 }
> define void @test(%struct.foo* noalias sret  %agg.result, double* %P1,
> i64* %P2) nounwind  {
> entry:
> 	load double* %P1, align 8		; <double>:0 [#uses=1]
> 	load i64* %P2, align 8		; <i64>:1 [#uses=1]
> 	getelementptr %struct.foo* %agg.result, i32 0, i32 0		; <double*>:2
> [#uses=1]
> 	store double %0, double* %2, align 8
> 	getelementptr %struct.foo* %agg.result, i32 0, i32 1		; <i64*>:3
> [#uses=1]
> 	store i64 %1, i64* %3, align 8
> 	ret void
> }
>
> which has no first class aggregates.  When the struct is very large
> (e.g. containing an array) you REALLY REALLY do not want to use first-
> class aggregate return, you want to return explicitly by pointer so
> the memcpy is explicit in the IR.

Ok, I see what you mean.  llvm-gcc does the transformation to the hidden
pointer argument.

I'm still not sure this is good.  If I hand-write LLVM IR that returns a large 
struct by value, the generated code should be correct.  It's not right
now AFAIK.  If you want to make the memcpy explicit, we could do the
l;owering in a separate pass.  That's fine with me, as long as it's
handled by LLVM so it produces correct code.

> >> AFAIK, llvm-gcc/g++ does an *extremely* good job of matching the
> >> X86-64 ABI on mainline.
> >
> > But that's all implemented within llvm-gcc.  LLVM codegen right now
> > does not implement the ABI correctly.
>
> Getting the ABI right requires the front-end to do target-specific
> work.  Without exposing the entire C (and every other language) type
> through to the code generator, there is no good solution for this.  We
> are working to incrementally improve things though.  Thinking the code
> generator will just magically handle all your ABI issues for you is
> wishful thinking :)

I never said anything about magic.  You don't need "the entire C (and every 
other language) type."  What you need is something that tells the code
generator what ABI to use and possibly what the source language was.
It should be possible to then define how each LLVM IR type maps onto the ABI.

                                                        -Dave



More information about the llvm-dev mailing list