# 機能設計書 114-llvm-ctxprof-util

## 概要

本ドキュメントは、LLVMプロジェクトにおけるコンテキストプロファイルユーティリティ「llvm-ctxprof-util」の機能設計を記述する。

### 本機能の処理概要

llvm-ctxprof-utilは、コンテキスチュアルプロファイル（Contextual Profile）データの形式変換を行うユーティリティツールである。YAMLテキスト形式とビットストリームバイナリ形式の間で相互変換を行う。コンテキスチュアルプロファイルは、関数の呼び出しコンテキストを考慮したプロファイル情報であり、より精密なPGO（Profile-Guided Optimization）を可能にする。

**業務上の目的・背景**：従来のPGOプロファイルは関数単位の情報しか持たないが、コンテキスチュアルプロファイルは呼び出し元のコンテキストを含む。これにより、同じ関数でも呼び出し元に応じて異なる最適化が可能になる。本ツールは、人間が読み書きできるYAML形式とコンパイラが使用するバイナリ形式の変換を提供し、テストやデバッグを容易にする。

**機能の利用シーン**：
- コンテキスチュアルプロファイルのテストデータ作成
- プロファイルデータのデバッグ・検証
- プロファイル形式の変換
- プロファイル内容の確認

**主要な処理内容**：
1. サブコマンド（fromYAML/toYAML）の判定
2. 入力ファイルの読み込み
3. 形式変換の実行
4. 出力ファイルへの書き込み

**関連システム・外部連携**：LLVM ProfileData/PGOCtxProfReader、PGOCtxProfWriterライブラリを使用。

**権限による制御**：特になし。ファイルシステムへのアクセス権限のみ必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | CLI | 主機能 | コマンドラインインターフェースによる操作 |

## 機能種別

データ変換

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| サブコマンド | enum | Yes | fromYAML または toYAML | 有効なサブコマンド |
| --input | string | No | 入力ファイル（デフォルト: 標準入力） | ファイル存在確認 |
| --output | string | No | 出力ファイル（デフォルト: 標準出力） | パス妥当性確認 |

### 入力データソース

**fromYAMLサブコマンド時:**
- YAML形式のコンテキスチュアルプロファイルファイル

YAML形式の構造:
```yaml
- Guid: <64bit整数>
  Counters: [<32bit整数>, ...]
  Contexts:
    - - Guid: ...
        Counters: [...]
```

**toYAMLサブコマンド時:**
- ビットストリーム形式のコンテキスチュアルプロファイルファイル

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| BitstreamProfile | binary | fromYAML時のビットストリーム出力 |
| YAMLProfile | text | toYAML時のYAMLテキスト出力 |

### 出力先

- 標準出力（デフォルト）
- 指定されたファイル（--outputオプション）

## 処理フロー

### 処理シーケンス

