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

Bob Wilson bob.wilson at apple.com
Fri Dec 11 10:10:32 PST 2009


On Dec 11, 2009, at 9:50 AM, Rafael Espindola wrote:

>> I don't think I get your point.  The expansion of that may be target-specific.  E.G., x86 passes "d" using "byval", but x86-64 expands it to an i64.
> 
> My point is that I see two reasonable ways to expand this for ARM
> given the current infrastructure:
> 
> declare arm_aapcscc void @f(i32, i32, i32, i32, i8)
> 
> or
> 
> %struct.foo_part = type { i8 }
> declare arm_aapcscc void @f(i32, i32, i32, i32, %struct.foo_part* byval)
> 
> For both cases I need to know in *llvm-gcc* when to stop using
> registers and switch to memory.

You could try to get the target hooks in llvm-gcc to know when to stop using registers, or you can just look at the type and decide to always use "byval" for that type.  The latter is simpler and cleaner, although probably less efficient.

> 
> If I understand you, you are proposing that this should be expanded to
> 
> %struct.foo = type { [5 x i8] }
> declare arm_aapcscc void @f(i32, i32, i32, %struct.foo_part* byval)
> 
> And get the codegen to split the last argument in part register part
> stack. Is that your proposal?

Yes.  That is how other targets handle this sort of thing.

> 
>> 
>>> 
>>> Byval was created to force something to the stack
>>> (http://llvm.org/bugs/show_bug.cgi?id=1521). In this case the first 4
>>> bytes have to go in a register. The last byte goes to the stack. I can
>>> use byval, but only for the last byte. I still need to know when the
>>> registers are over so that I can split the structure at that point.
>> 
>> Byval does not force things to the stack.  From the llvm IR perspective, byval arguments look like they are passed in memory, but the codegen needs to understand the target ABI and figure out how to pass them.  The values (or portions of values) that are actually passed in registers are then copied into memory.  There are some performance problems with this, and it's certainly not pretty, but we should fix the ARM ABI issues before trying to redesign the way llvm handles argument passing.
> 
> byval looks like a pointer to everything in llvm. Using it for
> something that will not have an address at all is very confusing. Do
> we actually do it in some current architecture? Do you have an example
> of a byval argument being passed in registers?

byval arguments are always copied to memory, so they do have addresses, but they may be passed in registers.  Look at PPCISelLowering's LowerFormalArguments_Darwin, for example.

For pr5406, we use byval on all the other major supported architectures except ARM.  We should fix ARM first to use the approach that we know works.  After that, if you want to initiate a project to find a more elegant solution, that would be fantastic.  It is pretty horrible that we essentially require all targets to implement byval to get compatibility with any sane ABI.

> 
> For example, in x86-64 something like
> 
> %struct.s = type { i64 }
> define i64 @f(%struct.s* byval %a)
> 
> gets passed on the stack. It would be passed in registers on arm with
> your proposal.
> 
> I also want to fix this bug first and try to improve things afterward.
> The first option (using a final i8) looks the easiest to implement
> right now. Would it be OK with you if I finish implementing that
> first?

I don't think that's the right way to go.





More information about the llvm-commits mailing list