LLVM: Bagian-Bagian yang Bermasalah
(npopov.com)- Menganalisis keterbatasan struktural dan utang teknis proyek LLVM dari berbagai sudut, sambil secara spesifik menyoroti area yang perlu diperbaiki
- Menunjukkan berbagai hambatan dalam pengelolaan proyek open source skala besar seperti kurangnya review, ketidakstabilan API, waktu build dan kompilasi, serta ketidakstabilan CI
- Untuk masalah desain IR, mencakup penanganan nilai undef, encoding constraint, semantik floating-point, dan ketidaklengkapan spesifikasi
- Menyoroti masalah struktural jangka panjang seperti heterogenitas backend, kebingungan penanganan ABI, serta tertundanya transisi GlobalISel dan pass manager
- Alih-alih memandang kondisi LLVM secara negatif, hal ini diposisikan sebagai peluang untuk perbaikan berkelanjutan dan perluasan kontribusi
Masalah struktural utama
-
Kurangnya kapasitas review disebut sebagai hambatan terbesar
- Penulis kode banyak, tetapi reviewer kurang, sehingga perubahan yang belum tervalidasi kadang ikut di-merge
- Karena struktur permintaan review menjadi tanggung jawab penulis, kontributor baru kesulitan menemukan reviewer yang tepat
- Penerapan sistem penugasan PR otomatis seperti di Rust disebut sebagai salah satu opsi perbaikan
-
Perubahan API dan IR yang terlalu sering (churn) membebani pengguna
- C API relatif stabil, tetapi C++ API sering berubah sehingga biaya pemeliharaan frontend dan backend meningkat
- Karena filosofi “Upstream or GTFO”, kode yang tidak dibagikan ke upstream tidak tercermin dalam pengambilan keputusan
-
Masalah waktu build yang berlebihan
- LLVM terdiri dari lebih dari 2,5 juta baris kode C++, sehingga waktu build sangat lama, dan build debug meningkatkan penggunaan memori serta disk secara drastis
- Precompiled header (PCH), build default berbasis dylib, dan daemonisasi test dibahas sebagai langkah perbaikan
-
Ketidakstabilan CI
- Lebih dari 200 buildbot menguji di berbagai lingkungan, tetapi tidak selalu mampu menjaga kondisi “hijau”
- Flaky test dan masalah buildbot mengaburkan sinyal peringatan sehingga sulit mendeteksi error yang nyata
- Pengenalan pengujian sebelum PR memberi sedikit perbaikan, tetapi solusi mendasarnya masih kurang
-
Kurangnya pengujian end-to-end
- Unit test optimisasi per tahap cukup baik, tetapi hampir tidak ada pengujian untuk keseluruhan pipeline atau integrasi backend
llvm-test-suitememang ada, tetapi belum cukup mencakup kombinasi operasi dasar dan tipe data
Masalah terkait backend dan performa
-
Heterogenitas antar-backend
- Meski tahap menengah terintegrasi, backend banyak dimodifikasi secara terpisah per target sehingga duplikasi dan percabangan meningkat
- Ada kecenderungan menambahkan hook khusus target alih-alih optimalisasi bersama
-
Waktu kompilasi
- Lambat untuk JIT dan bahasa yang menghasilkan IR dalam skala besar (Rust, C++)
- Build
-O0sangat lambat, dan backend TPDE diajukan sebagai alternatif yang bisa 10~20 kali lebih cepat
-
Tidak adanya pelacakan performa
- Tidak ada infrastruktur pelacakan performa runtime resmi
- Sistem LNT kurang efektif karena ketidakstabilan operasional, masalah UX, dan minimnya data
Masalah desain IR
-
Kompleksitas penanganan nilai undef
- Karena nilainya dapat berbeda di setiap penggunaan, hal ini bisa memicu error saat optimisasi
- Di masa depan mungkin digantikan oleh nilai poison, tetapi penanganan poison di memori masih belum memadai
-
Spesifikasi yang tidak lengkap dan tidak konsisten
- Ada kasus miscompile lama yang belum terselesaikan
- Terdapat tantangan desain seperti model provenance
- Untuk mengatasinya, telah dibentuk working group spesifikasi formal
-
Kurangnya konsistensi dalam encoding constraint
- Berbagai cara seperti poison flag, metadata, atribut, dan assumes dipakai secara campur aduk
- Hal ini berdampak negatif pada optimisasi karena bisa menyebabkan hilangnya informasi atau justru terlalu banyak informasi dipertahankan
-
Masalah semantik floating-point (FP)
- Ketidaksesuaian muncul pada signaling NaN, lingkungan nonstandar, penanganan denormal, dan presisi ekstra x87
- Penanganannya dipisahkan lewat constrained FP intrinsic, sehingga kompleksitas meningkat
Masalah teknis lainnya
-
Migrasi parsial yang tertunda
- Pass manager baru baru diterapkan sampai tahap menengah, sedangkan backend masih memakai versi lama
- GlobalISel belum berhasil sepenuhnya menggantikan sistem lama selama 10 tahun, dan masih hidup berdampingan dengan SDAG
-
Kebingungan dalam penanganan ABI dan calling convention
- Pemisahan tanggung jawab antara frontend dan backend tidak jelas dan kurang terdokumentasi
- Pengenalan library ABI dan implementasi prototipe sedang berjalan
- Ada masalah bahwa ABI dapat berubah tergantung aktivasi fitur target
-
Ketidakkonsistenan pengelolaan fungsi built-in dan libcalls
- TargetLibraryInfo dan RuntimeLibcalls terpisah sehingga kurang konsisten
- Tidak ada pemahaman yang memadai tentang ketersediaan berdasarkan jenis runtime library (libgcc, compiler-rt, dan lain-lain)
- Tidak ada titik kustomisasi untuk runtime eksternal seperti Rust
-
Inefisiensi struktur Context / Module
- Tipe dan konstanta berada di Context, sementara fungsi dan global berada di Module
- Karena data layout tidak bisa diakses, hal ini merepotkan untuk constant folding dan kasus lain
- Linking lintas-context tidak dimungkinkan, sehingga penyederhanaan struktur diperlukan
-
Register pressure akibat LICM (loop-invariant code motion)
- Hoist dilakukan tanpa cost model
- Karena tidak di-sink kembali di backend, hal ini meningkatkan spill dan reload
Kesimpulan
- Masalah-masalah yang disebutkan merupakan tantangan struktural yang muncul dari kematangan dan skala LLVM,
dan diposisikan sebagai peluang untuk meningkatkan kualitas proyek dan pengalaman kontributor - Di beberapa area (optimisasi build, library ABI, pelacakan performa, dll.), pekerjaan perbaikan sudah mulai berjalan
- Secara keseluruhan LLVM tetap kuat, tetapi refactoring berkelanjutan dan pembenahan spesifikasi tetap esensial
1 komentar
Komentar Hacker News
Tulisan secara keseluruhan tersusun rapi, jadi cukup mudah untuk setuju.
Belakangan ini stabilitas LLVM IR sudah cukup tinggi. Fil-C berhasil direbase dari LLVM 17 ke 20 hanya dalam sehari.
Di proyek lain juga pass yang sama dipertahankan di beberapa versi LLVM tanpa masalah besar.
Namun tekanan register pada LICM cukup parah, terutama untuk sumber yang bukan C/C++. Masalahnya tampaknya bukan pada LICM itu sendiri, melainkan regalloc yang perlu belajar melakukan rematerialize dengan lebih baik
Akan bagus jika lebih banyak opsi dibuka agar pengembang frontend bisa benchmark berbagai konfigurasi dan memilih nilai optimal
Setiap alat dan komponen punya aturannya sendiri, jadi perbedaan antarversi justru terasa wajar. Saya penasaran apakah pemahaman saya ini keliru
Saya pernah meminta maintainer compiler-rt untuk mengubah satu boolean saja agar bisa membangun LLVM 18 di macOS, tetapi isu itu malah dikunci sebagai isu yang “heated” dan sudah 4 tahun belum terselesaikan.
Meski begitu saya tetap suka LLVM. clang-tidy, ASAN, UBSAN, LSAN, MSAN, TSAN benar-benar luar biasa.
Menulis kode C/C++ tanpa memakai clang-tidy menurut saya adalah pilihan yang keliru.
Hanya saja -fbounds-safety hanya ada di AppleClang, sedangkan MSAN/LSAN hanya ada di LLVM Clang. Di Xcode juga tidak ada clang-tidy, clang-format, maupun llvm-symbolizer.
Pada akhirnya di macOS saya harus membangun Darwin LLVM sendiri dan memakainya.
Sisi Linux juga membingungkan. RHEL tidak menyediakan libcxx, tetapi Fedora menyediakannya. Namun libcxx yang sudah diinstrumentasi untuk MSAN tidak ada di distribusi mana pun.
Fedora hampir lengkap, tetapi tetap saja compiler-rt harus dibangun manual
Setelah mengikuti berbagai diskusi LLVM belakangan ini, saya merasa benar-benar perlu ada test suite yang bisa dieksekusi dan dimulai langsung dari LLVM IR, bukan dari C.
Jika pernah membuat backend sendiri, dokumentasi terkait SelectionDAG atau GlobalISel terasa kurang, dan makna operasinya tidak jelas sehingga mudah salah implementasi
C API terasa seperti bagian yang terabaikan di LLVM. Banyak opsi maupun opt pass yang tidak diekspos
Karena kebanyakan pengembang langsung memakai API C++, C API terdorong ke prioritas belakang dan akhirnya tetap menjadi warga kelas dua
Code review tidak langsung menghasilkan imbalan, jadi orang cenderung enggan melakukannya.
Jika review juga diberi kredit kontribusi, mungkin motivasinya akan muncul
Enam tahun lalu saya sering membangun LLVM dengan laptop Dell 9360 8GB. Jika paralelisme linking dikurangi, itu masih bisa dilakukan dalam batas memori.
Saya penasaran apakah sekarang build dengan 8GB masih memungkinkan
Pada masa awal LLVM, salah satu keunggulannya adalah kecepatan kompilasi yang lebih tinggi daripada GCC.
Sekarang setelah 23 tahun LLVM berlalu, saya penasaran apakah akan muncul sesuatu yang benar-benar baru lagi
Ada juga alternatif seperti Cranelift yang tidak memakai LLVM IR (Cranelift GitHub)
Penanganan ABI dan calling convention adalah penderitaan terbesar.
Di frontend compiler kita harus mengelola sendiri cara pengiriman argumen, dan kadang bahkan harus menghitung jumlah register
Dalam tulisan disebutkan bahwa “frontend terlindungi berkat C API yang stabil”, tetapi kenyataannya tidak begitu.
Beberapa API memang stabil, tetapi bagian seperti Orc sering berubah
LLVM tampaknya hampir tidak punya sistem review isu. Bug report yang saya kirim juga sudah bertahun-tahun belum ditangani