[llvm-commits] [llvm-gcc-4.2] r86892 - /llvm-gcc-4.2/trunk/gcc/llvm-abi.h

Dale Johannesen dalej at apple.com
Thu Dec 10 16:15:52 PST 2009


On Dec 10, 2009, at 3:19 PMPST, Rafael Espindola wrote:

> 2009/12/2 Rafael Espindola <espindola at google.com>:
>>> I'm hoping Dale will weigh in on this soon, but I'm tentatively  
>>> planning to add the byval support as soon as I get a chance (which  
>>> may be a while).

All right, I'm back from vacation now.

>> I have a small preference for expanding it early, but if most prefer
>> the byval solution I can give it a try. Not the highest priority item
>> for me right now, but might be able to help.
>
> Attached is a patch that makes llvm-gcc produce

> void @f(i32)
> and
> void @g(i32, i32, i32, i32, i16, i8)
>
> When given
>
> -----------------
> struct foo {
> char[3] a;
> };
>
> void f(struct foo x);
> void g(int a, int b, int c, int d, struct foo x);

I think it's a bad idea to try to do this in target-independent code.   
Whether the information goes in the high part or the low part of the  
register is target-dependent (there's some correlation with  
endianness), and just which structs need special treatment is also  
target-dependent.  I think there's even a target where
   struct { char[3] a;}
and
   struct { short a; char b; }
are passed differently.

I think most existing targets use byval, so I'd use that; there's lots  
of prior art to copy.

> ----------------------
>
> It is obviously wrong in that that it has the number of argument
> registers hardcoded. What is the best place to get that information in
> llvm-gcc? What gcc does is handle this in a target dependent location.
> I could also just add a #define to the different configs headers.
> arm.h already has a NUM_ARG_REGS...
>
> I think I would need the same information to implement the byval
> alternative. byval is normally used for things copied on the stack, so
> for function f above we would have to know that the struct would go in
> registers.  In more complicated cases we have to split the structure.
>
> I will try to figure out how to run the testsuite with qemu this  
> weekend.
>
> In a more long term note, I find the way we handle stacks very hard to
> understand :-(
>
> In the current way llvm-gcc is reverse engineering what llvm will do.
> It knows what will be in each register and the stack layout. It uses
> that information to map it to a llvm function signature that will be
> expanded again by the code generator.  This is particularly bad for
> x86 that uses both byval and first class aggregates.
>
> What I would propose is making the argument placement explicit at the
> LLVM IL level. A case like
>
> struct foo {char a[5];};
> void f(int a, int b, int c, foo d);
>
> would compile to
> %struct.f_stack_args = { i8 }
> declare arm_explicit void @f(i32, i32, i32, i32, %struct.f_stack_args)
>
> And a function like
>
> void g(void) {
>  struct foo x = {5, 6, 7, 8, 9};
>  f(1, 2, 3, x);
> }
>
> would be compiled to
>
> define arm_explicit void @g() nounwind {
> entry:
>  tail call arm_explicit  void @g(i32 1, i32 2, i32 3, i32 134678021,
> {i8 9}) nounwind
>  ret void
> }
>
> In this way almost all the lowering would be done in llvm-gcc/clang
> (preferably in a shared library). The backend would be a lot simpler
> since now every function would have at most 4 i32 args corresponding
> to each register and an argument representing the memory layout of the
> remaining C arguments.
>
> One thing I am not sure is where to put things like nocapture.
>
> Cheers,
> -- 
> Rafael Ávila de Espíndola
-------------- next part --------------
A non-text attachment was scrubbed...
Name: arm.patch
Type: text/x-patch
Size: 1763 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20091210/a67c350d/attachment.bin>
-------------- next part --------------



More information about the llvm-commits mailing list