[cfe-dev] Direct Argument Passing in Clang

Reid Kleckner rnk at google.com
Tue Sep 2 12:52:41 PDT 2014


The comment in CGCall was accurate when it was written. All backends used
to handle first-class LLVM aggregates (FCA) by passing the constituent
elements separately. That was never written down as a rule, so the
situation has evolved.

I believe ARM now does something different for homogenous floating point
aggregates (HFAs). It's still the case that if you pass an LLVM FCA, LLVM
is allowed to take it apart and put it back together again, without
preserving any padding bytes.

Depending on what you want, there are three things you can do:

1. Use ABIArgInfo::getDirect() and set CanBeFlattened to false. This is
probably the easiest, but most LLVM optimizations don't handle FCAs very
well. ARM does this for HFAs.

2. Use getIndirect(/*ByVal=*/true) to pass the argument on the stack in
memory with exactly the specified layout. There will be a bytewise copy. Do
this if you want the argument in memory (never in registers) and you care
about the struct layout.

3. Implement custom expansion logic from the struct type to constituent
member types. This is pretty much your only option if you want to pass
unions in registers. This is what x86_64 SysV does for example. In the
worst case, you can basically take a struct and split it up into
pointer-sized ints, pass those, and reconstitute the struct on the other
side.


On Thu, Aug 28, 2014 at 3:01 PM, Morgan, Zachary <z-morgan at ti.com> wrote:

>  I am in the process of adding a new ABI Info to
> lib/CodeGen/TargetInfo.cpp.  When classifying arguments passing
> conventions, for small structs, we want to pass directly.  That is, in
> classifyArgumentType(), we return ABIArgInfo::getDirect() in these cases.
> However, I noticed that the structure is then passed by its members
> individually.  So where I would expect a call of the form:
>
>
>
>     foo(struct s)
>
>
>
> I instead find
>
>
>
>     foo(member1, member2, …)
>
>
>
> This change in calling convention occurs in lib/CodeGen/CGCall.cpp – in
> each case near a comment stating that “If the coerce-to type is a first
> class aggregate, we flatten it” and further asserting that either way is
> semantically identical.  I would presume this can only be true only if
> padding of structures is equivalent to padding and promotions of values on
> the stack.  The test case I am looking at contains the use of the following
> as a parameter:
>
>
>
> typedef struct S
>
> {
>
>     char a;
>
>     char b;
>
>     char c;
>
> } S;
>
>
>
> As a whole, the struct will fit within at least 32 bits on the stack.
> When the members are separated, due to promotions, the struct will take up
> 3 * sizeof(int) on the stack.
>
>
>
> I’m fairly certain that what I want to do is pass the arguments directly
> as stated above, but I wanted to check and see if there is a more preferred
> way for handling this.
>
>
>
> Thanks,
>
> Zachary Morgan
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20140902/a4844778/attachment.html>


More information about the cfe-dev mailing list