# 機能設計書 81-効果推論

## 概要

本ドキュメントは、Juliaコンパイラにおける効果推論（Effects Analysis）機能の設計を記述する。効果推論は、抽象解釈ベースの型推論と連携して、メソッド呼び出しの計算効果（副作用・例外・終了性など）を静的に解析する機構である。

### 本機能の処理概要

効果推論は、Julia のメソッドが持つ計算効果（computational effects）を静的に解析し、最適化パスに活用可能な情報を提供する。

**業務上の目的・背景**：Juliaは動的型付け言語でありながら、高い実行性能を実現するためにコンパイル時最適化に依存している。効果推論によって「この関数は副作用がない」「例外を投げない」「必ず終了する」といった性質を静的に判定することで、定数畳み込み・デッドコード除去・インライン化などの最適化を安全に適用できるようになる。これにより、動的言語でありながら静的言語に匹敵するパフォーマンスを実現している。

**機能の利用シーン**：効果推論は、Julia コンパイラの型推論フェーズにおいて自動的に実行される。ユーザーは `Base.@assume_effects` マクロを用いて効果を手動で宣言することも可能であり、パフォーマンスクリティカルなライブラリコードでは手動アノテーションが活用される。また、`Base.infer_effects` で推論結果を確認できる。

**主要な処理内容**：
1. `Effects` 構造体による9種類の効果プロパティの表現（consistent, effect_free, nothrow, terminates, notaskstate, inaccessiblememonly, noub, nonoverlayed, nortcall）
2. 抽象解釈中の各文に対するローカル効果解析と、メソッド全体のグローバル効果へのマージ（`merge_effects`）
3. 効果ビットのエンコード・デコードによるコンパクトな格納（`encode_effects` / `decode_effects`）
4. 効果に基づく最適化判定（`is_foldable`, `is_removable_if_unused`, `is_finalizer_inlineable`）
5. `@assume_effects` マクロによるユーザー指定の効果オーバーライド

**関連システム・外部連携**：効果推論の結果は、最適化パス（No.82）で IR フラグとして利用される。また、コード生成（No.84）やAOTコンパイル（No.86）でも `encode_effects` / `decode_effects` を通じてシリアライズされた効果情報が使用される。

**権限による制御**：特になし。コンパイラ内部の自動処理であるが、`@assume_effects` マクロによるユーザーオーバーライドはコード作者の責任で使用される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能はコンパイラ内部機能であり、直接的なUI画面は存在しない |

## 機能種別

計算処理（コンパイラ内部の静的解析処理）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| メソッド本体 | CodeInfo | Yes | 型推論対象のメソッドのIR表現 | 有効なCodeInfoであること |
| 各SSA文の型情報 | Vector{Any} | Yes | 抽象解釈で推論された各文の型 | - |
| AbstractLattice | AbstractLattice | Yes | 型格子構造 | - |

### 入力データソース

- 型推論エンジン（`abstractinterpretation.jl`）からの呼び出し
- `@assume_effects` マクロによるユーザーアノテーション
- 組み込み関数の効果テーブル（`tfuncs.jl` 内で定義）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Effects | Effects | 9種類の効果プロパティを格納した構造体 |
| エンコード済み効果 | UInt32 | ビットフィールドエンコードされた効果情報 |
| IR フラグ | UInt32 | 最適化パスで使用されるステートメントレベルの効果フラグ |

### 出力先

- `InferenceResult` に格納され、最適化パスに渡される
- `CodeInstance` にエンコード済みで格納され、キャッシュされる
- IR の各文の `ssaflags` に `IR_FLAG_*` として反映される

## 処理フロー

### 処理シーケンス

```
1. Effects 構造体の初期化（EFFECTS_TOTAL: 全プロパティが最良値）
   └─ consistent=ALWAYS_TRUE, effect_free=ALWAYS_TRUE, nothrow=true, ...
2. 抽象解釈中の各文の解析
   └─ 各文（call, invoke, foreigncall 等）ごとにローカル効果を判定
3. ローカル効果のグローバル効果へのマージ
   └─ merge_effects() で保守的にマージ（ALWAYS_TRUE → ALWAYS_FALSE 方向）
4. 条件付き効果の解決
   └─ CONSISTENT_IF_NOTRETURNED, EFFECT_FREE_IF_INACCESSIBLEMEMONLY 等の解決
5. 最終的な Effects の確定
   └─ encode_effects() で UInt32 にエンコードしてキャッシュに格納
```

