# 帳票設計書 3-AIRデバッグ出力

## 概要

本ドキュメントは、Zigコンパイラにおける AIR（Abstract Intermediate Representation）デバッグ出力帳票の設計仕様を記述するものである。AIRはセマンティック解析後に生成される中間表現であり、本帳票はその内容をLiveness情報を含めて人間が読みやすいテキスト形式で出力する機能を定義する。

### 本帳票の処理概要

AIRデバッグ出力は、Zigソースコードがセマンティック解析を経て生成されるAIR（Abstract Intermediate Representation）を可視化するための帳票である。命令数、メモリ使用量の統計情報に加え、各命令の詳細とLiveness（生存性）情報を含む詳細なダンプを提供する。

**業務上の目的・背景**：コンパイラのコード生成フェーズにおいて、AIRは最も重要な中間表現である。セマンティック解析の結果を表現し、バックエンド（LLVM、x86_64、WebAssemblyなど）へのコード生成の入力となる。本帳票により、開発者はセマンティック解析の正確性、最適化の効果、レジスタ割り当て前の命令列を詳細に確認でき、コンパイラの品質向上に貢献する。

**帳票の利用シーン**：
1. コンパイラ開発者がセマンティック解析結果のデバッグを行う際
2. 最適化パスの効果検証（命令数・メモリ使用量の比較）
3. コード生成の問題調査（AIR命令とバックエンド出力の対応確認）
4. Liveness解析の正確性検証
5. コンパイラの性能分析（メモリフットプリント測定）

**主要な出力内容**：
1. 統計情報（総バイト数、命令数、Extra Data、Liveness情報）
2. 各AIR命令の詳細（命令タグ、オペランド、型情報）
3. Liveness情報（未使用マーク`!`、tomb_bits）
4. ブロック構造と制御フロー
5. 関数呼び出し情報

**帳票の出力タイミング**：`verbose_air`オプション有効時、または`dump`関数の明示的呼び出し時に出力される。

**帳票の利用者**：Zigコンパイラ開発者、バックエンド実装者、最適化エンジニア

## 帳票種別

デバッグ/診断レポート

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| - | コマンドライン | コンパイル時オプション | `verbose_air`オプション有効時 |
| - | デバッグAPI | `Air.print.dump()` | プログラムからの呼び出し |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | テキスト（標準エラー出力または指定Writer） |
| 用紙サイズ | N/A |
| 向き | N/A |
| ファイル名 | N/A（標準エラー出力） |
| 出力方法 | バッファリングされたストリーム書き込み |
| 文字コード | UTF-8 |

## 帳票レイアウト

### レイアウト概要

AIRデバッグ出力は統計ヘッダーと命令リストで構成される。

```
┌─────────────────────────────────────────────────────────────┐
│ # Total AIR+Liveness bytes: XXX                             │
│ # AIR Instructions:         N (XXX bytes)                   │
│ # AIR Extra Data:           N (XXX bytes)                   │
│ # Liveness tomb_bits:       XXX bytes                       │
│ # Liveness Extra Data:      N (XXX bytes)                   │
│ # Liveness special table:   N (XXX bytes)                   │
├─────────────────────────────────────────────────────────────┤
│ [各命令の詳細]                                               │
│   %N = instruction_tag(operands)                            │
│   %N!= instruction_tag(operands)  [!は未使用マーク]          │
│     { [ブロック内容] }                                       │
└─────────────────────────────────────────────────────────────┘
```

### ヘッダー部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | 総バイト数 | AIR+Livenessの合計サイズ | 計算値 | `{Bi}`（バイナリ単位） |
| 2 | AIR命令数 | AIR命令の総数 | `air.instructions.len` | `{d} ({Bi})` |
| 3 | AIR Extra Data | 追加データ項目数 | `air.extra.items.len` | `{d} ({Bi})` |
| 4 | Liveness tomb_bits | 生存性ビットマップサイズ | `liveness.tomb_bits.len` | `{Bi}` |
| 5 | Liveness Extra Data | Liveness追加データ | `liveness.extra.len` | `{d} ({Bi})` |
| 6 | Liveness special table | 特殊テーブルサイズ | `liveness.special.count()` | `{d} ({Bi})` |

### 明細部

| No | 項目名 | 説明 | データ取得元 | 表示形式 | 列幅 |
|----|-------|------|-------------|---------|-----|
| 1 | 命令番号 | AIR命令のインデックス | `Air.Inst.Index` | `%N` | 可変 |
| 2 | 未使用マーク | Liveness未使用フラグ | `liveness.isUnused(inst)` | `!`または空白 | 1 |
| 3 | 命令タグ | 命令の種別 | `Air.Inst.Tag` | 小文字スネークケース | 可変 |
| 4 | オペランド | 命令の引数 | 命令固有データ | カンマ区切り | 可変 |
| 5 | 型情報 | 戻り値型または操作対象型 | `Type` | 型名 | 可変 |

### フッター部

N/A

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| verbose_airオプション | コンパイル時に有効化 | Yes（自動出力時） |
| dump呼び出し | 明示的なAPI呼び出し | Yes（手動出力時） |
| enable_debug_extensions | ビルドオプションで有効化 | Yes |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| 1 | 命令インデックス | 昇順 |

### 改ページ条件

N/A（連続テキスト出力）

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

N/A（データベースを使用しない。コンパイラ内部のAIRデータ構造を参照）

### 内部データ構造参照

