Files
hakorune/docs/development/roadmap/phases/phase-25.1g/README.md
nyash-codex d3cbc71c9b feat(mir): Phase 25.1f完了 - Conservative PHI + ControlForm観測レイヤー
🎉 Conservative PHI Box理論による完全SSA構築

**Phase 7-B: Conservative PHI実装**
- 片方branchのみ定義変数に対応(emit_void使用)
- 全変数にPHI生成(Conservative Box理論)
- Stage-1 resolver全テスト緑化(3/3 PASS)

**Phase 25.1f: ControlForm観測レイヤー**
- LoopShape/IfShape/ControlForm構造定義
- Loop/If統一インターフェース実装
- debug_dump/debug_validate機能追加
- NYASH_CONTROL_FORM_TRACE環境変数対応

**主な変更**:
- src/mir/builder/phi.rs: Conservative PHI実装
- src/mir/control_form.rs: ControlForm構造(NEW)
- src/mir/loop_builder.rs: LoopForm v2デフォルト化

**テスト結果**:
 mir_stage1_using_resolver_min_fragment_verifies
 mir_stage1_using_resolver_full_collect_entries_verifies
 mir_parserbox_parse_program2_harness_parses_minimal_source

🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: ChatGPT <chatgpt@openai.com>
2025-11-18 18:56:35 +09:00

