# LLVM Project コードリーディングガイドライン

## はじめに

このガイドラインは、LLVM Projectのコードベースを効率的に理解するための手引きです。
C/C++に精通していないエンジニアでも、段階的に学習できるよう構成されています。

**対象読者:**
- プロジェクトに新規参画するエンジニア
- 他言語からの経験者
- コードレビューを行う担当者

---

## 1. 言語基礎

> このセクションでは、C++の基本構文とLLVMで使用される概念を解説します。

### 1.1 プログラム構造

LLVMはC++17を基本として記述されています。ファイルは以下の標準的な構造を持ちます。

```cpp
// ファイル: llvm/lib/IR/Value.cpp:1-37
//===-- Value.cpp - Implement the Value class -----------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements the Value, ValueHandle, and User classes.
//
//===----------------------------------------------------------------------===//

#include "llvm/IR/Value.h"
#include "LLVMContextImpl.h"
#include "llvm/ADT/DenseMap.h"
// ... その他のインクルード

using namespace llvm;
```

**構造の説明:**
1. ファイルヘッダー（ライセンス情報）
2. ファイルの目的を説明するコメント
3. インクルードディレクティブ
4. 名前空間の使用宣言
5. 実装本体

### 1.2 データ型と変数

LLVMでは独自のデータ型を多用します。

```cpp
// ファイル: llvm/include/llvm/ADT/StringRef.h:55-71
/// StringRef - Represent a constant reference to a string
class LLVM_GSL_POINTER StringRef {
public:
  static constexpr size_t npos = ~size_t(0);
  using iterator = const char *;
  using const_iterator = const char *;
  using size_type = size_t;
  using value_type = char;

private:
  /// The start of the string, in an external buffer.
  const char *Data = nullptr;
  /// The length of the string.
  size_t Length = 0;
};
```

**主要な独自データ型:**
- `StringRef`: 文字列への参照（コピーなし）
- `ArrayRef`: 配列への参照
- `SmallVector`: スタックに最適化された可変長配列
- `DenseMap`: 高速なハッシュマップ

### 1.3 制御構造

LLVMではイテレーターパターンとRANGE-BASEDループが多用されます。

```cpp
// ファイル: llvm/lib/Analysis/LoopInfo.cpp:67-68
bool Loop::hasLoopInvariantOperands(const Instruction *I) const {
  return all_of(I->operands(), [&](Value *V) { return isLoopInvariant(V); });
}
```

**特徴的なパターン:**
- `for (auto &X : container)` - 範囲ベースforループ
- `all_of`, `any_of`, `none_of` - STLアルゴリズム
- ラムダ式 `[&](...)` の活用

### 1.4 関数/メソッド定義

```cpp
// ファイル: llvm/lib/IR/Value.cpp:53-74
Value::Value(Type *ty, unsigned scid)
    : SubclassID(scid), HasValueHandle(0), SubclassOptionalData(0),
      SubclassData(0), NumUserOperands(0), IsUsedByMD(false), HasName(false),
      HasMetadata(false), VTy(checkType(ty)) {
  static_assert(ConstantFirstVal == 0, "!(SubclassID < ConstantFirstVal)");
  // ... 実装
}
```

**命名規則:**
- パラメータ名は小文字から開始
- 初期化子リストを使用
- `static_assert`によるコンパイル時検証

### 1.5 モジュール/インポート

```cpp
// ファイル: llvm/tools/llc/llc.cpp:15-67
#include "NewPMDriver.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/CodeGen/CommandFlags.h"
// ...
using namespace llvm;
```

**インクルードの規則:**
1. 関連するヘッダー
2. LLVMヘッダー（`llvm/`）
3. 標準ライブラリヘッダー（`<cassert>`等）

---

## 2. プロジェクト固有の概念

> このセクションでは、LLVM特有の概念を解説します。

### 2.1 フレームワーク固有の概念

#### LLVM IR (Intermediate Representation)

LLVMの核となる中間表現です。

```cpp
// ファイル: llvm/include/llvm/IR/Value.h:62-74
/// LLVM Value Representation
///
/// This is a very important LLVM class. It is the base class of all values
/// computed by a program that may be used as operands to other values.
/// Value is the super class of other important classes such as Instruction
/// and Function.
class Value {
  // ...
};
```

**主要な概念:**
- `Value`: 全ての計算結果の基底クラス
- `Instruction`: 単一の命令
- `BasicBlock`: 分岐のない命令の連続
- `Function`: 関数
- `Module`: コンパイル単位

