Description: Currently, every LLVM-based frontend that wants to support calling into C code (FFI) needs to re-implement a substantial amount of complex call ABI handling. The goal of this project is to introduce an LLVM ABI library, which can be reused across different frontends, including Clang. More details on the motivation and a broad outline of the design are available in this RFC:
The initial phase of the project will be to implement a prototype that can handle at least the x86_64 System V ABI. This will involve implementing the ABI type system, mapping of Clang types to ABI types and moving at least part of the X86 ABIInfo implementation from Clang to the new ABI library. This is to demonstrate general feasibility, figure out design questions and analyze compilation-time impact.
Assuming the results from the prototype are positive, the next step would be to upstream the implementation by splitting it into smaller PRs. Finally, the implementation can be expanded to cover additional targets, ultimately removing Clang’s ABI handling code entirely.
Expected results: The minimum result is a prototype for the x86_64 ABI. The maximum result is fully upstreamed support for all targets. The expected result is somewhere in the middle between those two.
Desirable skills: Intermediate C++. Some familiarity with LLVM is a plus, but not required.
I am really interested in this, especially that my work has involved a lot of delving with assembly and ABI, mostly ARM.
Are there things that you recommend me to read up or experiment with to prepare for this?
Hi @nikic,
I am interested in this project, I have nice experience in LLVM as you know. I added nsw and nuw flags to the trunc instruction and I also added the samesign flag to the icmp instruction, and some accepted PR in the instcombine pass. I started researching this. I hope I spend this summer working on this.
Hello @nikic! I’m interested in this project and have a few questions to better prepare my design proposal:
The existing (but incomplete and appears to be abandoned) llvm-abi project has an implementation for x86_64, but it maps to LLVM IR types directly. Would this be a good starting point to get a feel of what the expected prototype should look like?
I’ve done a bit of skimming over Clang, and can see that a lot of work such as ABI implementation details has been done already, and that a lot of this can be simply lifted and put in the new library. Is this assumption true or at least sensible? I would also like to ask for a direction on where exactly all of this stuff gets used when Clang makes decisions during emission of e.g a function call so I can study that further.
I’m looking forward to working with you to iron out more details during the application period, and hope to be selected for the summer!
Woah! I am really interested in this project. I was recently reading up about Swift’s C interop and came across this very problem. The success of this project would indeed offload much of the FFI duties to LLVM. About me: I’m a computer science major who majorly writes low-level/hardware level projects. I’m an occasional contributor to LLVM and have read most of the Transforms codebase. I’ve also contributed to InstCombine and ValueTracking in the past. Looking forward to interacting with you all!
The FunctionIRMapping part lowers from the ABI information to LLVM IR. Having something like this is not strictly required, though it’s probably a nice utility for simpler users. (I expect that the major consumers will want to do the LLVM IR lowering themselves, they just need the ABI information.)
I haven’t looked particularly deeply into this library, but yes, I expect it’s close to the goal here, at least in terms of high level concepts, if not implementation details.
Yes, Clang already implements everything that is necessary. This projects is basically “just” extracting the current Clang code into a separate library. Of course, this is a lot harder than it sounds, because the implementation in Clang is tightly coupled to other parts of Clang, most importantly the Clang AST type system.
To provide some code references for how Clang currently handles this:
Clang AST Types: We’ll need our own type system representation, which will hopefully be much simpler than than this.
ABIInfo is the interface implemented by individual targets and ABIArgInfo + CGFunctionInfo is the result returned by it. The ABI library will want to return something similar.
CodeGen/Targets includes the implementations for the different targets. Key methods to look at are computeInfo, classifyArgumentType and classifyReturnType. For example, X86_64ABIInfo::computeInfo is the main entry point for the x86_64 SysV ABI.
CGCall implements the actual lowering to LLVM IR based on the ABI information. See for example EmitCall.
It may also be interesting to look at some ABI documents to get a picture of the kind of rules involved here. For example: