compiler-optimizations-deep について
コンパイラエンジニアや性能重視の開発者向けに、ベクトル化やレジスタ割り当てから PGO、リンク後の BOLT まで、コンパイラフラグを超える最適化段階を解説するスキルです。
主な機能
- 01コンパイラパイプラインの概要
- 02ベクトル化失敗の切り分け
- 03レジスタ割り当てとスピル
- 04Clang の PGO ワークフロー
- 05リンク後の BOLT 最適化
- 06最適化パス間の相互作用
活用シーン
- 01LLVM がループをベクトル化できない原因の調査
- 02レジスタ圧迫とスタックスピルの説明
- 03PGO や BOLT の導入計画
- 04GCC と Clang の出力比較
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ mohitmishra786/ low-level-dev-skills --skill compiler-optimizations-deepインストール後、Claude Code で/compiler-optimizations-deepを入力して読み込まれたか確認します。
詳細
コンパイラー最適化(詳細)
目的
フラグによる最適化を超えて、中間レベルIRの最適化、レジスター割り当て、命令選択とスケジューリング、ベクトル化の境界、PGO、リンク後のBOLTについて説明し、skills/compilers/pgo とLLVM/GCCの内部処理をつなぎます。
使用する場面
-O3でもホットループがベクトル化されない- レジスター圧力によってスピルが発生する理由を教える
- PGOまたはBOLTの導入を計画する
- パス間の相互作用(例:ベクトル化の前にLICMを実行)を理解する
ワークフロー
1. コンパイラーパイプラインの概要
Frontend → LLVM IR / GCC GIMPLE
├── Mid-level: DCE, GVN, LICM, inlining
├── Loop opts: unroll, vectorize
├── Codegen prep: legalize types
├── Instruction selection (DAG → machine ops)
├── Register allocation (greedy, linear scan)
└── Peephole / scheduling
2. ベクトル化失敗の原因調査
clang -O3 -Rpass=loop-vectorize -Rpass-missed=loop-vectorize foo.c
| 失敗の理由 | 一般的な対処法 |
|---|---|
| 反復回数が不明 | ループを剥がす/回数を明示する |
| 依存関係 | 並べ替える/アキュムレーターを分離する |
| ループ内の関数呼び出し | インライン化する、またはループ外に出す |
| アラインメントが不明 | __builtin_assume_aligned |
3. レジスター割り当ての考え方
生存期間が物理レジスター数を超えると、割り当て器はスタックスロットにスピルし、コストのかかるロード/ストアが発生します。生存期間を短くすると(変数の分割、再計算による値の再生成など)効果があります。
GCCとLLVMはどちらも、グラフ彩色の派生方式を使用します(LLVMの「greedy regalloc」)。
4. PGOワークフロー(Clang)
clang -fprofile-instr-generate -O2 -o app foo.c
./app # training workload
llvm-profdata merge default.profraw -o default.profdata
clang -fprofile-instr-use=default.profdata -O2 -o app_pgo foo.c
分岐配置、インライン化、ベクトル化のしきい値が改善されます。
GCCとBOLTについては、skills/compilers/pgo を参照してください。
5. BOLT(リンク後)
llvm-bolt -instrument app -o app.inst
./app.inst
llvm-bolt -data=perf.fdata -reorder-blocks=+ -o app.bolt app
リンカーの処理後に配置を最適化します。リロケーション(-Wl,--emit-relocs)が必要です。
6. LICMの例
ループ不変コード移動により、合法な場合は x * scale を内側のループの外に移動し、反復ごとの処理を減らします。
7. エージェントの使用方法
/compiler-optimizations-deep Why did LLVM fail to vectorize this reduction loop?
よくある問題
| 症状 | 原因 | 対処法 |
|---|---|---|
| PGOで効果がない | トレーニングデータが実際の入力を反映していない | 本番環境の入力に合わせる |
| BOLTがクラッシュする | バイナリーがストリップされている | シンボルとリロケーションを保持する |
| アセンブリーでスピルが発生する | レジスター圧力 | 生存期間を短くする |
-O3 の方が遅い | コードの肥大化/キャッシュ | -O2 またはPGOを試す |
| GCCとClangで結果が異なる | パスの順序が異なる | IRとアセンブリーを比較する |
関連スキル
skills/compilers/pgo— PGOとBOLTの詳細skills/compiler-internals/llvm-ir-and-passes— IRレベルの最適化skills/compiler-internals/code-generation-and-backends— ISelとバックエンドskills/computer-architecture/cpu-pipelines-and-hazards— スケジューリングの背景skills/low-level-programming/simd-intrinsics— 手動でのベクトル化
コメント
Markdown 対応