rokdocs
v0.1

0.2. Compilation pipeline

This specification calls the rok compiler rokc. rokc embeds LLVM, MLIR and lld and runs the whole pipeline, from source to a linked binary, in-process.

0.2.1. Stages

The overall flow is as follows.

  source code
        │
        ▼
   rok-hir         (High-level IR - pre type inference, user code structure preserved)
        │
        ▼
   rok-mir         (Mid-level IR - monomorphized / operators desugared, all types fixed)
        │
        ▼
   standard MLIR   (upstream MLIR dialects - `func`, `arith`, `scf`, ...)    -O1 and above
        │
        ▼
   LLVM IR → native object → lld

At -O0 (builds and REPL), rok-mir goes straight to machine code through rok's native backend (0.2.4).

rok-hir is the high-level IR; it precedes type inference and preserves the structure of user code as is. rok-mir is the mid-level IR, in which monomorphization and operator desugaring are complete and all types are fixed. standard MLIR means the upstream MLIR dialects. Finally, LLVM IR and native code are produced.

0.2.2. One-way visibility

Each stage looks only at the stage immediately before it. The rok-hir generator refers only to the source. The rok-mir generator refers only to rok-hir. The MLIR emitter refers only to rok-mir.

Results of earlier stages are thus never consulted again by later stages. The specification documents follow the same rule: a lower-numbered file does not refer to a higher-numbered file.

0.2.3. Standard MLIR dialects only

No rok-specific MLIR dialect is defined. All dialects used are official upstream MLIR dialects.

DialectPurpose
funcFunction definition / call
arithInteger / floating-point arithmetic / comparison
scfStructured control flow (if / for / while)
cfUnstructured branches (switch, cond_br)
indexIndex type operations
mathMath functions
llvmLow-level ops (intrinsic, struct)

This choice guarantees the following. Improvements in upstream MLIR flow into rok automatically. rok interoperates with external MLIR-based tools such as IREE, Enzyme and Triton. And there is no cost of registering and maintaining a custom dialect.

In exchange, the responsibility for lowering rok's high-level semantics to the standard dialects concentrates in the compiler, specifically in the rok-mir → MLIR stage. This burden is intentional: it is moved inward so as not to close off options at the end of the pipeline.

0.2.4. Backends

rokc has two code generators. Both consume rok-mir and follow the same runtime ABI (8), so their objects link together.

BackendUsed forPath
native-O0 builds and REPL cellsrok-mir → machine code
MLIR → LLVM-O1 and aboverok-mir → MLIR → LLVM IR → optimized object

LLVM, MLIR and lld are part of rokc; no external LLVM tools are run and users do not install LLVM. Targets on macOS need the Xcode Command Line Tools for the SDK. Cross-compilation is built in: --target <triple> works from any host, and the toolchain ships the C library (musl, glibc link stubs) for its supported Linux targets, so a Linux target needs no sysroot. There are no C headers: rok compiles no C. Windows targets link against import libraries built from module definitions the toolchain carries, over the UCRT, with no MSVC tools or Windows SDK. Apple targets need the macOS SDK (Xcode Command Line Tools), which is not redistributable (9.2.14, 0.6). --emit=mlir / --emit=llvmir dump the intermediate forms (9.9.1).

Edit this page on GitHub