```
1. コマンドライン解析
   └─ サブコマンドとオプション取得
2. サブコマンド判定
   ├─ fromYAML: YAML→バイナリ変換
   │   ├─ 入力ファイル読み込み（テキストモード）
   │   ├─ 出力ファイルオープン
   │   └─ createCtxProfFromYAML実行
   └─ toYAML: バイナリ→YAML変換
       ├─ 入力ファイル読み込み（バイナリモード）
       ├─ 出力ファイルオープン
       ├─ PGOCtxProfileReader作成
       ├─ loadProfiles実行
       └─ convertCtxProfToYaml実行
3. 結果出力
4. エラーハンドリング
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[コマンドライン解析]
    B --> C{サブコマンド判定}
    C -->|fromYAML| D[YAML→バイナリ変換]
    C -->|toYAML| E[バイナリ→YAML変換]
    C -->|なし| F[ヘルプ表示]
    D --> G[入力ファイル読み込み]
    E --> H[入力ファイル読み込み]
    G --> I[出力ファイルオープン]
    H --> J[出力ファイルオープン]
    I --> K[createCtxProfFromYAML]
    J --> L[PGOCtxProfileReader作成]
    L --> M[loadProfiles]
    M --> N[convertCtxProfToYaml]
    K --> O{エラー?}
    N --> O
    O -->|Yes| P[エラー出力]
    O -->|No| Q[正常終了]
    P --> R[終了 code=1]
    Q --> S[終了 code=0]
    F --> R
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | サブコマンド必須 | fromYAMLまたはtoYAMLのいずれかが必要 | 起動時 |
| BR-002 | デフォルト入出力 | 入出力ファイル未指定時は標準入出力を使用 | オプション未指定時 |
| BR-003 | YAML形式 | GuidとCountersは必須、Contextsは任意 | YAML入力時 |

### 計算ロジック

特になし。形式変換のみ。

## データベース操作仕様

該当なし（ファイルベースのツール）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ファイルエラー | 入力ファイルが開けない | エラーメッセージ出力後終了 |
| - | 出力エラー | 出力ファイルが開けない | エラーメッセージ出力後終了 |
| - | 形式エラー | 入力形式が不正 | エラーメッセージ出力後終了 |

### リトライ仕様

リトライ処理なし

## トランザクション仕様

該当なし

## パフォーマンス要件

特に規定なし

## セキュリティ考慮事項

- 入力ファイルの検証

## 備考

- YAMLスキーマはテスト用途を想定
- ビットストリーム形式はコンパイラ内部で使用

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

コンテキスチュアルプロファイルは、GUIDで識別される関数とその呼び出しコンテキストを表現する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | PGOCtxProfReader.h | `llvm/include/ProfileData/PGOCtxProfReader.h` | プロファイルデータ構造 |

**読解のコツ**: Guid（64bit）は関数識別子、Countersは基本ブロックカウンター、Contextsは呼び出し先のプロファイル。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | llvm-ctxprof-util.cpp | `llvm/tools/llvm-ctxprof-util/llvm-ctxprof-util.cpp` | main関数（86-108行目） |

**主要処理フロー**:
1. **87行目**: コマンドライン解析
2. **88行目**: ExitOnError設定
3. **100-101行目**: FromYAMLサブコマンド処理
4. **103-104行目**: ToYAMLサブコマンド処理
5. **106-107行目**: ヘルプ表示

#### Step 3: 変換処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | llvm-ctxprof-util.cpp | `llvm/tools/llvm-ctxprof-util/llvm-ctxprof-util.cpp` | convertFromYaml関数（49-65行目）、convertToYaml関数（67-83行目） |

**convertFromYaml処理フロー**:
- **50-53行目**: 入力ファイル読み込み（テキストモード）
- **55-62行目**: 出力ファイルオープン
- **64行目**: createCtxProfFromYAML呼び出し

**convertToYaml処理フロー**:
- **68-70行目**: 入力ファイル読み込み（バイナリモード）
- **72-75行目**: 出力ファイルオープン
- **76-79行目**: PGOCtxProfileReader作成とloadProfiles
- **80行目**: convertCtxProfToYaml呼び出し

### プログラム呼び出し階層図

```
main()
    │
    ├─ cl::ParseCommandLineOptions
    │
    ├─ FromYAML? ──▶ convertFromYaml()
    │                    │
    │                    ├─ MemoryBuffer::getFileOrSTDIN
    │                    ├─ raw_fd_ostream
    │                    └─ createCtxProfFromYAML()
    │
    └─ ToYAML? ──▶ convertToYaml()
                       │
                       ├─ MemoryBuffer::getFileOrSTDIN
                       ├─ raw_fd_ostream
                       ├─ PGOCtxProfileReader::loadProfiles()
                       └─ convertCtxProfToYaml()
```

### データフロー図

```
[fromYAML]
YAMLファイル ───▶ createCtxProfFromYAML ───▶ ビットストリームファイル
    │                    │
    │        ┌───────────┘
    │        ▼
    │   YAML解析
    │        │
    │        ▼
    └── ビットストリーム生成

[toYAML]
ビットストリームファイル ───▶ PGOCtxProfileReader ───▶ YAMLファイル
         │                         │
         │           ┌─────────────┘
         │           ▼
         │    loadProfiles()
         │           │
         │           ▼
         └── convertCtxProfToYaml()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| llvm-ctxprof-util.cpp | `llvm/tools/llvm-ctxprof-util/` | ソース | メイン処理 |
| PGOCtxProfReader.h | `llvm/include/ProfileData/` | ヘッダ | プロファイル読み込み |
| PGOCtxProfWriter.h | `llvm/include/ProfileData/` | ヘッダ | プロファイル書き込み |
| CMakeLists.txt | `llvm/tools/llvm-ctxprof-util/` | 設定 | ビルド設定 |