| 参照項目 | 帳票項目との対応 | 取得条件 | 備考 |
|---------|----------------|---------|------|
| `Air.instructions` | 各命令の詳細 | 全命令を走査 | MultiArrayList形式（tag, data） |
| `Air.extra` | 命令の追加データ | 命令タグに応じて | 可変長データ |
| `Air.Liveness` | 生存性情報 | オプション | tomb_bits, extra, special |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| instruction_bytes | `instructions.len * (@sizeOf(Tag) + 8)` | なし | タグ1バイト + データ8バイト |
| extra_bytes | `extra.items.len * @sizeOf(u32)` | なし | 4バイト/項目 |
| tomb_bytes | `liveness.tomb_bits.len * @sizeOf(usize)` | なし | ポインタサイズ/項目 |
| total_bytes | 上記の合計 + 構造体オーバーヘッド | なし | - |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[write/dump呼び出し] --> B[enable_debug_extensions確認]
    B --> C[統計情報計算]
    C --> D[ヘッダー出力]
    D --> E[Writer構造体初期化]
    E --> F[getMainBody取得]
    F --> G[writeBody呼び出し]
    G --> H[各命令をwriteInstで出力]
    H --> I{命令タイプ?}
    I -->|ブロック命令| J[ブロック内容を再帰出力]
    I -->|その他| K[オペランド出力]
    J --> L[次の命令へ]
    K --> L
    L --> M{全命令完了?}
    M -->|No| H
    M -->|Yes| N[終了]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| 書き込みエラー | 出力ストリームエラー | なし | エラー返却/無視 |
| 未実装命令 | 新命令の出力未対応 | `@panic("TODO")` | 実装追加が必要 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 数百〜数万命令（関数サイズに依存） |
| 目標出力時間 | O(N)（命令数に比例） |
| 同時出力数上限 | 1件 |

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

- AIRダンプにはコードの詳細な構造情報が含まれる
- 最適化前の情報が含まれるため、アルゴリズムの詳細が露出する可能性

## 備考

- `build_options.enable_debug_extensions`が有効な場合のみ利用可能
- `skip_body`フラグでブロック内容の出力をスキップ可能
- Liveness情報はオプション（`null`の場合は未使用マークなし）

---

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

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

### 推奨読解順序

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

AIRの基本構造を理解することが前提となる。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Air.zig | `src/Air.zig` | AIR構造体：instructions, extra, values |
| 1-2 | Air.zig | `src/Air.zig` | `Inst.Tag`列挙型：命令種別の定義 |
| 1-3 | Air.zig | `src/Air.zig` | `Liveness`構造体：生存性解析結果 |

**読解のコツ**: AIRもZIRと同様にMultiArrayList形式で格納されている。Liveness情報は別構造体で管理される。

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

AIRテキスト出力の起点を特定。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | print.zig | `src/Air/print.zig` | `write`関数（行12-54）：完全なAIRダンプのエントリーポイント |
| 2-2 | print.zig | `src/Air/print.zig` | `writeInst`関数（行56-73）：単一命令出力 |
| 2-3 | print.zig | `src/Air/print.zig` | `dump`関数（行75-83）：stderr直接出力ヘルパー |

**主要処理フロー**:
1. **行13**: `comptime assert(build_options.enable_debug_extensions)`でビルド時チェック
2. **行14-24**: メモリ使用量の計算（instruction_bytes, extra_bytes, tomb_bytes等）
3. **行27-42**: 統計ヘッダーの出力
4. **行45-53**: Writer初期化とwriteBody呼び出し

#### Step 3: Writer構造体を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | print.zig | `src/Air/print.zig` | `Writer`構造体（行95-101）：出力状態管理 |
| 3-2 | print.zig | `src/Air/print.zig` | `writeBody`関数（行105-110）：命令列の出力 |
| 3-3 | print.zig | `src/Air/print.zig` | `writeInst`関数（行112-352）：命令タグに応じた出力 |

**主要処理フロー**:
- `skip_body`: ブロック内容をスキップするかどうかのフラグ
- `liveness`: オプションの生存性情報（未使用マーク出力に使用）

#### Step 4: 命令出力処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | print.zig | `src/Air/print.zig` | `writeInst`のswitch文（行120-351）：命令タイプごとの出力分岐 |
| 4-2 | print.zig | `src/Air/print.zig` | `writeBinOp`（行354-359）：二項演算の出力 |
| 4-3 | print.zig | `src/Air/print.zig` | `writeBlock`（行395-434）：ブロック命令の出力 |

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

```
write / dump
    |
    +-- 統計計算・ヘッダー出力
    |
    +-- Writer初期化
    |
    +-- writeBody
            |
            +-- writeInst (各命令に対して)
                    |
                    +-- [命令タグに応じた分岐]
                    |       |
                    |       +-- writeBinOp
                    |       +-- writeUnOp
                    |       +-- writeTyOp
                    |       +-- writeBlock (再帰)
                    |       +-- writeCall
                    |       +-- ... (各命令タイプ固有の出力関数)
                    |
                    +-- writeOperand (オペランド出力)
                    +-- writeType (型情報出力)
```

### データフロー図

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

Air構造体            ─────> write ────────────────────────> stderr/Writer
  |                         |
  +-- instructions   ─────> writeInst ────────────────────> "%N = tag(...)"
  |                         |
  +-- extra          ─────> extraData() ──────────────────> オペランド詳細
  |                         |
  +-- Liveness       ─────> isUnused() ───────────────────> "!"マーク
        |
        +-- tomb_bits ─────> getBlock() ──────────────────> ブロック終端deaths
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| print.zig | `src/Air/print.zig` | ソース | AIRテキスト出力のメイン実装 |
| Air.zig | `src/Air.zig` | ソース | AIRデータ構造定義 |
| Liveness.zig | `src/Liveness.zig` | ソース | 生存性解析結果の構造体 |
| Compilation.zig | `src/Compilation.zig` | ソース | verbose_airオプション処理 |
| build_options | `build_options` | 設定 | `enable_debug_extensions`フラグ定義 |