#### Pass システム

最適化やコード生成を行うパスシステムです。

```cpp
// ファイル: llvm/include/llvm/Pass.h:95-99
/// Pass interface - Implemented by all 'passes'.  Subclass this if you are an
/// interprocedural optimization or you do not fit into any of the more
/// constrained passes described below.
class LLVM_ABI Pass {
  // ...
};
```

**パスの種類:**
- `ModulePass`: モジュール全体に対する変換
- `FunctionPass`: 関数単位の変換
- `LoopPass`: ループ単位の変換

### 2.2 プロジェクト独自のパターン

#### RTTI代替システム

LLVMはC++ RTTIを使用せず、独自のシステムを使用します。

```cpp
// ファイル: llvm/include/llvm/IR/Value.h:76
const unsigned char SubclassID;   // Subclass identifier (for isa/dyn_cast)
```

使用例:
```cpp
if (const Instruction *I = dyn_cast<Instruction>(V))
  return !contains(I);
```

- `isa<T>(V)`: VがT型かどうかを判定
- `cast<T>(V)`: Vを安全にT型にキャスト（失敗時はアサート）
- `dyn_cast<T>(V)`: 動的キャスト（失敗時はnullptr）

#### コマンドラインオプション

```cpp
// ファイル: llvm/lib/IR/Value.cpp:39-41
static cl::opt<bool> UseDerefAtPointSemantics(
    "use-dereferenceable-at-point-semantics", cl::Hidden, cl::init(false),
    cl::desc("Deref attributes and metadata infer facts at definition only"));
```

`cl::opt`を使用してコマンドラインオプションを宣言します。

---

## 3. 命名規則

> このセクションでは、プロジェクト全体で使用される命名規則を解説します。

### 3.1 ファイル・ディレクトリ命名

| パターン | 意味 | 例 |
|---------|------|-----|
| PascalCase.cpp | 実装ファイル | Value.cpp, LoopInfo.cpp |
| PascalCase.h | ヘッダーファイル | Value.h, Function.h |
| llvm-xxx | コマンドラインツール | llvm-objdump, llvm-ar |
| xxxPass | 最適化パス | LoopStrengthReducePass |

### 3.2 クラス・関数・変数命名

| プレフィックス/サフィックス | 意味 | 例 |
|---------------------------|------|-----|
| PascalCase | クラス名 | Value, Function, BasicBlock |
| camelCase | メソッド名 | getValue(), isLoopInvariant() |
| UpperCase | 定数/列挙 | ConstantFirstVal, PMT_Unknown |
| xxx_iterator | イテレーター型 | use_iterator, arg_iterator |
| xxxTy | 型名 | VTy (Value Type) |
| is/has/can | ブール値を返すメソッド | isUsedByMD, HasName, canBeOmittedFromSymbolTable |
| get | 値を取得するメソッド | getName(), getType() |
| set | 値を設定するメソッド | setName(), setMetadata() |

### 3.3 プログラム分類一覧

| 分類 | ディレクトリ | 説明 |
|-----|-------------|------|
| コアライブラリ | lib/ | LLVM本体の実装 |
| ヘッダー | include/ | 公開API |
| ツール | tools/ | コマンドラインユーティリティ |
| テスト | test/, unittests/ | テストコード |
| ドキュメント | docs/ | ドキュメンテーション |

---

## 4. ディレクトリ構造

> このセクションでは、プロジェクトのディレクトリ構造を解説します。

```
llvm-project/
├── llvm/                    # LLVMコアプロジェクト
│   ├── include/             # 公開ヘッダー
│   │   ├── llvm/            # C++ヘッダー
│   │   └── llvm-c/          # C言語バインディング
│   ├── lib/                 # ライブラリ実装
│   │   ├── IR/              # 中間表現
│   │   ├── Analysis/        # 解析パス
│   │   ├── Transforms/      # 変換パス
│   │   ├── CodeGen/         # コード生成
│   │   ├── Target/          # ターゲット固有コード
│   │   └── Support/         # サポートライブラリ
│   ├── tools/               # コマンドラインツール
│   ├── test/                # 回帰テスト
│   └── docs/                # ドキュメント
├── clang/                   # Clang C/C++フロントエンド
├── lld/                     # LLDリンカー
├── lldb/                    # LLDBデバッガー
├── libcxx/                  # C++標準ライブラリ
├── compiler-rt/             # ランタイムライブラリ
├── mlir/                    # MLIRプロジェクト
└── ... (その他サブプロジェクト)
```

