Manuel Jacob via llvm-dev
2019-Jan-15 21:56 UTC
[llvm-dev] [RFC] Introducing an explicit calling convention
[+CC Kai Nacke, who I remember talking about this topic at a FOSDEM 2014 talk] On 2019-01-15 19:14, Reid Kleckner via llvm-dev wrote:> On Tue, Jan 15, 2019 at 9:24 AM David Greene via llvm-dev < > llvm-dev at lists.llvm.org> wrote: > >> David Chisnall via llvm-dev <llvm-dev at lists.llvm.org> writes: >> >> > I'm not opposed to this in principle, and actually I'd quite like to >> > move in this direction and remove our reliance on undocumented and >> > inconsistent conventions between the back end and the front end for >> > conveying information about ABIs. For example, returning two 32-bit >> > integers or a pair of pointers on x86-32 requires returning the result >> > in a single i64 in LLVM IR (on platforms where small structs are >> > returned in registers, not on Linux), which is not particularly >> > helpful for analysis or consistent with any other architecture. Given >> > that front ends have to be aware of calling conventions, it would be >> > nice if they could express them in the same way that the ABI >> > references do... >> >> +1. Coordinating ABI semantics between the frontend and LLVM is >> tricky. >> It would be super helpful to have a formal way of expressing ABI >> semantics in the IR. >> > > I agree with that, but I think most users want LLVM to go the other way > from what the OP is suggesting. I think non-clang frontends would > prefer it > if we pushed more calling convention details down into LLVM, not the > other > way around.I agree that handling the calling conventions in one place (e.g. the frontend) would be a good idea. Sometimes people complain that ABI handling in the frontend is hard and that they have to duplicate (in their language’s frontend) what Clang does. However, I don’t think that pushing more of this complexity into LLVM would be a good idea. What I suggest is that there should be a helper library for ABI lowering (ideally that library should be used by Clang eventually). What do you think? -Manuel
David Chisnall via llvm-dev
2019-Jan-16 09:33 UTC
[llvm-dev] [RFC] Introducing an explicit calling convention
On 15/01/2019 21:56, Manuel Jacob via llvm-dev wrote:> > Sometimes people complain that ABI handling in the frontend is hard and > that they have to duplicate (in their language’s frontend) what Clang > does. However, I don’t think that pushing more of this complexity into > LLVM would be a good idea. What I suggest is that there should be a > helper library for ABI lowering (ideally that library should be used by > Clang eventually). What do you think?I would love to see this and I was hoping that some of the Swift work would lead to a refactored clang library that allowed you to generate IR corresponding to C/C++ functions. I think we have four use cases for front ends: 1. JIT'd language, minimal FFI. This doesn't care what the calling convention is, doesn't care that it's stable, does care that it's efficient. Except at well-defined external calls, is very happy for LLVM to pick a different calling convention for every function. 2. Language that has only an LLVM implementation, but does support static compilation and linking across different compiler versions. Doesn't care what the calling convention is, but it has to be stable. LLVM is free to pick a different calling convention for every type signature, but the convention must be stable and doesn't have to match the platform ABI. 3. Language that is adding a new LLVM implementation that is expected to interoperate with an existing implementation. There are a lot of these out there and they all end up suffering. Typically they either fork LLVM and add a custom calling convention, or they try to upstream a calling convention. When they want to support a new architecture, then need to coordinate their releases with LLVM to get their calling conventions supported by the new back end. They make live even harder for the next person to want to use their calling convention by adding more undocumented informal contracts between how the front end generates LLVM IR and how the back end maps this to register / stack layout. 4. Language that wants to interoperate with C/C++. These sometimes embed a big chunk of clang. This probably should be the preferred solution, because it will invariably miss corner cases (packed structs, for example) if it does anything simpler. Unfortunately, clang isn't really designed for this kind of embedding and the APIs that consumers need change quite frequently. Alternatively, they implement their own partial ABI support. For the core C ABI (ignoring GNU extensions and C++), it is *much* easier to do this in a JIT that generates assembly directly than one that targets LLVM IR. ABI specs describe a fairly simple (even amd64, though that's stretching it somewhat) set of rules for mapping C constructs to registers / stack offsets. These are well defined and well documented. The corresponding set of mappings from C constructs to IR constructs are undocumented outside of the code and the only way that you can reliably find them is to run clang and see what it emits (I have done this - it's not fun). If you need only basic C interop, doing this for each platform that you support ought to be simpler than embedding clang, but it isn't. Ideally, we'd have both a clean set of APIs for other front ends to embed clang (including a lot of what libclang exposes: parsing C headers, walking types, and then generating interoperable code), built on top of a clean way for the front end to either specify the exact ABI requirements or leave them entirely up to later optimisations or the back end. David
Frej Drejhammar via llvm-dev
2019-Jan-16 11:56 UTC
[llvm-dev] [RFC] Introducing an explicit calling convention
David Chisnall via llvm-dev <llvm-dev at lists.llvm.org> writes:> On 15/01/2019 21:56, Manuel Jacob via llvm-dev wrote: >> >> Sometimes people complain that ABI handling in the frontend is hard >> and that they have to duplicate (in their language’s frontend) what >> Clang does. However, I don’t think that pushing more of this >> complexity into LLVM would be a good idea. What I suggest is that >> there should be a helper library for ABI lowering (ideally that >> library should be used by Clang eventually). What do you think? > > I would love to see this and I was hoping that some of the Swift work > would lead to a refactored clang library that allowed you to generate > IR corresponding to C/C++ functions.Such a library would still have to have a way to send the low-level information about register and stack slot mappings to the back-end. The original proposal would have to be extended to support calling functions with the explicit CC, but then it could serve as the target of this ABI lowering library. I quite like Philip Reames suggestion[1] (elsewhere in this thread) of just providing a way to plug in an externally defined calling convention. The ABI lowering library could produce such plugins and we don't have to worry about syntax and the expressibility of the CC description. --Frej [1] http://lists.llvm.org/pipermail/llvm-dev/2019-January/129189.html
Chris Lattner via llvm-dev
2019-Jan-18 06:29 UTC
[llvm-dev] [RFC] Introducing an explicit calling convention
On Jan 16, 2019, at 1:33 AM, David Chisnall via llvm-dev <llvm-dev at lists.llvm.org> wrote:> On 15/01/2019 21:56, Manuel Jacob via llvm-dev wrote: >> Sometimes people complain that ABI handling in the frontend is hard and that they have to duplicate (in their language’s frontend) what Clang does. However, I don’t think that pushing more of this complexity into LLVM would be a good idea. What I suggest is that there should be a helper library for ABI lowering (ideally that library should be used by Clang eventually). What do you think? > > I would love to see this and I was hoping that some of the Swift work would lead to a refactored clang library that allowed you to generate IR corresponding to C/C++ functions. > > I think we have four use cases for front ends: > > 1. JIT'd language, minimal FFI. This doesn't care what the calling convention is, doesn't care that it's stable, does care that it's efficient. Except at well-defined external calls, is very happy for LLVM to pick a different calling convention for every function. > > 2. Language that has only an LLVM implementation, but does support static compilation and linking across different compiler versions. Doesn't care what the calling convention is, but it has to be stable. LLVM is free to pick a different calling convention for every type signature, but the convention must be stable and doesn't have to match the platform ABI. > > 3. Language that is adding a new LLVM implementation that is expected to interoperate with an existing implementation. There are a lot of these out there and they all end up suffering. Typically they either fork LLVM and add a custom calling convention, or they try to upstream a calling convention. When they want to support a new architecture, then need to coordinate their releases with LLVM to get their calling conventions supported by the new back end. They make live even harder for the next person to want to use their calling convention by adding more undocumented informal contracts between how the front end generates LLVM IR and how the back end maps this to register / stack layout. > > 4. Language that wants to interoperate with C/C++. These sometimes embed a big chunk of clang. This probably should be the preferred solution, because it will invariably miss corner cases (packed structs, for example) if it does anything simpler. Unfortunately, clang isn't really designed for this kind of embedding and the APIs that consumers need change quite frequently. Alternatively, they implement their own partial ABI support. For the core C ABI (ignoring GNU extensions and C++), it is *much* easier to do this in a JIT that generates assembly directly than one that targets LLVM IR. ABI specs describe a fairly simple (even amd64, though that's stretching it somewhat) set of rules for mapping C constructs to registers / stack offsets. These are well defined and well documented. The corresponding set of mappings from C constructs to IR constructs are undocumented outside of the code and the only way that you can reliably find them is to run clang and see what it emits (I have done this - it's not fun). If you need only basic C interop, doing this for each platform that you support ought to be simpler than embedding clang, but it isn't. > > Ideally, we'd have both a clean set of APIs for other front ends to embed clang (including a lot of what libclang exposes: parsing C headers, walking types, and then generating interoperable code), built on top of a clean way for the front end to either specify the exact ABI requirements or leave them entirely up to later optimisations or the back end.If anyone would like to organize a round table at EuroLLVM to talk about this topic, I’d love to participate. I have lots of thoughts and opinions here (but can’t really explain it all without a whiteboard) and they may be interesting to discuss. -Chris
Seemingly Similar Threads
- [RFC] Introducing an explicit calling convention
- [RFC] Introducing an explicit calling convention
- [RFC] Introducing an explicit calling convention
- For what reason the "official" Wine does not support USB ?
- [LLVMdev] Contributing the Apple ARM64 compiler backend