このページの目次
GCC と Clang の内部
カバー範囲: コンパイルパイプライン (フロントエンド/ミドルエンド/バックエンド) → IR (GIMPLE/LLVM IR) → LTO → PGO → Sanitizer → コンパイラ最適化一覧 対象: GCC 12+, Clang 15+, ユーザー空間コンパイル
コンパイルパイプライン
flowchart TD
SRC["📄 C ソースコード"]
SRC --> FRONTEND["🔍 フロントエンド (言語依存)<br/>プリプロセス + 字句解析 + 構文解析 + 意味解析"]
FRONTEND --> AST["🌳 抽象構文木 (AST)"]
AST --> MIDDLE["⚙️ ミドルエンド (言語非依存、アーキテクチャ非依存)<br/>GIMPLE (GCC) または LLVM IR (Clang)<br/>→ 最適化パス: 不要コード削除、ループ最適化、ベクトル化、..."]
MIDDLE --> BACKEND["🔧 バックエンド (アーキテクチャ依存)<br/>レジスタ割り当て + 命令選択 + 命令スケジューリング"]
BACKEND --> ASM["📝 対象アセンブリ (.s)"]
ASM --> ASSEMBLER["🔗 アセンブラ"]
ASSEMBLER --> OBJ["📦 オブジェクトファイル (.o)"]
classDef src fill:#e3f2fd,stroke:#1565c0
classDef step fill:#f3e5f5,stroke:#7b1fa2
classDef ir fill:#fff3e0,stroke:#ef6c00
classDef out fill:#e8f5e9,stroke:#2e7d32
class SRC,OBJ src
class FRONTEND,BACKEND,ASSEMBLER step
class MIDDLE ir
class AST,ASM out
GCC GIMPLE と LLVM IR
GCC GIMPLE (GNU Compiler Collection):
3アドレス形式 → 約200個の最適化パス
形式: 関数 → ベーシックブロック → GIMPLE文
-fdump-tree-all を使用して各最適化パスの出力を観察
LLVM IR (Clang):
SSA形式 → 高級言語に近い
-emit-llvm → .ll テキストを出力 → 可読性が高い
opt → 独立した最適化ツール (clangとは独立)
llc → 独立したコードジェネレータ
LTO: リンク時最適化
# GCC LTO:
# Thin LTO (Clang、高速なインクリメンタル LTO):
# LTO の典型的な効果:
# - ファイルを跨ぐ小規模関数のインライン化 (コストモデルで数千〜数万の関数を評価可能)
# - 不要コードの削除 (プログラム全体を解析 → 未呼び出し関数を削除)
# - 定数伝播 (ファイル間を跨ぐ定数の追跡)
# バイナリサイズ: ↓5-15%, パフォーマンス: ↑2-5%
PGO: プロファイル誘導型最適化
# 1. インストルメンテーション (計測):
# 2. 再コンパイル (プロファイルで誘導):
# PGO の典型的な効果:
# - ブランチ予測の最適化 (ホットパス上のコード再配置)
# - インライン化判断の精度向上 (頻繁に呼び出される関数 → インライン化)
# - レジスタ割り当ての最適化 (ホット変数の優先度が高い)
# パフォーマンス: ↑5-15%
Sanitizer: 実行時エラー検出
# Address Sanitizer (ASAN): ヒープ境界外アクセス、UAF、スタックオーバーフロー
# Undefined Behavior Sanitizer (UBSAN):
# 検出対象: 整数オーバーフロー、シフト範囲外、null dereference、型アライメント
# Thread Sanitizer (TSAN): データ競合
# Memory Sanitizer (MSAN): 未初期化読み込み (Clang のみ)
# オーバーヘッド:
# ASAN: 約2倍の低速化、約2倍のメモリ使用
# TSAN: 約5-10倍の低速化、約5-10倍のメモリ使用
# UBSAN: 約1.2倍の低速化 (最も軽量、本番環境でも利用可能)
一般的な最適化オプション
# 特定の最適化:
-march=native # 本机CPU向けに最適化 (AVX2/BMI/... を使用)
コンパイル成果物の分析
# 最適化結果の観察:
|
# バイナリ分析:
| |
参考
- ドキュメント: GCC Internals Manual, LLVM Language Reference
- LWN: "LTO and PGO", "Sanitizers in GCC and Clang"
キーワード: GCC, Clang, GIMPLE, LLVM IR, LTO, ThinLTO, PGO, ASAN, UBSAN, TSAN, 最適化フラグ