# 帳票設計書 16-ProfileQualityStats

## 概要

本ドキュメントは、BOLTによるプロファイルデータの品質統計情報レポートの設計仕様を定義する。PrintProfileQualityStatsパスは、入力プロファイルの品質を複数の観点から検証し、統計情報を報告する。

### 本帳票の処理概要

ProfileQualityStatsは、BOLTツールに入力されるプロファイルデータの品質を検証し、CFG継続性、コールグラフフロー保存性、関数CFGフロー保存性、例外処理使用率の4つの観点から統計情報を出力するレポートである。

**業務上の目的・背景**：プロファイルに基づく最適化（PGO/FDO）の効果は、入力プロファイルの品質に大きく依存する。サンプリングやプロファイル収集時の問題により、プロファイルにはノイズや不整合が含まれることがある。本レポートは、プロファイルの品質を定量的に評価し、最適化結果の信頼性を判断する材料を提供する。

**帳票の利用シーン**：
- BOLTによるバイナリ最適化前のプロファイル品質検証
- プロファイル収集プロセスの改善
- 最適化結果のデバッグ・分析

**主要な出力内容**：
1. CFG継続性チェック - 正の実行カウントブロックが到達可能か
2. コールグラフフロー保存性チェック - 関数呼び出し回数とCFGフローの一致
3. 関数CFGフロー保存性チェック - 各ブロックのインフロー/アウトフロー一致
4. 例外処理使用統計 - ランディングパッドの実行カウント比率
5. 各統計の95パーセンタイル値

**帳票の出力タイミング**：BOLTの`profile-quality-stats`パス実行時（`--print-profile-quality-stats`オプション）

**帳票の利用者**：性能エンジニア、コンパイラ開発者、バイナリ最適化担当者

## 帳票種別

品質統計レポート / 解析レポート

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| - | コマンドライン | N/A | `llvm-bolt --print-profile-quality-stats` |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | テキスト（標準出力） |
| 用紙サイズ | N/A |
| 向き | N/A |
| ファイル名 | N/A（標準出力） |
| 出力方法 | BC.outs()経由 |
| 文字コード | システムロケール依存 |

### 出力設定

| 項目 | 内容 |
|-----|------|
| 対象関数数 | デフォルト1000（`-top-functions-for-profile-quality-check`で変更可） |
| パーセンタイル | デフォルト95（`-percentile-for-profile-quality-check`で変更可） |
| 詳細出力 | `-v=1`で有効化 |

## 帳票レイアウト

### レイアウト概要

出力は以下の形式で表示される。

```
BOLT-INFO: profile quality metrics for the hottest N functions (reporting top M% values): function CFG discontinuity X.XX%; call graph flow conservation gap Y.YY%; CFG flow conservation gap Z.ZZ% (weighted) W.WW% (worst); exception handling usage A.AA% (of total BBEC) B.BB% (of total InvokeEC)
```

### 明細部（-v=1時）

```
abbreviations: EC = execution count, POS BBs = positive EC BBs
distribution of NUM(unreachable POS BBs) per function
  Length     : N
  MAX        : X
  TOP 1%     : Y
  ...
  MIN        : Z
```

### 出力項目

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | CFG discontinuity | CFG不連続性の95パーセンタイル | BFS解析 | パーセント |
| 2 | call graph flow conservation gap | コールグラフフロー保存ギャップ | フロー解析 | パーセント |
| 3 | CFG flow conservation gap (weighted) | 加重平均CFGフロー保存ギャップ | ブロック解析 | パーセント |
| 4 | CFG flow conservation gap (worst) | 最悪CFGフロー保存ギャップ | ブロック解析 | パーセント |
| 5 | exception handling usage | 例外処理使用率 | ランディングパッド | パーセント |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| プロファイル有効 | 関数に有効なプロファイルがある | Yes |
| 関数サイズ | 2ブロック以上 | Yes |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| 1 | 関数実行カウント | 降順 |

### 改ページ条件

N/A

## データベース参照仕様

### 参照テーブル一覧

本帳票はデータベースを使用せず、BOLTの内部データ構造から情報を取得する。

| データソース | 用途 | 取得方法 |
|-------------|------|---------|
| BinaryFunction | 関数情報 | BC.getBinaryFunctions() |
| BinaryBasicBlock | ブロック情報 | Function内イテレーション |
| FunctionLayout | レイアウト情報 | Function->getLayout() |
| BranchInfo | 分岐情報 | BB->branch_info() |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| FractionECUnreachable | SumUnreachableBBEC / SumAllBBEC | 浮動小数点 | CFG不連続性 |
| CallGraphGap | 1 - MIN(NetEntryOutflow, CallGraphInflow) / MAX(...) | 浮動小数点 | フロー保存ギャップ |
| WeightedGap | WeightedGapSum / WeightSum | 浮動小数点 | 加重平均 |
| Weight | log(EC * NumNonPseudos) | 対数 | 重み計算 |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[runOnFunctions開始] --> B[有効プロファイル関数収集]
    B --> C[実行カウントでソート]
    C --> D[上位N関数を選択]
    D --> E[computeFlowMappings]
    E --> F[printCFGContinuityStats]
    F --> G[printCallGraphFlowConservationStats]
    G --> H[printCFGFlowConservationStats]
    H --> I[printExceptionHandlingStats]
    I --> J{-v >= 1?}
    J -->|Yes| K[バケット別詳細出力]
    J -->|No| L[終了]
    K --> L
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| 有効関数なし | プロファイル付き関数が0 | (出力スキップ) | プロファイルデータの確認 |
| 対象関数0 | TopFunctions=0指定 | (出力スキップ) | オプション値の確認 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 上位1000関数 |
| 目標出力時間 | 関数数に比例（通常数秒） |
| 同時出力数上限 | 1 |

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

