Hello :wave: Other than Rust, do we have choices to integrate with the Cranelift API, say from Haskell and C# via a shard library of some sort?
The CLI is there but I'm thinking of something better. Thank you!
There aren't currently any Cranelift bindings for other languages. Rust has good support for exposing C-compatible APIs, and Haskell has good support for using C APIs, so it's certainly possible. Tools like cbindgen
(to generate a C header for a Rust API) and hsc2hs
(to generate Haskell bindings from a C header) should help. (I assume there are similar options for C#, but I'm not familiar with that ecosystem.) But nobody has done any of that work for Cranelift.
After some thought, I don't see a super easy path to providing a Cranelift C API, because it has a lot of entry points. Though one piece that you might think would be a pain actually is the easiest part: the InstBuilder
API is auto-generated, so auto-generating additional FFI-compatible entry points for that API would be relatively straightforward. I'd definitely consider merging a PR that did that. Designing a reasonable C API for everything else you might want is not as clear though.
I should note that Wasmtime does have a C API and bindings for several languages, so if you don't mind using WebAssembly as your IR, you can get a JIT/AOT compiler built on Cranelift that you can use from whatever language you want. That will be a more stable API over time than using Cranelift directly, too.
I would agree that a builder-focused API would not be too hard (conceptually, though there's a lot of plumbing and implementation-level thought to do here). I suspect that an API that allows introspection and mutation of the IR might be a bit more difficult, but maybe also not as immediately useful (I suspect that most of the demand for this is from projects that want to use Cranelift as a backend; @Mohannad Al-Awad is that the case for you?). In that case, an API of "constructors" -- for instructions, blocks, and functions -- is maybe ~a month of work total? I'd also be happy to discuss further and help with design here, along with Jamey, if someone is interested.
@Chris Fallin, does your time estimate include cranelift_codegen::Context
, cranelift-module, and either cranelift-jit or cranelift-object? Do you think there's anything especially challenging with any of those?
yeah, I was thinking about what it would take to give a basic "compile this function" toplevel entry point, given a CLIFFunction* and CompileOptions* or somesuch; some of the fiddly plumbing would come about in communicating the result of that (relocations, etc). Wrapping either the jit or object crate to get module-level support is another bit of work, maybe not necessary for a very first step...
Hi @Jamey Sharp and thank you for the suggestions. To be honest, I have considered WASM/WASI setup before for a different reason: portability in the sense that I can exchange backend compilers. However, I am not sure, due to my ignorance, if WASM/WASI is ready for general purpose programming while interfacing with other system/runtime APIs. Another consideration was also whether I will be able to pass the IR as an in-memory data structure to the backend compiler rather than passing it in some text/binary format that will then need to be parsed again, for performance. If you may comment on these points, I will be thankful. As for your point of multiple entry points, are you pointing out the large API surface that will need to be made C/FFI-compatible?
Hi @Chris Fallin and thank you also for your extended help. Yes, you are correct about my demand of Cranelift for backend compilation. Now, I need to decide whether to go with WASM/WASI IR or Cranelift-native IR, considering the points that I have mentioned above.
One more point for that decision is also possible optimizations with WASM/WASI due to potentially lost metadata from the previous steps that could benefit Cranelift having used its IR natively... not sure.
Last updated: Dec 23 2024 at 12:05 UTC