LLVM: 問題点
(npopov.com)- LLVMプロジェクトの構造的限界と技術的負債を多角的に分析し、改善が必要な領域を具体的に指摘
- レビュー不足、APIの不安定性、ビルドおよびコンパイル時間、CIの不安定性など、大規模オープンソースプロジェクト運営上のボトルネックを提示
- IR設計の問題として、
undef値の扱い、制約条件のエンコード、浮動小数点の意味体系、仕様の不完全性などを含む - バックエンドの異質性、ABI処理の混乱、GlobalISel・パスマネージャ移行の遅延など、長期的な構造問題を指摘
- LLVMの現状を否定するのではなく、継続的改善と貢献拡大の機会として提示
主な構造的問題
-
レビュー能力の不足が最大のボトルネックとして指摘される
- コードを書く人は多いがレビュアーが不足しており、十分に検証されていない変更がマージされる事例が発生
- レビュー依頼が作者責任の構造であるため、新規コントリビューターが適切なレビュアーを見つけにくい
- RustのPR自動割り当てシステムの導入が改善策として言及される
-
**APIおよびIRの頻繁な変更(Churn)**が利用者の負担
- C APIは比較的安定しているが、C++ APIは頻繁に変更され、フロントエンド・バックエンドの保守コストが増加
- 「Upstream or GTFO」という哲学により、共有されていないコードが意思決定に反映されない
-
ビルド時間の過大という問題
- LLVMは250万行を超えるC++コードで構成されており、ビルド時間が非常に長く、デバッグビルドではメモリ・ディスク使用量が急増
- プリコンパイル済みヘッダー(PCH)、dylibのデフォルトビルド、テストのデーモン化などが改善策として議論されている
-
CIの不安定性
- 200台以上のビルドボットが多様な環境でテストしているが、常に「グリーンな状態」を維持できていない
- flakyテストやビルドボットの問題により警告信号が薄まり、実際のエラー検出が難しい
- PR事前テストの導入で一部改善したものの、根本的な解決は不十分
-
エンドツーエンドテスト不足
- 個別最適化のユニットテストは充実している一方、全体パイプラインやバックエンド結合テストはほとんどない
llvm-test-suiteは存在するが、基本演算・データ型の組み合わせを十分に扱えていない
バックエンドおよび性能関連の問題
-
バックエンド間の異質性
- 中間段階は統合されているが、バックエンドは各ターゲットごとに独立した修正が多く、重複と分岐の増加につながっている
- 共通最適化よりもターゲット専用フックを追加する傾向がある
-
コンパイル時間
- JITおよび大規模IRを生成する言語(Rust、C++)で遅い
-O0ビルドが特に遅く、TPDEバックエンドは最大10〜20倍高速な代替案として提示される
-
性能追跡の欠如
- 公式なランタイム性能追跡インフラが存在しない
- LNTシステムは動作の不安定さ・UXの問題・データ不足などにより実効性が低い
IR設計の問題
-
undef値処理の複雑さ- 使用ごとに異なる値を取り得るため、最適化時に誤りを引き起こす
- 将来的にはpoison値で置き換えられる可能性があるが、メモリ内のpoison処理はまだ不十分
-
仕様の不完全性と不整合
- 古くから未解決の誤動作事例が存在
- provenanceモデルなど設計上の難題がある
- これを解決するため正式仕様ワーキンググループが構成された
-
制約条件エンコードの一貫性不足
- poisonフラグ、メタデータ、属性、assumesなど多様な方式が混在
- 情報損失または過剰保持により最適化へ悪影響を与える
-
浮動小数点(FP)の意味体系の問題
- シグナリングNaN、非標準環境、denormal処理、x87の超過精度などで不一致が発生
- 制約付きFP intrinsicとして別扱いされ、複雑さが増している
その他の技術的問題
-
部分的な移行の遅延
- 新パスマネージャは中間段階までにしか適用されておらず、バックエンドでは依然として旧式が使われている
- GlobalISelは10年経っても完全移行できず、SDAGと並存している
-
ABIおよび呼び出し規約処理の混乱
- フロントエンドとバックエンドの間で責任分離が不明確で、文書化も不足
- ABIライブラリの導入とプロトタイプ実装が進行中
- ターゲット機能の有効化に応じてABIが変わる問題がある
-
ビルトイン関数およびlibcalls管理の不一致
- TargetLibraryInfoとRuntimeLibcallsが分離されており、一貫性が不足
- ランタイムライブラリの種類(libgcc、compiler-rtなど)に応じた可用性を認識できない
- Rustなど外部ランタイム向けのカスタマイズポイントがない
-
Context / Module構造の非効率性
- 型・定数はContextに、関数・グローバルはModuleに存在
- データレイアウトにアクセスできず、定数畳み込みなどで不便
- コンテキスト間リンクができず、構造の単純化が必要
-
LICM(ループ不変コード移動)によるレジスタ圧迫
- コストモデルなしで無条件にhoistを実行
- バックエンドで再度sinkしないため、スピル・リロード増加につながる
結論
- 列挙された問題はLLVMの成熟度と規模に由来する構造的課題であり、
プロジェクトの品質とコントリビューター体験を改善する機会として提示されている - 一部領域(ビルド最適化、ABIライブラリ、性能追跡など)ではすでに改善作業が進行中
- 全体としてLLVMは依然として強力だが、継続的なリファクタリングと仕様整備が不可欠
1件のコメント
Hacker Newsのコメント
文章全体がよく整理されていて、とても共感した。
最近は LLVM IR の安定性 がかなり高くなっている。Fil-C を LLVM 17 から 20 に1日でリベースした。
他のプロジェクトでも複数の LLVM バージョンにまたがって同じ pass を維持してきたが、大きな問題はなかった。
ただし LICM のレジスタ圧迫 は、とくに C/C++ 以外のソースで深刻だ。問題は LICM 自体というより、regalloc が rematerialize をもっと上手く扱えるようにすべき点にある気がする
フロントエンド開発者がさまざまな設定を ベンチマーク して最適値を選べるよう、オプションをもっと開放してほしい
各ツールやコンポーネントがそれぞれ独自のルールを持っているので、バージョン間の差異が出るのはむしろ自然に思える。もしかすると私の理解が間違っているのだろうか、という疑問がある
LLVM 18 を macOS でビルドしようとして compiler-rt の担当者に boolean を1つ変えてほしいと頼んだところ、「heated」な issue としてロックされ、そのまま4年間未解決のままだ。
それでも LLVM は今でも大好きだ。clang-tidy, ASAN, UBSAN, LSAN, MSAN, TSAN は本当に素晴らしい。
C/C++ コードを書くのに clang-tidy を使わないのは間違った選択だと思う。
ただし -fbounds-safety は AppleClang にしかなく、MSAN/LSAN は LLVM Clang にしかない。Xcode には clang-tidy、clang-format、llvm-symbolizer もない。
結局 macOS では自分で Darwin LLVM をビルド して使うしかなかった。
Linux 側も混乱している。RHEL は libcxx を提供しないが、Fedora は提供する。しかし MSAN 用に instrument された libcxx はどのディストリビューションにもない。
Fedora はほぼそこまで来ているが、依然として compiler-rt を手動でビルドしなければならない
最近の LLVM 関連の議論を見ていて、C ではなく LLVM IR から始まる実行可能なテストスイート がぜひ必要だと感じた。
バックエンドを直接作ってみると、SelectionDAG や GlobalISel に関する文書が不足しており、演算の意味も曖昧で、誤って実装しやすい
C API は LLVM では取り残された存在のように感じる。多くのオプションや opt pass が公開されていない。
ほとんどの開発者が C++ API を直接使うので、C API は後回しにされ、結局 二級市民 のままになってしまう
コードレビューは即時の報酬につながらないため、人々があまりやりたがらない。
レビューにも貢献クレジットを与えれば、動機付けになるかもしれない。
6年前、8GB の Dell 9360 ノート PC で LLVM をよくビルドしていた。リンク並列度を下げればメモリ制限内で可能だった。
今でも 8GB でビルドできるのか気になる。
LLVM の初期には GCC より速いコンパイル速度 が強みだった。
いまや LLVM から23年が経ったが、その後にまた新しいものが出てくるのか気になる。
LLVM IR を使わない Cranelift のような代替もある(Cranelift GitHub)
ABI と呼び出し規約の処理 が最大の苦痛だ。
コンパイラフロントエンドで引数の受け渡しを直接管理しなければならず、ときには レジスタ数の計算 まで必要になる
記事では「フロントエンドは安定した C API によって守られている」とされていたが、実際にはそうではない。
安定している API もあるが、Orc のような部分は頻繁に変わる。
LLVM には issue レビュー体制 がほとんどないように見える。私が上げたバグレポートも何年も処理されていない