Roadmap menulis backend target CPU baru untuk LLVM: langkah minimal dari TargetLowering, frame lowering, hingga instruction emission, serta studi kasus backend toy/edu (Cpu0, AVR historis) sebagai referensi belajar.

Setelah di episode 17 kita memahami register allocation dan MC Layer, pada episode ini kita menarik pandangan ke atas: bagaimana menulis backend target baru dari nol untuk LLVM.
Menulis backend baru adalah salah satu proyek paling ambisius dalam ekosistem LLVM — ia melibatkan ratusan hingga ribuan baris TableGen, pengaturan instruction selection, register allocation, dan code emission. Meskipun demikian, memahami roadmap-nya memberikan kalian gambaran realistis tentang apa yang diperlukan.
Untuk target CPU toy (subset instruksi minimal), langkah-langkahnya:
| Langkah | Keterangan | File utama |
|---|---|---|
| 1. Daftarkan target | Buat direktori lib/Target/MyTarget/ | MyTarget.td |
| 2. Definisikan register | Register class dan register fisik | MyTargetRegisterInfo.td |
| 3. Definisikan instruksi | Encoding, format, operands | MyTargetInstrInfo.td |
| 4. TargetLowering | Konversi LLVM IR selection → MachineInstr | MyTargetISelLowering.cpp |
| 5. Frame lowering | Stack frame layout, callee-saved registers | MyTargetFrameLowering.cpp |
| 6. Instruction emission | Emit MCInst → assembly/object text | MyTargetAsmPrinter.cpp |
TargetLowering mendefinisikan bagaimana operasi LLVM IR diturunkan ke operasi target:
MyTargetLowering::MyTargetLowering(const TargetMachine &TM)
: TargetLowering(TM) {
// Register types yang didukung
addRegisterClass(MVT::i32, &MyTarget::GPRRegClass);
// Konversi operation
setOperationAction(ISD::ADD, MVT::i32, Legal);
setOperationAction(ISD::MUL, MVT::i32, Expand);
setOperationAction(ISD::SDIV, MVT::i32, LibCall);
}Menentukan layout stack frame — berapa alokasi untuk local variables, callee-saved registers, dan alignment:
void MyTargetFrameLowering::eliminateFrameIndex(
MachineBasicBlock::iterator II,
int SPAdj, RegScavenger *RS) const {
// Ganti frame index references dengan SP+offset
int FrameIdx = MI->getOperand(1).getIndex();
int Offset = getOffset(FrameIdx);
MI->getOperand(1).setReg(SPReg);
MI->getOperand(1).setImm(Offset);
}Beberapa backend yang berguna sebagai referensi belajar:
| Backend | Keterangan |
|---|---|
| Cpu0 | Backend toy sederhana, cocok untuk belajar |
| AVR (historis) | Backend embedded yang sekarang di-out-of-tree |
| MSP430 | Backend embedded kecil untuk TI MSP430 |
Backend Cpu0 adalah yang paling cocok untuk pemula: cukup sederhana untuk dipahami dalam hitungan minggu, tetapi cukup lengkap untuk menunjukkan seluruh pipeline backend.
# Asumsi: backend MyTarget sudah terbuild
llc -march=mytarget -o hello.s hello.bc
llvm-mc -triple=mytarget -filetype=obj hello.s -o hello.o
# Jalankan di emulator ISA toy
mytarget-emulator hello.oWarning
Menulis backend baru untuk target produksi (bukan toy) membutuhkan bulan-bulan kerja dan pemahaman mendalam tentang hardware target. Jika kalian bekerja untuk semiconductor company, pelajari backend X86 atau AArch64 sebagai referensi — mereka adalah backend paling mature dan paling banyak dipelajari.
Inti yang harus dibawa pulang:
Di episode 19 selanjutnya kita akan membahas linking, LTO & DTLTO — LLD linker cepat, ThinLTO parallel, dan DTLTO (Distributed ThinLTO) untuk distribusi kompilasi lintas mesin. Sampai jumpa di episode 19!