Memahami tahapan lengkap pipeline kompilasi — lexing, parsing, semantic analysis, AST, lowering ke IR, optimasi, codegen, hingga binary — dan perbandingan desain GCC monolitik vs LLVM modular library-first yang memungkinkan tooling seperti clangd.

Setelah di episode 1 kita memahami sejarah LLVM dan arsitektur 3-fase secara konseptual, pada episode ini kita masuk lebih dalam: bagaimana satu baris kode C berubah dari teks mentah menjadi binary yang bisa dieksekusi CPU.
Pipeline kompilasi adalah jantung LLVM. Memahami setiap tahapan — dan memahami mengapa LLVM mendesainnya sebagai library — akan memberikan kalian fondasi untuk menulis pass optimasi, membangun front-end, atau menggunakan libTooling di episode-episode mendatang.
Setiap kali kalian menjalankan clang -o program source.c, sebenarnya terjadi delapan tahapan yang saling berurutan:
Lexer memecah source code menjadi token: identifier, keyword, literal, operator. Ini tahapan paling sederhana — tidak ada pemahaman makna, hanya pemecahan string.
int main() {
return 42;
}Hasil lexing:
KEYWORD(int) IDENTIFIER(main) LPAREN RPAREN LBRACE KEYWORD(return) INTEGER(42) SEMICOLON RBRACEParser mengonsumsi token dan membangun Abstract Syntax Tree (AST) berdasarkan grammar bahasa. AST merepresentasikan hierarki struktur kode secara树状.
Sema memvalidasi AST: tipe konsisten, scope benar, deklarasi lengkap. Error seperti "use of undeclared identifier" muncul di tahap ini.
AST diturunkan ke LLVM IR — intermediate representation yang berada di tengah-tengah antara source code dan assembly. Inilah format yang dikonsumsi oleh optimizer.
Pass optimizer LLVM menganalisis dan mentransformasi IR untuk menghasilkan kode yang lebih cepat atau lebih kecil. Tahap ini adalah keunggulan utama LLVM — kita bahas detailnya di episode 8.
IR diturunkan ke machine code untuk target spesifik (x86, ARM, RISC-V). Tahap ini melibatkan instruction selection, register allocation, dan scheduling.
Machine code diemisikan ke format objek (ELF, Mach-O, COFF).
Linker (LLD atau GNU ld) menggabungkan object file dan library menjadi binary final executable.
-### dan -save-tempsFlag -### menampilkan seluruh command yang dijalankan Clang secara internal — dari preprocessing hingga linking:
clang -### -o hello hello.c 2>&1Outputnya panjang dan menunjukkan bahwa Clang sebenarnya menjalankan banyak subprocess: preprocessor, compiler proper, assembler, dan linker.
Flag -save-temps menyimpan file intermediate di setiap tahapan:
clang -save-temps -o hello hello.c
ls hello.* hello.*Kalian akan melihat file-file ini:
| File | Isi |
|---|---|
hello.i | Hasil preprocessing (include expansion) |
hello.s | Assembly output |
hello.bc | LLVM bitcode (binary IR) |
hello.o | Object file |
hello | Binary final |
Inspeksi setiap tahapan:
cat hello.ll
# atau dari bitcode
llvm-dis hello.bc -o - | lessPerbedaan fundamental: GCC dibangun sebagai executable monolitik. Kalian tidak bisa memanggil optimizer GCC dari kode C++ kalian tanpa modifikasi ekstensif. LLVM dibangun sebagai kumpulan library — optimizer, codegen, assembler, linker semuanya tersedia sebagai library yang bisa dipanggil terpisah.
Dampak praktis:
| Aspek | GCC | LLVM/Clang |
|---|---|---|
| Integrasi IDE | Terbatas (tepatnya cotext) | clangd: autocompletion, refactoring, diagnistik |
| Sanitizer | -fsanitize=* (built-in) | compiler-rt library (dapat di-link terpisah) |
| JIT compilation | Tidak ada | ORC JIT API (episode 20) |
| Custom pass | Sulit (extension points terbatas) | New Pass Manager (episode 7) |
| Libtooling | Tidak ada | Clang C++ API untuk analisis & refactoring |
Inilah mengapa clangd bisa berjalan di background tanpa mengompilasi seluruh proyek: ia memanggil Clang API secara parsial untuk parsing dan analisis tipe. GCC tidak memungkinkan ini karena arsitekturnya tidak dirancang sebagai library.
Inti yang harus dibawa pulang:
-### untuk melihat command internal Clang, -save-temps untuk menyimpan file intermediate.Di episode 3 selanjutnya kita akan membahas struktur proyek LLVM & build dari source — monorepo llvm-project, komponen build (TableGen), cara build dengan CMake + Ninja, serta kapan harus build dari source vs pakai prebuilt. Sampai jumpa di episode 3!