コンテンツにスキップ

LLVM/コンパイラ最適化技術

出典: フリー教科書『ウィキブックス(Wikibooks)』

LLVM は強力なコンパイラインフラストラクチャであり、多くの最適化技術を提供しています。本章では、LLVM の最適化手法をカテゴリ別に整理し、各手法の概要を説明します。

最適化の分類

[編集]

LLVM の最適化は、大きく以下のカテゴリに分類されます。

  • ローカル最適化(Local Optimization): 単一の基本ブロック内で完結する最適化
  • 関数内最適化(Function-Level Optimization): 関数内で完結する最適化
  • 関数間最適化(Interprocedural Optimization, IPO): 関数をまたいで行われる最適化
  • リンク時最適化(Link Time Optimization, LTO): コンパイル後、リンク時に適用される最適化

ローカル最適化(Local Optimization)

[編集]

定数伝播(Constant Propagation)

[編集]
  • 定数式を評価し、変数の値を計算済みにする。
  • -constprop パスを使用。

不要なコードの削除(Dead Code Elimination, DCE)

[編集]
  • 使用されない変数やコードを削除。
  • -dce パスを使用。

強畳み込み(Strength Reduction)

[編集]
  • x * 2x << 1 に置き換えるなど、計算コストの低い演算へ変換。
  • -instcombine パスを使用。

関数内最適化(Function-Level Optimization)

[編集]

ループ最適化(Loop Optimization)

[編集]
  • ループアンローリング(Loop Unrolling): ループの繰り返し回数を減らして分岐回数を減少。
  • ループ不変式移動(Loop Invariant Code Motion, LICM): ループ内で変化しない計算をループ外へ移動。

メモリアクセスの最適化

[編集]
  • 共通部分式除去(Common Subexpression Elimination, CSE): 同じ計算を複数回実行しないように最適化。
  • メモリアラインメントの最適化: 読み書きの際のアライメントを調整し、高速化。

関数間最適化(Interprocedural Optimization, IPO)

[編集]

インライン展開(Inlining)

[編集]
  • 小さな関数を呼び出し元に展開し、関数呼び出しのオーバーヘッドを削減。
  • -inline パスを使用。

関数間定数伝播(Interprocedural Constant Propagation, ICP)

[編集]
  • 関数の引数がコンパイル時に確定している場合、その値を元に最適化。
  • -ipconstprop パスを使用。

デッドグローバル除去(Global Dead Code Elimination, GDCE)

[編集]
  • 使用されないグローバル変数や関数を削除。
  • -globaldce パスを使用。

関数の統合(Function Merging)

[編集]
  • 似た関数を統合し、バイナリサイズを削減。
[編集]

ThinLTO

[編集]
  • 分散ビルドを活かしつつ LTO の恩恵を受ける。
  • -flto=thin を使用。

Full LTO

[編集]
  • 全体を対象に強力な最適化を適用。
  • -flto=full を使用。

最適化の適用方法

[編集]

LLVM では、以下のコマンドを用いて最適化を適用できます。

opt コマンドによる最適化

[編集]
opt -passes=inline -S input.ll -o output.ll

clang による最適化付きコンパイル

[編集]
clang -O2 -flto -c foo.c -o foo.o
clang -O2 -flto -c bar.c -o bar.o
clang -O2 -flto foo.o bar.o -o a.out

まとめ

[編集]

LLVM は多くの最適化技術を備えており、適切に活用することでパフォーマンスを向上できます。用途に応じた最適化を適用し、効率的なコードを生成しましょう。