
2026/02/01 6:44
**LLVM 2025年の動向**
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
LLVM の低レベルポインタとメモリ処理が改修され、言語全体でパフォーマンス、安全性、および保守性が向上します。
主な変更点は新しい
インフラストラクチャです: 以前は複数の定数オフセットを使用していた GEP が単一オフセット形式に分割され、共通接頭辞 CSE を可能にし、専用ptradd命令への道を開きます。残りの作業としては、定数スケーリングまたは別個の乗算をサポートするかどうかの決定、IRBuilder で新しい形式を強制すること、および型ベースの GEP 構築を防止することが挙げられます。ptradd副作用のない
命令 が CHERI アーキテクチャ用に追加され、ポインタのアドレス部分のみを返し、由来情報は公開しません。ptrtoaddrライフタイム固有関数が強化されました: これらは
のみ適用され、サイズ引数が削除され、最適化パス中に発生した誤用を排除します。allocaキャプチャ追跡が改良されました:ストアに対して
メタデータを使用し、アドレスキャプチャと由来キャプチャを区別することで、非可変参照の Rust エイリアス解析が向上します。!capturesABI ライブラリプロトタイプ は GSoC プロジェクトで作成され、より豊富な ABI 型システムを使用して関数署名を低減し、重複するフロントエンド作業を削減します。
Clang と LLVM 間の一貫性チェック がアラインメントデータを強制し、重複レイアウト定義を除去して、Rust およびその他のフロントエンド向けにクロスツールチェーンの信頼性を高めます。
に対する アサーション が拡張され、誤った符号付で発生した APInt の不正コンパイルを検出し、最適化パス中に現れた少なくとも 2 件の不正コンパイルを修正しました。ConstantInt::get()コンパイル時のパフォーマンス改善には、約 0.25 % の SCCP ワークリスト向上、約 0.35 % の
速度向上、および型割り当てサイズの約 0.25 % 特化が含まれます。デバッグラインテーブル発行と Clang AST の変更もビルド時間を約 1–2.6 % 向上させました。getBaseObjectSize()新しい最適化として、複数のストアを結合する store‑merge、定数範囲推論のための非インタープロシージャ SCCP における
、そしてほとんど使われない assume を削除するパスが追加されました。PredicateInfo1Rust の統合は LLVM 20 から LLVM 21 に移行し、非可変参照の読み取り専用キャプチャ、alloc‑variant‑zeroed 属性最適化、および by‑value 引数の
マークといった新機能を活用します。dead_on_returnパッケージング作業はモノリシックビルドへ移行し、現在は mlir、polly、bolt、libcxx、flang with PGO を含みます。メイン LLVM と互換性パッケージをシンボリックリンクで統合しようと試みましたが、RPM の制限により失敗し、そのようなシンリンク戦略を避ける決定に至りました。
本文
2026年です。いつものように、年次まとめブログを書きます。少し遅れていますが、やはり1月であることには感謝します!今回のまとめは、自分自身の作業についてであり、重要な項目や大枠のみを扱います。
過去数年
- 2024
- 2023
- 2022
ptradd
過去3年間にわたり、
ptradd マイグレーションの進捗は緩やかでした。この変更の目的は、型ベースの getelementptr(GEP)表現から、ポインタに整数オフセットを加算するだけの ptradd 命令へ移行することです。
年初には、定数オフセット GEP を
getelementptr i8, ptr %p, i64 OFFSET の形で正規化し、これは ptradd と同等でした。
今年の進捗: すべての GEP を単一オフセットに正規化。
例:
getelementptr [10 x i32], ptr %p, i64 %a, i64 %b → 2つの命令に分割。これにより、
ptradd は「1 つのオフセット引数しか受け取らない」設計に近づき、共通接頭辞 CSE(Common Subexpression Elimination)も可能になります。
作業は段階的に行いました:
- 複数変数インデックスを分割。
- 定数インデックスを切り離す。
- 先頭のゼロインデックスを除去。
主な労力は回帰防止でした:多くの変換が単一 GEP のみならず、GEP チェーン全体に対しても動作するよう拡張されました ― これは
ptradd マイグレーションとは別に有用です。
残りタスク:
が定数スケーリング係数をサポートすべきか、または乗算を別途要求すべきか決定。ptradd- 正規化から「新形式の使用」を必須化へ移行(IRBuilder で生成し、型ベース形式は禁止)。
ptrtoaddr
LLVM 22 では
ptrtoaddr 命令が導入されました。これは ptrtoint に似ていますが:
- プロヴァナンスを露出しない (
vsaddr()
)expose_provenance() - ポインタの「アドレス部分」だけを返す(CHERI ポインタはメタデータを持つため重要)
副作用のない変換は LLVM のプロヴァナンスストーリーに不可欠です。類似命令が 2 種類あることで既存最適化を慎重に調整する必要がありました。私はこの作業を担当し、
ptrtoaddr は主要な最適化でサポートされるようになりました。
ライフタイム・イントリニシア(Lifetime Intrinsics)
スタック確保は
alloca を使い、通常エントリブロックに配置します。これらのライフタイムは
lifetime.start/end イントリニシアでマークし、スタックカラーリングを有効化しています。
2つの大きな変更:
- ライフタイム・イントリニシアは
のみ適用可能に。以前は任意ポインタ(関数引数など)にも使用でき、スタックカラーリングと互換性がありませんでした。alloca - ライフタイムのサイズ引数を削除。実際利用されておらず、スタックカラーリングも無視していました。
これらの修正で、非
alloca ポインタに対する誤用が多く明らかになり(しばしば PHI ノードの裏側)、alloca 間の生存期間と重複を効率的に判定するさらなる作業が残っています。
キャプチャ追跡(Capture Tracking)
昨年から継続した改善です:
- ポインタのアドレスキャプチャとプロヴァナンスキャプチャを区別。プロヴァナンスのみが解析不能なメモリ副作用を引き起こします。
- アライアス分析はプロヴァナンスキャプチャだけを確認し、読み取り専用キャプチャを使用。
- ストアに
メタデータを追加(Rust の!captures
などの最適化に有効)。println!()
これが完全に活用できるかは、Rust のアライアスモデルに関する未解決問題に依存します。
ABI
LLVM のプラットフォーム ABI ハンドリングは脆弱です。フロントエンドは各ターゲットごとに複雑な呼び出し規約を再実装せざるを得ませんでした。そこで、Clang QualTypes よりも単純化した「ABI 型システム」を取り込み、関数署名を LLVM IR に下位変換する ABI ライブラリの提案を行いました。
が実装したプロトタイプは x86‑64 SystemV ABI で動作し、追加オーバーヘッドはほぼありません。vortex73- このライブラリを upstream へ統合する作業が進行中です。
その他の作業:
- Clang と LLVM 間の重複型アラインメントデータを排除。
- CC 下位変換に元の「非合法化された」引数型を露出し、ターゲット固有のハック(例:MIPS fp128 libcalls)を簡素化。
ConstantInt アサーション
uint64_t から任意精度整数 (APInt) を構築する際に、値が N ビットに収まることを確認するアサーションを導入しました。初期は ConstantInt::get() を除外して範囲を狭めていましたが、誤コンパイルが発覚。ConstantInt::get() への拡張で数件の問題を修正し、更に 2 件の誤コンパイルも検出。
コンパイル時間(Compilation‑time)
今年はほとんど作業がありませんでした。外部からの活動も少なめです。
主なポイント:
- AArch64 設定を追加 (x86 より 10–20 % 遅い)。原因は GlobalISel vs FastISel、コード生成時のアライアス分析。
- 最適化:
- SCCP ワークリスト管理(約 0.25 % 改善)。
関数(getBaseObjectSize()
の高コストを回避)で約 0.35 % 改善。__builtin_object_size- 特化型サイズ計算(約 0.25 % 改善)。
他の貢献者のハイライト:
- デバッグ行テーブル出力最適化(約 1 % 速く)。
- Clang AST のネスト名スペシファイア表現を変更し、ビルド時間を約 2.6 % 改善。
最適化(Optimizations)
大きな IR 変更が必要ない限り、直接最適化作業はあまり行いません。ほとんどは他者に委ねます。
最近の作業:
- ストアマージュ最適化:複数ストアを単一大きさのストアへ統合(以前はバックエンドでヒット&ミス)。
- 非 interprocedural SCCP で
を有効化し、分岐と仮定から導かれる定数範囲に基づく信頼できる最適化を可能に。PredicateInfo1
の速度向上も実装し、総合的には約 0.1 % コンパイル時間の軽微な回帰。PredicateInfo - 「unlikely assumes」をドロップするパスを実装。仮定が増えると最適化品質が低下する問題に対処。
Rust
Rust は LLVM 20 → LLVM 21 へ更新しました。両方ともスムーズに移行できましたが、LLVM 21 で BOLT インストゥルメンテーションの誤コンパイルが発生し、ホストツールチェーンを更新して修正。
新しい LLVM 機能使用例:
- 読み取り専用キャプチャ(非可変参照)でメモリ最適化信頼性向上。
属性によりalloc-variant-zeroed
→__rust_alloc + memset
を最適化(LTO で属性発行問題を解決)。__rust_alloc_zeroed- 値渡し引数を
とマーク。dead_on_return - ポインタ算術に
を使用。getelementptr nuw
パッケージング
Red Hat の LLVM チームは Fedora、CentOS Stream、および RHEL でパッケージ管理を担当しています。日次スナップショットビルドで作業し、新しいメジャーリリースでは単にバージョン番号を上げるだけが目標ですが、実際にはそれほど簡単ではありません。
今年の成果:
- mlir, polly, bolt, libcxx, flang をモノリシックビルドへ統合(libclc はまだ別)。
- PGO サポートを追加。
- メイン LLVM パッケージと
互換パッケージ間の一貫性向上を試みたが、RPM の制限に直面:アップグレード時にディレクトリをシンボリックリンクで置き換えられない、32bit/64bit パッケージを同時インストールできない。最終的にはシンボリックリンクの向きを逆転させる形に。教訓は:RPM ではシンボリックリンクを避けること。llvmNN
LLVM エリアチーム & プロジェクト評議会
新しいガバナンス(選出されたエリアチーム)を採用しました。私は
fhahn と arsenm と共に LLVM エリアチームに選出され、RFC の議論を行うため 2 週間ごとにミーティングを実施。一般的には手を離し、必要時のみ明確化を求めます。
主な議題:
- 浮動小数点 min/max の意味(最近解決)。
- デラインリゼーションの課題(一般的な苦情)。
エリアチーム長としてプロジェクト評議会にも参加し、AI ポリシー、必須プルリクエスト、sframe 上流化などの論争を討議。進展があり、AI ポリシーは現在ライブです。
その他
- LLVM のプロヴァナンスモデルで正確性ギャップを埋めるため、正式な仕様作業グループを設立(現行焦点:バイト型)。
- LLVM C API でのグローバルコンテキストを非推奨化。
- マスク付きメモリイントリニシアでのアラインメント表記を変更。
- メモリ内
表現を簡素化し、さらなる変更を提案。blockaddress
最後に、昨年約 2 500 件のプルリクエストをレビューしましたが、自分のレビューキューには追いつきませんでした。