### 各ディレクトリの役割

| ディレクトリ | 役割 | 主要ファイル |
|-------------|------|-------------|
| llvm/lib/IR/ | LLVM IR表現の実装 | Value.cpp, Function.cpp, Module.cpp |
| llvm/lib/Analysis/ | プログラム解析パス | LoopInfo.cpp, ScalarEvolution.cpp |
| llvm/lib/Transforms/ | 最適化変換パス | Scalar/, Vectorize/, IPO/ |
| llvm/lib/CodeGen/ | マシンコード生成 | SelectionDAG/, GlobalISel/ |
| llvm/lib/Target/ | ターゲット固有 | X86/, AArch64/, RISCV/ |
| llvm/lib/Support/ | 共通サポート | StringRef.cpp, CommandLine.cpp |
| llvm/tools/ | CLIツール | llc/, opt/, llvm-objdump/ |

---

## 5. アーキテクチャ

> このセクションでは、プロジェクトのアーキテクチャパターンを解説します。

### 5.1 全体アーキテクチャ

LLVMは多段のコンパイラパイプラインアーキテクチャを採用しています。

```
┌─────────────────────────────────────────────────────────────────────┐
│                          ソースコード                                │
│                     (C/C++/Fortran/etc.)                            │
└─────────────────────────────────────────────────────────────────────┘
                                  │
                                  ▼
┌─────────────────────────────────────────────────────────────────────┐
│                    フロントエンド (Clang等)                          │
│                 [clang/lib/, flang/lib/]                            │
└─────────────────────────────────────────────────────────────────────┘
                                  │
                                  ▼
┌─────────────────────────────────────────────────────────────────────┐
│                         LLVM IR                                      │
│                    [llvm/lib/IR/]                                    │
└─────────────────────────────────────────────────────────────────────┘
                                  │
                                  ▼
┌─────────────────────────────────────────────────────────────────────┐
│                   最適化パス (Passes)                                │
│      [llvm/lib/Analysis/, llvm/lib/Transforms/]                     │
└─────────────────────────────────────────────────────────────────────┘
                                  │
                                  ▼
┌─────────────────────────────────────────────────────────────────────┐
│                     コード生成                                       │
│                  [llvm/lib/CodeGen/]                                 │
└─────────────────────────────────────────────────────────────────────┘
                                  │
                                  ▼
┌─────────────────────────────────────────────────────────────────────┐
│                   ターゲット固有                                     │
│                  [llvm/lib/Target/]                                  │
└─────────────────────────────────────────────────────────────────────┘
                                  │
                                  ▼
┌─────────────────────────────────────────────────────────────────────┐
│                     機械語出力                                       │
│               (オブジェクトファイル/アセンブリ)                      │
└─────────────────────────────────────────────────────────────────────┘
```

### 5.2 レイヤー構成

| レイヤー | 責務 | 代表的なファイル |
|---------|------|-----------------|
| IR表現 | 中間表現のデータ構造 | llvm/lib/IR/Value.cpp |
| 解析 | プログラム解析 | llvm/lib/Analysis/LoopInfo.cpp |
| 変換 | 最適化と変換 | llvm/lib/Transforms/Scalar/ |
| コード生成 | 低レベルIR生成 | llvm/lib/CodeGen/ |
| ターゲット | アーキテクチャ固有 | llvm/lib/Target/X86/ |
| サポート | 共通ユーティリティ | llvm/lib/Support/ |

### 5.3 データフロー

1. **フロントエンド**: ソースコードをLLVM IRに変換
2. **最適化**: IRレベルでの最適化パスを適用
3. **コード生成**: IRをマシンIR (MIR)に変換
4. **ターゲット固有最適化**: アーキテクチャ固有の最適化
5. **出力**: オブジェクトファイルまたはアセンブリを生成

---

## 6. 主要コンポーネント

> このセクションでは、主要なコンポーネントとその連携を解説します。

### 6.1 エントリーポイント

#### llc (LLVM static compiler)

```cpp
// ファイル: llvm/tools/llc/llc.cpp:9-12
// This is the llc code generator driver. It provides a convenient
// command-line interface for generating an assembly file or a relocatable file,
// given LLVM bitcode.
```

主要なエントリーポイント:
- `llc`: ビットコードからマシンコードを生成
- `opt`: 最適化パスを実行
- `clang`: C/C++コンパイラドライバ

### 6.2 ビジネスロジック

#### Value クラス階層

