LLVM sebagai Compiler Infrastructure: Arsitektur, IR, dan Perbandingan Performa

3 menit baca · 11 Nov 2026

LLVM bukan satu compiler, tapi kumpulan library dan tool untuk membangun compiler. Clang, rustc, dan compiler Swift memakainya untuk bagian optimasi dan code generation. Di artikel ini saya bahas cara kerjanya: arsitektur tiga tahap, LLVM IR, dan seberapa efisien hasilnya dibanding alternatif lain.
## Masalah yang diselesaikan
Kalau ada M bahasa dan N arsitektur target, pendekatan naif butuh M × N compiler. LLVM memecahnya jadi M + N: tiap bahasa cukup punya satu frontend yang menghasilkan IR, dan tiap arsitektur cukup punya satu backend yang membaca IR itu.
## Arsitektur tiga tahap
Source code → [Frontend] → LLVM IR → [Optimizer] → LLVM IR → [Backend] → Machine code
### Frontend
Mem-parse source code dan menghasilkan LLVM IR. Contoh: Clang (C/C++/Objective-C), rustc (Rust), compiler Swift.
### Optimizer
Rangkaian pass yang mentransformasi IR, misalnya dead code elimination, inlining, dan loop optimization. Karena bekerja di level IR, optimasinya berlaku untuk semua bahasa yang masuk lewat LLVM.
### Backend
Menerjemahkan IR ke instruksi target: x86, ARM, RISC-V, WebAssembly, dan lainnya.
## LLVM IR
IR mirip assembly tapi tidak terikat CPU tertentu, dan punya sistem tipe. Fungsi C ini:
c
int add(int a, int b) {
return a + b;
}
kira-kira menjadi:
llvm
define i32 @add(i32 %a, i32 %b) {
entry:
%sum = add i32 %a, %b
ret i32 %sum
}
i32 adalah integer 32-bit, %sum nilai sementara, dan ret mengembalikan hasil. Untuk melihat IR dari program sendiri:
bash
clang -S -emit-llvm -O0 add.c -o add.ll
[Callout] Coba bandingkan output -O0 dengan -O2 pada program yang lebih besar dari contoh ini. Di fungsi sekecil add bedanya hampir tidak terlihat.
## Tool bawaan
clang: frontend dan driver compileopt: menjalankan optimization pass pada file.llllc: mengubah IR jadi assemblylld: linkerlldb: debugger
## Rust dan bahasa lain
Rust tidak punya backend sendiri. rustc mengurus parsing, type checking, dan borrow checker, lalu menyerahkan LLVM IR ke LLVM. Di Benchmarks Game, versi Rust yang dipakai tercatat Rust 1.84.1 dengan LLVM 19.1.5, jadi optimasi dan code generation-nya datang dari mesin yang sama dengan Clang. debian
Konsekuensinya, Rust dan C/C++ bisa dibandingkan cukup adil. Menurut komentar di forum Rust, tidak ada alasan teoritis Rust harus lebih lambat karena backend-nya sama. Bahasa lain dengan pola serupa: Swift, Julia, dan Kotlin/Native. rust-lang
ProyekPeranClangCompiler C/C++/Objective-CRustrustc menghasilkan LLVM IRSwiftCompiler resmi SwiftJuliaJIT compilerKotlin/NativeCompile Kotlin ke native
## Perbandingan performa
### Clang vs GCC
Hasilnya seri dan pemenangnya berganti-ganti. Phoronix menyimpulkan bahwa di berbagai workload, masing-masing compiler mendapat campuran kemenangan yang sehat. Di Snapdragon X1 Elite, Clang 20.1 tercepat berdasarkan geometric mean semua tes, tapi GCC masih menang di beberapa tes seperti C-Ray dan ChaCha20. Untuk kode C/C++ umum, selisihnya biasanya beberapa persen dan arahnya tergantung program. phoronixphoronix
### Rust vs C
SumberTemuanBenchmarks GameRust dan C satu kelas kecepatanStudi akademikRust rata-rata overhead 1,96x di Algorithm Benchmarks dan 1,35x di Game Benchmarks dibanding C nsf
Dua hasil ini terlihat bertentangan, tapi hasilnya sangat dipengaruhi cara kode ditulis. Studi tadi menemukan penyebabnya antara lain bounds checking dan beberapa pola yang kurang teroptimasi. Jadi kesimpulan yang aman: dalam kondisi wajar, Rust satu kelas dengan C/C++.
[Callout] Angka di atas bergantung pada hardware, versi compiler, dan flag (-O2, -O3, -march=native, LTO). Untuk kasus sendiri, ukur langsung pakai program Anda.
## Penutup
Nilai utama LLVM ada di pemisahan tanggung jawabnya: frontend, optimizer, dan backend bisa berkembang sendiri-sendiri selama kontrak di tengahnya (IR) tetap sama. Sebagai orang yang sehari-hari bikin API, pola ini terasa akrab. Berikutnya saya mau coba menulis pass sederhana sendiri.