Exploring Rust's Compilation Pipeline: Building a Custom Toolchain—MIR, CLIF, or Beyond? #47
Replies: 5 comments 22 replies
-
What's the goal here? I can perhaps answer better knowing why you want an end-to-end Rust toolchain (i.e., different from the existing mainstream Rust toolchain).
Theoretically, these can be achieved. But practically, it's quite hard to aim for it all at once. My take would be that we depend on other implementations (libraries) conveniently till all the parts eventually use pliron infrastructure.
The way I see it, both of what you mention will be required, not just one or the other. A borrow checked, optimized MIR can be translated to an MIR dialect in pliron. This can then be further optimized, subject to other static analysis etc within the pliron framework. Once pliron supports an llvm dialect completely (it's only a partial / proof-of-concept today) and / or a clif dialect, then either could be used for generating assembly. A personal target of mine is to have complete llvm and clif dialects in-tree inside pliron (as separate crates, but in the same repo) and have conversions available b/w the two. This will enable anyone using pliron to just target one of the two, and the other would automatically work. |
Beta Was this translation helpful? Give feedback.
-
|
I’ve put together an initial implementation of the Clif → Pliron-Clif dialect with a (basic) working example, using the existing Pliron-LLVM implementation as a starting point. You can find it here: Pliron-Clif Implementation. I have a couple of questions regarding the generated IR:
builtin.func @add: builtin.function <(builtin.int <si32>, builtin.int <si32>) -> (builtin.int <si32>)>
{
^entry_block_1v1(block_1v1_arg0: builtin.int <si32>, block_1v1_arg1: builtin.int <si32>):
op_2v1_res0 = clif.iadd block_3v1_arg0, block_4v1_arg1: builtin.int <si32>;
clif.return (op_3v1_res0) [] []: <(builtin.int <si32>) -> ()>
}Additionally, I’d love to hear your feedback on the overall implementation—like am I heading in the right direction? |
Beta Was this translation helpful? Give feedback.
-
I meant to say for
|
Beta Was this translation helpful? Give feedback.
-
Can you try using I closed #49 as "won't implement", and this is an alternate for that. |
Beta Was this translation helpful? Give feedback.
-
|
I’m working on the Hummanta compiler, which has similar requirements—though my use case is a bit more complex, as it needs to support multiple frontend languages and multiple VM bytecode outputs. Based on MLIR and the earlier discussion, I’ve sketched a diagram of Hummanta’s compilation flow and its interaction with MLIR: In my design:
Additionally, I plan to use MLIR for source-to-source translation between languages. I chose Cranelift for its ISLE (ideal for custom ISAs), while LLVM provides broad platform support. |
Beta Was this translation helpful? Give feedback.

Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
I am currently evaluating what it takes to build an end-to-end Rust toolchain. This includes the compiler backend, for which, at present, the only reliable option is LLVM. My goal is threefold, prioritized in the following order:
Full Control of the Compilation Pipeline: Can we achieve complete control over the compilation process to enable better reasoning and customization? Essentially, the ability to modify any stage of compilation to achieve specific outcomes—whether it’s performance, stability, formal verification, productivity, or other goals. While this may be an ambitious ask, my initial focus will be on achieving comparable performance.
Competing with State-of-the-Art Solutions: Can we compete with established systems like LLVM? Perhaps not entirely, but at least for narrowly scoped, custom use cases as a starting point.
Support for RISC-V Hardware: Can we provide support for a selection of extensions for RISC-V hardware, whether custom or standard? I believe that with Pliron (similar to MLIR), this should be relatively straightforward.
Additional Context: I recently spoke with one of the core developers of Cranelift, where I learned that using Cranelift as the backend for plain Rust code could result in a performance hit of 5–15x compared to LLVM. Although Cranelift describes itself as an optimizing compiler, its current focus is on consuming optimized WebAssembly (WASM)—optimized using LLVM’s optimizer—and converting it into Cranelift IR (CLIF) for machine code generation.
The developer mentioned that it would be possible to add necessary optimizations, such as
mem2regand aggressive inlining, to reduce this performance gap. However, he also noted that Cranelift’s primary focus is on compilation speed. Additionally, the ISLE DSL (Domain-Specific Language) used in Cranelift can feel overly complex, to the point where it starts to resemble LLVM in terms of intricacy.Given the above context, I’m exploring the following two paths, depending on the amount of information or stability guarantees we lose when moving from MIR (high-level IR) to CLIF IR (low-level IR):
MIR → Pliron MIR
rustc). This lack of stability could pose challenges for long-term maintenance.CLIF → Pliron CLIF
I’d love to hear your thoughts on this.
Beta Was this translation helpful? Give feedback.
All reactions