```cpp
// ファイル: llvm/include/llvm/IR/Value.h:75
class Value {
  // 全ての値の基底クラス
};
```

継承階層:
```
Value
├── Argument        (関数引数)
├── BasicBlock      (基本ブロック)
├── User            (オペランドを持つ値)
│   ├── Constant    (定数)
│   └── Instruction (命令)
└── ...
```

### 6.3 データアクセス

#### Module クラス

```cpp
// llvm/include/llvm/IR/Module.h
class Module {
  // コンパイル単位全体を表現
  // 関数、グローバル変数、型定義を含む
};
```

### 6.4 ユーティリティ/共通機能

#### ADT (Abstract Data Types)

```cpp
// ファイル: llvm/include/llvm/ADT/StringRef.h:48-54
/// StringRef - Represent a constant reference to a string, i.e. a character
/// array and a length, which need not be null terminated.
///
/// This class does not own the string data, it is expected to be used in
/// situations where the character data resides in some other buffer.
```

主要なADT:
- `StringRef`: 文字列参照
- `ArrayRef`: 配列参照
- `SmallVector`: 小さな可変長配列
- `DenseMap`: 高速ハッシュマップ
- `SetVector`: 順序を保持する集合

---

## 7. よく使われるパターン

> このセクションでは、コード内で頻出するパターンを解説します。

### パターン一覧

| パターン | 説明 | 出現頻度 | 代表的なファイル |
|---------|------|---------|-----------------|
| RTTI代替 (isa/cast/dyn_cast) | 型判定と変換 | 高 | 全体 |
| Visitor パターン | IRの走査 | 高 | InstVisitor.h |
| Pass システム | 変換の抽象化 | 高 | Pass.h |
| Use-Def チェーン | 値の使用追跡 | 高 | Value.h |
| SSA形式 | 単一代入 | 高 | IR全体 |

### 各パターンの詳細

#### パターン1: RTTI代替 (isa/cast/dyn_cast)

**目的:** C++ RTTIを使わずに型判定と変換を行う

**実装例:**
```cpp
// ファイル: llvm/lib/Analysis/LoopInfo.cpp:61-64
bool Loop::isLoopInvariant(const Value *V) const {
  if (const Instruction *I = dyn_cast<Instruction>(V))
    return !contains(I);
  return true; // All non-instructions are loop invariant
}
```

**解説:** `dyn_cast<T>(V)`はVがT型ならT*を返し、そうでなければnullptrを返します。これによりifとキャストを同時に行えます。

#### パターン2: コマンドラインオプション

**目的:** ツールのオプションを宣言的に定義

**実装例:**
```cpp
// ファイル: llvm/tools/llc/llc.cpp:76-77
static cl::opt<std::string>
    InputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-"));
```

**解説:** `cl::opt`マクロを使用してグローバルにオプションを定義します。

#### パターン3: Use-Def チェーン

**目的:** 値の使用と定義を追跡

**実装例:**
```cpp
// ファイル: llvm/include/llvm/IR/Value.h:119-120
Type *VTy;
Use *UseList = nullptr;
```

**解説:** 各`Value`は自身を使用している`Use`のリストを持ちます。これにより、値の全ての使用箇所を効率的に走査できます。

---

## 8. 業務フロー追跡の実践例

> このセクションでは、実際の業務フローをコードで追跡する方法を解説します。

### 8.1 フロー追跡の基本手順

1. エントリーポイントを特定
2. 処理の流れを追跡（呼び出し関係を追う）
3. データの変換を確認
4. 最終的な出力を確認

### 8.2 フロー追跡の実例

#### 例1: LLVM IRからマシンコードへの変換

**概要:** llcツールがビットコードを読み込み、アセンブリを出力するまでの流れ

**処理フロー:**
```
llc main() → ParseIRFile() → TargetMachine::addPassesToEmitFile() → PassManager.run() → Output
```

**詳細な追跡:**

1. **エントリーポイント** (`llvm/tools/llc/llc.cpp`)
   ```cpp
   // llcのmain関数がビットコードを読み込む
   static cl::opt<std::string>
       InputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-"));
   ```

2. **IR読み込み** (`llvm/lib/IRReader/`)
   - `parseIRFile()`でビットコードまたはテキストIRを読み込み
   - `Module`オブジェクトを構築

3. **ターゲットマシン取得** (`llvm/lib/Target/`)
   - トリプル（例: x86_64-linux-gnu）に基づいてターゲットを選択
   - `TargetMachine`を構築