119 lines
6.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Phase 25.1g — Conservative PHI ↔ ControlForm 統合(設計+小さな導線)
Status: planning設計・導線追加既存挙動は変えない
## ゴール
- 25.1f で整えた **ControlForm 観測レイヤー**LoopShape / IfShape + ControlFormを、
Conservative PHI BoxIf/Loop 用 SSA/PHI ロジック)の入口として使えるようにする。
- いきなりすべてを書き換えるのではなく、
1. If 用 Conservative PHI → ControlForm 対応
2. LoopForm v2 Exit PHI → ControlForm 対応
の順に、小さく段階的に寄せる。
- 各ステップごとに Rust テストと `tools/test_stageb_min.sh` を流しつつ、
SSA/PHI の赤ログが増えていないことを確認して進む。
## 前提25.1f までで揃ったもの)
- Rust:
- `src/mir/control_form.rs`:
- `LoopShape` / `IfShape` / `ControlKind` / `ControlForm` / `CfgLike` / `is_control_form_trace_on()` が定義済み。
- `src/mir/loop_builder.rs`:
- LoopForm v2 経路(`build_loop_with_loopform`)の出口で `LoopShape``ControlForm::Loop` を生成・トレース。
- `lower_if_in_loop` の merge 部分で `IfShape``ControlForm::If` を生成・トレース。
- `NYASH_CONTROL_FORM_TRACE`(未設定=ON, 0/false=OFFでトレース ON/OFF 切り替え可能。
- Conservative PHI:
- If 用: `src/mir/builder/phi.rs` / `src/mir/phi_core/if_phi.rs`Conservative PHI Box 実装)。
- Loop 用: `src/mir/phi_core/loopform_builder.rs`LoopForm v2 の Exit PHI / Carrier/Pinned 対応)。
- .hako:
- `lang/src/shared/mir/control_form_box.hako`:
- `static box ControlFormBox`kind_name + loop_* / if_* + entry/exitsだけ実装済みまだ未使用
## 方針Option B の範囲)
- **このフェーズでは**:
- Conservative PHI の「インターフェースと呼び出し位置」に ControlForm の導線を用意する。
- ただし既存のロジック(引数で BlockId を受け取る形は残し、ControlForm 導線は **観測+補助的な入口** として扱う。
- 影響範囲は If / Loop の PHI 部分に限定し、他の MIR 降下には触れない。
- 実装方針:
- 新しい API を「足す」→ 既存コードから段階的に使い始める、という形で進める。
- 例:
- If 用: `merge_modified_at_merge_with_control(form: &ControlForm, ...)` を追加。
- Loop 用: `build_exit_phis_for_control(form: &ControlForm, ...)` を追加。
- 最初のステップでは「ControlForm から必要な BlockId を取り出して、既存の関数に委譲するだけ」の薄いラッパにする。
## タスク粒度
### G1: If 用 Conservative PHI への ControlForm 導線
- 目的:
- `loop_builder.rs::lower_if_in_loop` から、`ControlForm::If` を PHI ロジックに渡せるようにする。
- ステップ:
1. `src/mir/phi_core/if_phi.rs` に薄いラッパ関数を追加:
```rust
pub fn merge_modified_with_control<O: PhiMergeOps>(
ops: &mut O,
form: &crate::mir::control_form::ControlForm,
pre_if_snapshot: &HashMap<String, ValueId>,
then_map_end: &HashMap<String, ValueId>,
else_map_end_opt: &Option<HashMap<String, ValueId>>,
skip_var: Option<&str>,
) -> Result<(), String> {
// ControlForm::If から cond/then/else/merge を取り出し、
// 既存の merge_modified_at_merge_with に橋渡しするだけ(ロジックは変えない)。
}
```
2. `lower_if_in_loop` 側で:
- 既存の `merge_modified_at_merge_with` 呼び出しの直前/直後にコメントを付け、
- 将来的に `merge_modified_with_control` に置き換えられるように位置を明示する25.1g ではまだ呼び替えない or dev フラグで限定)。
3. テスト:
- `cargo test -q mir_stage1_using_resolver_min_fragment_verifies -- --nocapture`
- `cargo test -q mir_stage1_using_resolver_full_collect_entries_verifies -- --nocapture`
- 必要なら `NYASH_CONTROL_FORM_TRACE=1` で IfShape ログを確認し、BlockId 対応が設計どおりかを確認。
### G2: LoopForm v2 Exit PHI への ControlForm 導線
- 目的:
- LoopForm v2 Exit PHI`loopform_builder.rs::build_exit_phis`)にも ControlForm ベースの入口を用意する。
- ステップ:
1. `src/mir/phi_core/loopform_builder.rs` にラッパ関数追加:
```rust
pub fn build_exit_phis_for_control<O: LoopFormOps>(
loopform: &LoopFormBuilder,
ops: &mut O,
form: &crate::mir::control_form::ControlForm,
exit_snapshots: &[(BasicBlockId, HashMap<String, ValueId>)],
) -> Result<(), String> {
// form.kind が Loop の場合に限り、
// shape.preheader/header/body/latch/exit から exit_id/branch_source_block を決めて
// 既存の build_exit_phis に委譲するだけ。
}
```
2. `LoopBuilder::build_loop_with_loopform` からは:
- 現在どおり `loopform.build_exit_phis(self, exit_id, branch_source_block, &exit_snaps)` を呼び続ける。
- コメントで「ControlForm 経由の入口」があることを明示し、将来の切り替えポイントを固定する。
3. テスト:
- `cargo test -q mir_loopform_exit_phi -- --nocapture`
- `cargo test -q mir_stageb_loop_break_continue -- --nocapture`
- `./tools/test_stageb_min.sh` を流して、Exit PHI 誘発系の赤ログが増えていないことを確認。
### G3: ControlForm ↔ Conservative PHI の設計メモ更新
- 目的:
- 25.1d/e/f/g の成果をまとめ、「If/Loop の PHI が最終的にどのレイヤで SSOT を持つか」を文書で固定する。
- ステップ:
- `phase-25.1d/README.md` と `phase-25.1f/README.md` をリンクしつつ、
- Conservative PHI Box の責務If/Loop 両方)
- ControlForm レイヤの責務
- .hako 側 `ControlFormBox` / `LoopSSA` の予定
を Phase 25 全体の流れの中に整理して追記する。
- `CURRENT_TASK.md` に 25.1g の短いサマリを追加して、今どこまで進めたかをいつでも追えるようにする。
## このフェーズで「しない」こと
- 既存の Conservative PHI 実装を一気に ControlForm 専用に書き換えること:
- 25.1g は「導線追加+ラッパ」「設計固め」まで。
- 実際の置き換えOption B の本体)は、さらに小さなステップに分けて後続フェーズで行う。
- LoopBuilder/If 降下の大規模リファクタOption C 相当):
- これは Phase 25.2 以降の仕事として残しておく。