Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

Share code for generating ABI conformant function calls/returns #4735

Open Quuxplusone opened 15 years ago

Quuxplusone commented 15 years ago
Bugzilla Link PR4246
Status NEW
Importance P normal
Reported by Duncan Sands (baldrick@free.fr)
Reported on 2009-05-22 12:47:12 -0700
Last modified on 2011-06-12 15:56:24 -0700
Version unspecified
Hardware All All
CC bob.wilson@apple.com, clattner@nondot.org, daniel@zuster.org, Dr.Graef@t-online.de, efriedma@quicinc.com, fvbommel@gmail.com, geek4civic@gmail.com, llvm-bugs@lists.llvm.org, nobled@dreamwidth.org, sreeram@tachyontech.net
Fixed by commit(s)
Attachments
Blocks
Blocked by
See also
For platforms like x86-64, getting ABI conformance right is hard.
There is one implementation in llvm-gcc, and another in clang.
Currently, anyone writing a compiler and wanting to be able to
interface with external C functions needs to roll their own
implementation.  We should consider developing a generic solution
that can be used by llvm-gcc, clang and other projects.
Quuxplusone commented 15 years ago
This is a totally crazy idea, but it might just work. :)

To expand a little more, this is what I think the proposal is:

Front-end compilers are expected to define a mapping of their type information
onto the C[++?] type system, and provide an interface for the ABI code to have
access to that type information. This must include everything the ABI could
care about:
 1. Types: structs, unions, arrays, Complex, vectors, extended vectors (Clang).
 2. Alignment and padding.
 3. [Unnamed] bit-fields.
 4. etc.

The generic ABI code then computes how a function type should be lowered to
LLVM, and the front-end uses that result (which is an intermediate data
structure) to convert its type to LLVM.

It would be relatively straightforward to prototype this in clang, although it
would be worth polishing our ABI support and adding another target before we
undertook this.
Quuxplusone commented 15 years ago

I should add: vaarg handling is a serious wrench in the works. I can see how the generic ABI code could return information about how to pass the type, but returning information about how to implement vaarg is much more difficult (I think).

Quuxplusone commented 15 years ago
Can't you just make the va_arg instruction and llvm.va_* intrinsics actually
work? :)

(If those work, the only thing vaarg-related the ABI needs to be concerned
about is the va_list type, which could just be returned from a query method...)
Quuxplusone commented 15 years ago

It isn't that simple, the vaarg instructions are currently powerful enough to do the right thing. For them to even be able to work correctly, the backend needs to know how the type would have been passed, and the LLVM type alone is not sufficient to encode this.

Quuxplusone commented 15 years ago

The solution for va_arg seems easy: just provide a method (or a set of methods; not sure what'll be easier) on the ABI class to generate a call to va_arg. We do that right now in CGCall in clang... is there some reason why that won't work here?

Quuxplusone commented 15 years ago

No, you are probably right that that is good enough.

It depends on how generic we need it to be if it is to be reused by llvm-gcc/ldc/whatever. For arguments passing, the interface could conceivably be generic enough that it doesn't need to create LLVM instructions.

For va_arg handling, the current interface we rely on in clang assumes that the ABI code can generate LLVM instructions, which means we need to pass a module/function/basicblock/irbuilder into the generic ABI handling code.

p.s. Comment #4, s/are/are not/.

Quuxplusone commented 15 years ago

I think it's reasonable to assume all the users are generating LLVM IR; if they weren't, they wouldn't be using LLVM in the first place :)

Quuxplusone commented 15 years ago
A truly generic solution that doesn't assume you are targeting LLVM would
be a neat thing to have.  If it can be done at no cost, we might as well
do it that way.  However it's important not to try to be all things to
all men, so if it's simpler to target LLVM then I'm all for it.
Quuxplusone commented 15 years ago

It seems that the first step would be to refactor the clang call lowering stuff so that it lives in libbasic instead of libcodegen. If that could be done, it would be "obviously" independent of both the clang ASTs and LLVM IR.

The way to do this is probably to add a callback-based virtual interface for getting information about opaque ASTs. A front-end that used this API would then have to implement the virtual interface, saying "this type is a complex float", etc

Quuxplusone commented 15 years ago
(In reply to comment #9)
> The way to do this is probably to add a callback-based virtual interface for
> getting information about opaque ASTs.  A front-end that used this API would
> then have to implement the virtual interface, saying "this type is a complex
> float", etc

That sounds messy; my first instinct is something more like an array of tagged
unions to communicate a type.