[LLVMdev] Structs as first class values.

Tony Scudiero tscud at cray.com
Thu Jul 31 12:30:16 PDT 2008


I work with David Greene  and I've been looking into the x86-64 ABI.
Right now I'm working with the 2.3 release of LLVM and LLVM-GCC 4.2/2.3
(binary release for linux). I'm unable to replicate the results you
posted here - I'm getting wildly different output. I wonder what I'm
doing wrong. I suspect it has something to do with my not being able to
pass it the -m64 or --64 options, I get

"sorry, unimplemented: 64-bit mode not compiled in"

I want to make sure I'm using the same options and roughly the same
version to make sure I'm on the same page. I'm running on 64 bit SUSE
linux. Can you tell me what options to llvm-gcc you used and how you
built that llvm-gcc (i.e. do I need to build an llvm-gcc from source to
support 64bit mode?) Thanks!

    -Tony S.




Chris Lattner wrote:
> On Jul 23, 2008, at 9:05 AM, David Greene wrote:
>   
>>> In the case of X86-64, llvm-gcc does use aggregate return (for the
>>> interesting cases which return things in registers) and it does do  
>>> the
>>>       
>> I don't follow.  By "aggregate return" do you mean "structs as first  
>> class
>> values?"  That is, llvm-gcc generates a return of a struct by value?
>>     
>
> Yes, consider:
>
> struct foo { double X; long Y; };
> struct foo test(double *P1, long *P2) {
>    struct foo F;
>    F.X = *P1;
>    F.Y = *P2;
>    return F;
> }
>
> we compile this to:
>
> 	%struct.foo = type { double, i64 }
>
> define %struct.foo @test(double* %P1, i64* %P2) nounwind  {
> entry:
> 	load double* %P1, align 8		; <double>:0 [#uses=1]
> 	load i64* %P2, align 8		; <i64>:1 [#uses=1]
> 	%mrv3 = insertvalue %struct.foo undef, double %0, 0		; <%struct.foo>  
> [#uses=1]
> 	%mrv4 = insertvalue %struct.foo %mrv3, i64 %1, 1		; <%struct.foo>  
> [#uses=1]
> 	ret %struct.foo %mrv4
> }
>
> which was previously (before first class aggregates got enabled  
> yesterday):
>
> define %struct.foo @test(double* %P1, i64* %P2) nounwind  {
> entry:
> 	load double* %P1, align 8		; <double>:0 [#uses=1]
> 	load i64* %P2, align 8		; <i64>:1 [#uses=1]
> 	ret double %0, i64 %1
> }
>
> and both produce this machine code:
>
> _test:
> 	movq	(%rsi), %rax
> 	movsd	(%rdi), %xmm0
> 	ret
>
>   
>>> 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.
>
>   
>>> 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 :)
>
> -Chris 
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>   




More information about the llvm-dev mailing list