### フローチャート

```mermaid
flowchart TD
    A[抽象解釈開始] --> B[Effects を EFFECTS_TOTAL で初期化]
    B --> C[各SSA文を順次解析]
    C --> D{文の種類}
    D -->|call/invoke| E[呼び出し先の Effects を取得]
    D -->|foreigncall| F[ccall の効果を判定]
    D -->|その他| G[デフォルト Effects を適用]
    E --> H[merge_effects でグローバル Effects にマージ]
    F --> H
    G --> H
    H --> I{全文解析完了?}
    I -->|No| C
    I -->|Yes| J[条件付き効果の解決]
    J --> K[encode_effects で UInt32 にエンコード]
    K --> L[CodeInstance に格納]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-81-01 | 効果の単調性 | 効果プロパティは ALWAYS_TRUE から ALWAYS_FALSE への方向にのみ遷移する | 全ての効果解析 |
| BR-81-02 | 保守的マージ | 2つの効果をマージする場合、より悪い方が採用される | merge_effects 呼び出し時 |
| BR-81-03 | 畳み込み可能性 | consistent かつ effect_free かつ terminates かつ noub の場合のみ定数畳み込み可能 | is_foldable 判定時 |
| BR-81-04 | 削除可能性 | effect_free かつ nothrow かつ terminates の場合のみ未使用時に削除可能 | is_removable_if_unused 判定時 |
| BR-81-05 | 条件付き一貫性 | 返値に新規割当mutableオブジェクトが含まれない場合に CONSISTENT_IF_NOTRETURNED が解決される | 返値型の解析時 |

### 計算ロジック

効果ビットのエンコード:
```
encoded = (consistent << 0) | (effect_free << 3) | (nothrow << 5) |
          (terminates << 6) | (notaskstate << 7) | (inaccessiblememonly << 8) |
          (noub << 10) | (nonoverlayed << 12) | (nortcall << 14)
