Step 07 · Targets and llc
Our mlcc emits target-independent LLVM IR. To produce a binary:
./build/mlcc -O program.ml > program.ll
/opt/homebrew/opt/llvm/bin/llc -O3 -filetype=obj program.ll -o program.o
clang program.o -o program
./program
llc walks:
LLVM IR
→ SelectionDAG / GlobalISel (instruction selection)
→ MachineInstr (target-specific MI)
→ Register allocation
→ Instruction scheduling
→ Machine code emission (.o)
Going programmatic
Inside C++, you'd:
InitializeNativeTarget,InitializeNativeTargetAsmPrinter.TargetRegistry::lookupTarget(sys::getDefaultTargetTriple(), err).target->createTargetMachine(...).- Set the module's
DataLayoutandTargetTriple. - Use a legacy
PassManager+addPassesToEmitFile(...)to write a.o.
We stop short of that in cp-11 to keep the lab focused; cp-12 (ORC
JIT) will internalise target initialisation in order to execute IR
without lli.
When to add a custom target
Building a real backend is a full course. For research languages, ride the existing X86/AArch64/RISC-V backends. Only write a target when you ship custom silicon.