Reussir Language Reference

RRC: Inspecting the Compiler

RRC: Inspecting the Compiler

rrcrrc is Reussir’s compiler driver. Rene normally invokes it on behalf of a package, which is the convenient route for producing a complete executable. Running rrcrrc directly is useful when learning the pipeline, diagnosing a compiler problem, or capturing an intermediate representation for another MLIR tool.

This tutorial continues inside the hellohello package from Your First Project.

1. Ask for high-level IR

From the package root, compile src/lib.rrsrc/lib.rr only as far as Reussir’s high-level intermediate representation (HIR):

rrc src/lib.rr --package-name hello \
--emit hir --no-source-locations -o -
rrc src/lib.rr --package-name hello \
--emit hir --no-source-locations -o -

The options make the request explicit:

  • --package-name hello--package-name hello gives every declared item its package-qualified name;
  • --emit hir--emit hir stops after parsing and elaboration;
  • --no-source-locations--no-source-locations removes location annotations from the dump;
  • -o --o - writes the textual result to standard output.
A terminal using rrc to print the high-level IR for the Hello World program.
The HIR generated from the same src/lib.rrsrc/lib.rr that Rene compiled.

The first HIR line connects the generated C entry trampoline to #hello::entry#hello::entry; that is the effect of #[main]#[main]. The remaining lines show the package-qualified printing helper and the typed call from entryentry. The escaped source inside the helper is expected—it has not reached the Rust-backed compilation step yet.

2. Move through the pipeline

rrcrrc is a stage-oriented driver. A Reussir source file normally travels through this sequence:

.rr → HIR → MIR → Reussir MLIR → LLVM-dialect MLIR → LLVM IR → assembly/object
.rr → HIR → MIR → Reussir MLIR → LLVM-dialect MLIR → LLVM IR → assembly/object

Change only the value passed to --emit--emit to inspect another textual stage:

rrc src/lib.rr --package-name hello \
--emit mir --no-source-locations -o -
rrc src/lib.rr --package-name hello \
--emit mlir --no-source-locations -o -
rrc src/lib.rr --package-name hello \
--emit mir --no-source-locations -o -
rrc src/lib.rr --package-name hello \
--emit mlir --no-source-locations -o -

HIR retains elaborated language structure. MIR makes ownership, reference counting, and reuse decisions explicit. Reussir MLIR expresses those decisions in the Reussir dialect. The next mlir-llvmmlir-llvm stage lowers the module into LLVM-compatible dialects.

The Hello, World!Hello, World! printing helper contains host Rust, so lowering that particular file beyond Reussir MLIR also needs the runtime search paths that Rene supplies during rene buildrene build. To try a later stage without introducing that setup, save this pure function as square.rrsquare.rr:

pub fn square(x: i64) -> i64 {
x * x
}
pub fn square(x: i64) -> i64 {
x * x
}

LLVM IR and the other file-based emitters require a real output path:

rrc square.rr --package-name scratch \
--emit llvm-ir -O aggressive -o square.ll
rrc square.rr --package-name scratch \
--emit llvm-ir -O aggressive -o square.ll

Optimization levels are nonenone, defaultdefault, aggressiveaggressive, and sizesize. Keeping optimization off is often clearest while inspecting a transformation; use defaultdefault or aggressiveaggressive when the generated machine code is the subject of the experiment.

3. Know when to use Rene

Direct rrcrrc can also emit assembly, object files, libraries, and executables, and it accepts an existing HIR, MIR, MLIR, or LLVM IR file as its input stage. For an ordinary application, keep using rene buildrene build: Rene prepares the matching runtime, supplies the required library paths, handles every declared target, and records enough information for incremental builds.

Use rrcrrc when the compiler pipeline itself is what you want to observe. Use Rene when the result you want is the program.

Next, open the REPL to try Reussir expressions without creating a package or executable.