Step 05 · The mlir-translate / lli pipeline

mlir-translate is MLIR's bridge to external IRs. Its --mlir-to-llvmir mode walks an MLIR module that's already in the llvm dialect and produces textual LLVM IR. From there lli or llc take over.

MiniLang source
   │  Lexer → Parser → Resolver → TypeChecker → IR builder
   ▼
MiniLang TAC IR
   │  mlir_emit::emit
   ▼
MLIR (`llvm` dialect)
   │  mlir-translate --mlir-to-llvmir
   ▼
LLVM IR (text)
   │  lli   (or  llc -filetype=obj  + ld)
   ▼
Process exit code + stdout

Implementing the pipeline in C++

runShell (in mlir_emit.cpp) forks /bin/sh -c "mlir-translate ... | lli" with pipes attached. Robust enough for tests; production tooling would likely link MLIR's own translation library instead.

Catching errors

If mlir-translate rejects our IR (wrong type, missing op), the pipe breaks and lli exits non-zero. We capture stderr from the child into PipelineResult::error so test failures point at the offending stage.

Inspecting intermediate stages

echo 'print 42;' | ./build/mlmlir | tee /tmp/m.mlir
/opt/homebrew/opt/llvm/bin/mlir-opt /tmp/m.mlir --canonicalize       # pretty + sanity-check
/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/llc -O2 -filetype=obj -o /tmp/m.o