[llvm-commits] [llvm-gcc-4.2] r86892 - /llvm-gcc-4.2/trunk/gcc/llvm-abi.h
Rafael Espindola
espindola at google.com
Thu Dec 10 15:19:10 PST 2009
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).
>
> 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);
----------------------
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/d6f4068f/attachment.bin>
More information about the llvm-commits
mailing list