[llvm-dev] RFC: Adding argument allocas

Reid Kleckner via llvm-dev llvm-dev at lists.llvm.org
Mon Dec 12 13:56:47 PST 2016


On Fri, Dec 9, 2016 at 4:04 PM, James Y Knight <jyknight at google.com> wrote:

> IMO, the LLVM function definitions should be a straightforward
> transformation from the C function signatures, and clang should stop
> mangling the function signatures with its own intimate knowledge of the
> calling convention rules.
>
> Instead, clang could emit (still ABI-specific!) annotations on the
> arguments that communicates the *properties* of the source-language types
> which affect the ABI. LLVM, then, would use that information to implement
> the complete calling convention. No counting of numbers of registers in
> Clang to put "inreg" markers in the right places, or byval, or any of that
> sort of stuff it has to do today.
>

Clang's ABI lowering is part of why I don't want to pattern match
alloca+store in LLVM. Today here is how we pass 'struct P { double x, y; }'
on x86_64-linux:

define void @f(double %p.coerce0, double %p.coerce1) #0 {
entry:
  %p = alloca %struct.P, align 8
  %0 = bitcast %struct.P* %p to { double, double }*
  %1 = getelementptr inbounds { double, double }, { double, double }* %0,
i32 0, i32 0
  store double %p.coerce0, double* %1, align 8
  %2 = getelementptr inbounds { double, double }, { double, double }* %0,
i32 0, i32 1
  store double %p.coerce1, double* %2, align 8
  ret void
}

My proposal doesn't make this any better so long as we split these things
in the frontend, so let's assume we go the direction you propose, so that
we receive just one %struct.P value. I'm pretty sure full FCA stores are
non-canonical, so after optimizations, this is what we'd have to pattern
match in the backend:

define void @f(%struct.P %p) #0 {
  %p.addr = alloca %struct.P, align 8
  %x.addr = getelementptr inbounds %struct.P, %struct.P* %0, i32 0, i32 0
  %x = extractvalue %struct.P %p, 0
  store double %x, double* %x.addr, align 8
  %y.addr = getelementptr inbounds %struct.P, %struct.P* %0, i32 0, i32 1
  %y = extractvalue %struct.P %p, 1
  store double %y, double* %y.addr, align 8
  ret void
}

This is doable, but I don't like it.

It's not clear if we have consensus to stop splitting structs in clang, but
that is the direction I'd like to go in the future. It would also be a bit
of a bitcode ABI break, similar to the way the byval change.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20161212/01d44094/attachment.html>


More information about the llvm-dev mailing list