```

効果ビットのマージ:
- UInt8 フィールド: `old === ALWAYS_FALSE || new === ALWAYS_FALSE` なら `ALWAYS_FALSE`、それ以外は `old | new`
- Bool フィールド: `old & new`

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

本機能はデータベースを使用しない。コンパイラ内部のインメモリデータ構造のみを操作する。

### 操作別データベース影響一覧

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 内部整合性エラー | エンコード・デコードの不一致 | assert による検出。コンパイラバグとして報告 |
| - | 効果オーバーライド不整合 | @assume_effects の宣言が実際の効果と矛盾 | 未定義動作となる（ユーザー責任） |

### リトライ仕様

該当なし。コンパイラ内部処理のため自動リトライは行わない。

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

該当なし。

## パフォーマンス要件

- 効果推論は型推論と同時に実行されるため、型推論全体の時間に含まれる
- Effects 構造体はコンパクト（9フィールド、合計約10バイト）で高速にマージ可能
- encode_effects / decode_effects はビット演算のみで構成され O(1)

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

- `@assume_effects` マクロの誤用は未定義動作を引き起こす可能性がある
- 効果推論自体はメモリ安全であり、外部入力を直接扱わない

## 備考

- 効果プロパティの定義は `codegen.cpp` および `staticdata.c` の `effects_foldable` 関数と同期が必要（コード内コメントに明記）
- `NUM_EFFECTS_OVERRIDES` 定数で効果オーバーライドのビット数が管理されている

---

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

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

### 推奨読解順序

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

まず Effects 構造体とその定数定義を理解することが最も重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | effects.jl | `Compiler/src/effects.jl` | Effects 構造体の定義（119-150行目）と9種類の効果プロパティの意味 |
| 1-2 | effects.jl | `Compiler/src/effects.jl` | 定数定義（152-177行目）: ALWAYS_TRUE, ALWAYS_FALSE, 各条件付きビット |
| 1-3 | effects.jl | `Compiler/src/effects.jl` | プリセット定数（178-180行目）: EFFECTS_TOTAL, EFFECTS_THROWS, EFFECTS_UNKNOWN |

**読解のコツ**: UInt8 フィールド（consistent, effect_free, inaccessiblememonly, noub, nonoverlayed）は3値以上の状態を持つ。ALWAYS_TRUE(0x00) が最良で、ALWAYS_FALSE(0x01) が最悪、その間に条件付き状態がある。Bool フィールド（nothrow, terminates, notaskstate, nortcall）は2値。

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

Effects が型推論からどのように構築されるかを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | effects.jl | `Compiler/src/effects.jl` | merge_effects 関数（275-286行目）: 2つの Effects をマージする中核ロジック |
| 2-2 | effects.jl | `Compiler/src/effects.jl` | merge_effectbits 関数（288-294行目）: 個別ビットのマージルール |
| 2-3 | effects.jl | `Compiler/src/effects.jl` | is_better_effects 関数（205-273行目）: 効果の改善判定 |

**主要処理フロー**:
1. **275-286行目**: merge_effects が全9フィールドを個別に merge_effectbits でマージ
2. **288-293行目**: UInt8 ビットのマージ: ALWAYS_FALSE があれば即 ALWAYS_FALSE、それ以外は OR
3. **294行目**: Bool ビットのマージ: AND 演算

#### Step 3: 効果の判定ユーティリティを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | effects.jl | `Compiler/src/effects.jl` | 判定関数群（296-336行目）: is_consistent, is_effect_free, is_nothrow 等 |
| 3-2 | effects.jl | `Compiler/src/effects.jl` | 複合判定（308-327行目）: is_foldable, is_removable_if_unused, is_finalizer_inlineable |

#### Step 4: エンコード・デコードを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | effects.jl | `Compiler/src/effects.jl` | encode_effects 関数（339-349行目）: UInt32 へのビットパッキング |
| 4-2 | effects.jl | `Compiler/src/effects.jl` | decode_effects 関数（351-362行目）: UInt32 からの復元 |

#### Step 5: 最適化パスとの連携を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | optimize.jl | `Compiler/src/optimize.jl` | IR フラグ定数（18-63行目）: IR_FLAG_CONSISTENT 等の定義 |
| 5-2 | optimize.jl | `Compiler/src/optimize.jl` | flags_for_effects 関数（72-98行目）: Effects から IR フラグへの変換 |

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

```
abstractinterpretation (型推論メインループ)
    |
    +-- Effects 初期化 (EFFECTS_TOTAL)
    |
    +-- 各文の解析
    |      +-- builtin_effects (組み込み関数の効果)
    |      +-- stmt_effects (一般文の効果)
    |      +-- merge_effects! (グローバル Effects へのマージ)
    |             +-- merge_effectbits (UInt8)
    |             +-- merge_effectbits (Bool)
    |
    +-- ipo_dataflow_analysis!
    |      +-- 条件付き効果の解決
    |
    +-- encode_effects
           +-- CodeInstance に格納
```

### データフロー図

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

CodeInfo          --> Effects 初期化                 --> Effects (初期値)
各SSA文           --> ローカル効果解析               --> ローカル Effects
                  --> merge_effects                  --> グローバル Effects
                  --> 条件付き効果解決               --> 最終 Effects
                  --> encode_effects                 --> UInt32 (CodeInstance)
                  --> flags_for_effects              --> UInt32 (IR flags)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| effects.jl | `Compiler/src/effects.jl` | ソース | Effects 構造体定義・マージ・エンコード/デコード・判定関数群 |
| optimize.jl | `Compiler/src/optimize.jl` | ソース | IR フラグ定数定義・flags_for_effects による Effects→IRフラグ変換 |
| abstractinterpretation.jl | `Compiler/src/abstractinterpretation.jl` | ソース | 抽象解釈中の効果解析呼び出し元 |
| tfuncs.jl | `Compiler/src/tfuncs.jl` | ソース | 組み込み関数の効果定義 |
| ssair/passes.jl | `Compiler/src/ssair/passes.jl` | ソース | SROA・ADCE パスでの効果情報利用 |
| ssair/inlining.jl | `Compiler/src/ssair/inlining.jl` | ソース | インライン化判定での効果情報利用 |
| codegen.cpp | `src/codegen.cpp` | ソース | LLVM コード生成での効果情報利用 |
| staticdata.c | `src/staticdata.c` | ソース | シリアライズ時の効果情報エンコード |
