cp-13 · MLIR foundations — emit, lower, translate
cp-11/12 used LLVM IR directly. cp-13 takes a step up the abstraction ladder to MLIR (Multi-Level Intermediate Representation): a generic framework for building IRs with first-class regions, blocks, and extensible dialects.
We emit our TAC IR as MLIR text in the llvm dialect (a near-1:1
mapping of LLVM IR into MLIR syntax), then drive Homebrew's
mlir-translate + lli to execute the program.
Why the llvm dialect?
Real MLIR projects build a custom dialect (minilang.*) and lower it
through arith, cf, memref to llvm. That's pedagogically
fantastic but operationally fragile across MLIR versions. cp-13
keeps the toolchain minimal so every test passes out-of-the-box on
LLVM/MLIR 20. The step docs walk through what a full dialect would
look like.
Build & run
cmake -S src/cpp -B build
cmake --build build
./build/tests/test_mlir_emit # → 25/25 checks passed
echo 'print 2+3*4;' | ./build/mlmlir # emit MLIR
echo 'print 2+3*4;' | ./build/mlmlir --run # → 14
Inspect the pipeline by hand:
echo 'print 42;' | ./build/mlmlir > /tmp/m.mlir
/opt/homebrew/opt/llvm/bin/mlir-opt /tmp/m.mlir --canonicalize
/opt/homebrew/opt/llvm/bin/mlir-translate /tmp/m.mlir --mlir-to-llvmir
/opt/homebrew/opt/llvm/bin/mlir-translate /tmp/m.mlir --mlir-to-llvmir \
| /opt/homebrew/opt/llvm/bin/lli