- 関数名が出力に含まれる可能性がある（-v=2以上）
- プロファイルの品質情報が漏洩してもセキュリティリスクは低い

## 備考

- MinBlockCount（500）以上のブロックのみworst gap計算対象
- MinLPECSum（50）以上の関数のみ例外処理統計対象
- 5つのバケットに分割した詳細統計も出力可能

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ProfileQualityStats.h | `bolt/include/bolt/Passes/ProfileQualityStats.h` | PrintProfileQualityStatsクラスの定義（84-93行目） |
| 1-2 | ProfileQualityStats.cpp | `bolt/lib/Passes/ProfileQualityStats.cpp` | FlowInfo構造体（47-53行目）とTotalFlowMapTy型定義（44-46行目） |

**読解のコツ**:
- `FlowInfo`は各種フローマップを保持する構造体
- `TotalFlowMapTy`は関数番号からブロック別フロー配列へのマップ

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ProfileQualityStats.cpp | `bolt/lib/Passes/ProfileQualityStats.cpp` | runOnFunctions（676-689行目）がエントリーポイント |

**主要処理フロー**:
1. **678-683行目**: 有効プロファイル関数をValidFunctionsに収集
2. **684-685行目**: 空チェックと早期リターン
3. **687行目**: printAll関数を呼び出し

#### Step 3: 各統計出力関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ProfileQualityStats.cpp | `bolt/lib/Passes/ProfileQualityStats.cpp` | printCFGContinuityStats（94-195行目）：CFG継続性統計 |
| 3-2 | ProfileQualityStats.cpp | `bolt/lib/Passes/ProfileQualityStats.cpp` | printCallGraphFlowConservationStats（197-284行目）：コールグラフフロー保存統計 |
| 3-3 | ProfileQualityStats.cpp | `bolt/lib/Passes/ProfileQualityStats.cpp` | printCFGFlowConservationStats（286-404行目）：CFGフロー保存統計 |
| 3-4 | ProfileQualityStats.cpp | `bolt/lib/Passes/ProfileQualityStats.cpp` | printExceptionHandlingStats（406-472行目）：例外処理統計 |

**主要処理フロー**:
- **94-174行目**: BFSで正の実行カウントブロックの到達可能性を計算
- **197-273行目**: 関数エントリフローとコールグラフフローの差分を計算
- **286-381行目**: 各ブロックのインフロー/アウトフロー差分を計算

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

```
runOnFunctions (ProfileQualityStats.cpp:676)
    │
    ├─ shouldOptimize (ProfileQualityStats.cpp:669)
    │      └─ hasValidProfile チェック
    │
    └─ printAll (ProfileQualityStats.cpp:608)
           │
           ├─ llvm::sort (実行カウントでソート)
           │
           ├─ computeFlowMappings (ProfileQualityStats.cpp:474)
           │      ├─ TotalIncomingFlows計算
           │      ├─ TotalOutgoingFlows計算
           │      ├─ TotalMaxCountMaps計算
           │      ├─ TotalMinCountMaps計算
           │      └─ CallGraphIncomingFlows計算
           │
           ├─ printCFGContinuityStats (ProfileQualityStats.cpp:94)
           │      └─ BFSで到達可能性計算
           │
           ├─ printCallGraphFlowConservationStats (ProfileQualityStats.cpp:197)
           │      └─ エントリフロー vs コールグラフフロー
           │
           ├─ printCFGFlowConservationStats (ProfileQualityStats.cpp:286)
           │      └─ ブロック別インフロー/アウトフロー
           │
           └─ printExceptionHandlingStats (ProfileQualityStats.cpp:406)
                  └─ ランディングパッド統計
```

### データフロー図

```
[入力]                        [処理]                              [出力]

BinaryFunction ──────────▶ ValidFunctions収集 ─────────────┐
                               │                            │
BinaryBasicBlock ────────▶ フロー情報収集 ─────────────────┤
                               │                            │
BranchInfo ──────────────▶ computeFlowMappings ────────────┤
                               │                            ▼
                         printCFGContinuityStats ────▶ BOLT-INFO出力
                               │
                         printCallGraphFlowConservationStats
                               │
                         printCFGFlowConservationStats
                               │
                         printExceptionHandlingStats
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ProfileQualityStats.h | `bolt/include/bolt/Passes/ProfileQualityStats.h` | ヘッダー | パス定義 |
| ProfileQualityStats.cpp | `bolt/lib/Passes/ProfileQualityStats.cpp` | ソース | パス実装 |
| BinaryFunction.h | `bolt/include/bolt/Core/BinaryFunction.h` | ヘッダー | 関数クラス |
| BinaryBasicBlock.h | `bolt/include/bolt/Core/BinaryBasicBlock.h` | ヘッダー | ブロッククラス |
| BinaryPasses.h | `bolt/include/bolt/Passes/BinaryPasses.h` | ヘッダー | パス基底クラス |