4. **パス実行** (`llvm/lib/CodeGen/`)
   - 最適化パスを適用
   - IRをマシンIRに変換
   - レジスタ割り当て
   - スケジューリング

5. **出力**
   - アセンブリまたはオブジェクトファイルを生成

### 8.3 フロー追跡チェックリスト

- [ ] エントリーポイントを特定したか
- [ ] 呼び出し関係を把握したか
- [ ] データの変換ポイントを確認したか
- [ ] エラーハンドリングを確認したか
- [ ] 最終的な出力を確認したか

---

## 9. 設計書の参照順序

> このセクションでは、プロジェクト理解のための設計書参照順序を案内します。

### 9.1 目的別ロードマップ

#### 全体像を把握したい場合
1. README.md
2. llvm/docs/GettingStarted.rst
3. llvm/docs/LangRef.rst (LLVM Language Reference)

#### 特定機能を理解したい場合
1. 該当コンポーネントのドキュメント
2. ヘッダーファイルのコメント
3. テストケース

#### 改修作業を行う場合
1. 該当機能のドキュメント
2. 関連するヘッダーファイル
3. 既存のテストケース

### 9.2 ドキュメント一覧

| ドキュメント | 概要 | 参照タイミング |
|-------------|------|---------------|
| GettingStarted.rst | ビルド方法、基本概念 | 最初に |
| LangRef.rst | LLVM IR言語仕様 | IR理解時 |
| WritingAnLLVMPass.rst | パス作成ガイド | パス開発時 |
| CodeGenerator.rst | コード生成解説 | バックエンド開発時 |

---

## 10. トラブルシューティング

> このセクションでは、コードリーディング時によくある問題と解決法を解説します。

### よくある疑問と回答

#### Q: isa/cast/dyn_castの違いは何ですか?
A:
- `isa<T>(V)`: VがT型かをboolで返す
- `cast<T>(V)`: 必ずキャスト成功前提、失敗時はアサート
- `dyn_cast<T>(V)`: 失敗時はnullptr、成功時はT*

#### Q: PassManager とは何ですか?
A: 最適化パスを管理・実行するフレームワークです。パスの依存関係を解決し、効率的な順序で実行します。

#### Q: テストはどこにありますか?
A:
- 回帰テスト: `llvm/test/`
- ユニットテスト: `llvm/unittests/`

### デバッグのヒント

1. **DEBUGマクロの活用**
   ```cpp
   LLVM_DEBUG(dbgs() << "Value: " << *V << "\n");
   ```
   `-debug`オプションで出力を有効化できます。

2. **統計情報の収集**
   ```cpp
   STATISTIC(NumReduced, "Number of reductions");
   ```
   `-stats`オプションで統計を表示できます。

3. **アサーションの活用**
   Debugビルドでは`assert()`が有効です。

---

## 付録

### A. 用語集

| 用語 | 説明 |
|-----|------|
| IR | Intermediate Representation（中間表現） |
| SSA | Static Single Assignment（静的単一代入形式） |
| Pass | 最適化や変換を行う処理単位 |
| Target | 対象アーキテクチャ（X86, ARM等） |
| Triple | ターゲット識別子（例: x86_64-linux-gnu） |
| BasicBlock | 分岐のない命令の連続 |
| CFG | Control Flow Graph（制御フローグラフ） |
| DAG | Directed Acyclic Graph（有向非巡回グラフ） |
| RTTI | Run-Time Type Information |

### B. ファイル一覧

| ファイル/ディレクトリ | 説明 | 主な内容 |
|---------------------|------|---------|
| llvm/include/llvm/IR/Value.h | 値の基底クラス | Value, User定義 |
| llvm/include/llvm/Pass.h | パス基底クラス | Pass, FunctionPass定義 |
| llvm/include/llvm/ADT/ | 抽象データ型 | StringRef, SmallVector等 |
| llvm/lib/Transforms/Scalar/ | スカラー最適化 | ループ最適化、定数畳み込み等 |
| llvm/lib/Target/X86/ | X86ターゲット | X86固有のコード生成 |

### C. 参考資料

- [LLVM公式ドキュメント](https://llvm.org/docs/)
- [Clang公式ドキュメント](https://clang.llvm.org/docs/)
- [LLVM Programmer's Manual](https://llvm.org/docs/ProgrammersManual.html)
- [Writing an LLVM Pass](https://llvm.org/docs/WritingAnLLVMPass.html)
- [LLVM Language Reference Manual](https://llvm.org/docs/LangRef.html)
