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>
This commit is contained in:
252
docs/development/roadmap/phases/phase-25.1f/README.md
Normal file
252
docs/development/roadmap/phases/phase-25.1f/README.md
Normal file
@ -0,0 +1,252 @@
|
||||
# Phase 25.1f — ControlForm(Loop/If 共通ビュー)& Stage‑B ハーネス準備
|
||||
|
||||
Status: planning(設計+観測レイヤ追加/挙動は変えない)
|
||||
|
||||
## ゴール
|
||||
|
||||
- LoopForm v2(ループ)と If まわり(`phi_core::if_phi`)に対して、**制御構造の共通ビュー `ControlForm`** を用意する。
|
||||
- すでに導入済みの Conservative PHI Box(If/Loop 用 SSA/PHI ロジック)を、
|
||||
- ループ専用/If 専用でバラバラに持つのではなく、
|
||||
- `ControlForm` を単一の SSOT(Single Source of Truth)として参照する方向に寄せる。
|
||||
- Stage‑B 最小ハーネスや Stage‑1 Resolver など、「複雑な if + loop」を含む経路で、
|
||||
- ループと条件分岐の形を **構造として観測・検証できる足場** を整える(いきなり本番導線は切り替えない)。
|
||||
|
||||
※ このフェーズでは Rust の挙動は変えず、「制御構造の箱(LoopShape / IfShape)+ ControlForm の定義」と、
|
||||
デバッグ/テスト用の観測導線(トレース)までに留める。
|
||||
|
||||
## 背景(25.1d / 25.1e までの位置づけ)
|
||||
|
||||
- 25.1d:
|
||||
- Rust MIR ビルダーの SSA/PHI バグ(ValueId 二重定義/non‑dominating use/undefined Value)を、
|
||||
小さな Rust テスト(`mir_*_verifies`)で炙り出して修正済み。
|
||||
- CalleeBoxKind / BoxCompilationContext によって Stage‑B / Stage‑1 の静的 Box とランタイム Box の混線も構造的に解消。
|
||||
- 25.1e:
|
||||
- ループの PHI 生成の SSOT を LoopForm v2 + `phi_core` に寄せ、
|
||||
- Exit PHI、break/continue、pinned/carrier/invariant 変数を整理。
|
||||
- Conservative PHI Box(If/Loop 両方で「安全側に倒す PHI 生成」を行い、不要な PHI は将来の削除で最適化する方針)を実装。
|
||||
- Stage‑1 UsingResolver 系テストと Program v0 PHI スモーク、Stage‑B 風ループテストはすべて緑。
|
||||
|
||||
ここまでで「LoopForm v2 + Conservative PHI」の根本バグはだいたい取り切れたが、
|
||||
|
||||
- PHI ロジックが If 用と Loop 用で散在している。
|
||||
- Stage‑B ハーネス側で「どの loop/if がどう組み合わさっているか」を横断的に眺める手段がまだ弱い。
|
||||
|
||||
→ 25.1f では、**Loop / If を一段上から包む ControlForm レイヤ**を定義し、Stage‑B ハーネスに進む前準備として構造を固める。
|
||||
|
||||
## 方針 — ControlForm / Shape の設計
|
||||
|
||||
### 型と場所
|
||||
|
||||
- 新規モジュール案:
|
||||
- `src/mir/control_form.rs`
|
||||
- 基本構造:
|
||||
- `LoopShape`:
|
||||
- `preheader: BasicBlockId`
|
||||
- `header: BasicBlockId`
|
||||
- `body: BasicBlockId`(代表 body ブロック)
|
||||
- `latch: BasicBlockId`
|
||||
- `exit: BasicBlockId`
|
||||
- `continue_targets: Vec<BasicBlockId>`
|
||||
- `break_targets: Vec<BasicBlockId>`
|
||||
- `IfShape`:
|
||||
- `cond_block: BasicBlockId`
|
||||
- `then_block: BasicBlockId`
|
||||
- `else_block: Option<BasicBlockId>`
|
||||
- `merge_block: BasicBlockId`
|
||||
- `ControlKind`:
|
||||
- `Loop(LoopShape)` / `If(IfShape)`(将来 `Switch` / `Match` も追加可能な余地だけ確保)
|
||||
- `ControlForm`:
|
||||
- `entry: BasicBlockId`(構造全体の入口)
|
||||
- `exits: Vec<BasicBlockId>`(構造を抜けた先のブロック群)
|
||||
- `kind: ControlKind`
|
||||
|
||||
### 生成パス(from_loop / from_if)
|
||||
|
||||
- `LoopForm` → `ControlForm`:
|
||||
- 既存の LoopForm v2(`LoopFormBuilder` が返す構造)から `LoopShape` を構築し、
|
||||
- `ControlForm::from_loop(loop_form: &LoopForm)` で共通ビューに変換する。
|
||||
- `entry = preheader`, `exits = [exit]` というルールで統一。
|
||||
- If 用:
|
||||
- 既存の `phi_core::if_phi` / builder 側の if lowering から、必要な情報をまとめた薄い `IfForm`(もしくは `IfShape` 直構築)を定義。
|
||||
- `ControlForm::from_if(if_form: &IfForm)` で共通ビューに変換。
|
||||
- `entry = cond_block`, `exits = [merge_block]` を基本とし、将来 `else if` や switch なども扱える形で設計。
|
||||
|
||||
### Invariant / Debug 用の Trait
|
||||
|
||||
- 25.1f では「挙動を変えない」ため、ControlForm 自体は **観測・検証専用** として設計する:
|
||||
- `debug_dump(&self)`:
|
||||
- Loop / If の各ブロック ID を一括でログ出力し、Stage‑1 / Stage‑B テストから CFG の形を視覚的に確認できるようにする。
|
||||
- `CfgLike` トレイト(任意):
|
||||
- `fn has_edge(&self, from: BasicBlockId, to: BasicBlockId) -> bool;`
|
||||
- `fn predecessors_len(&self, block: BasicBlockId) -> usize;`
|
||||
- `LoopShape::debug_validate<C: CfgLike>(&self, cfg: &C)` などを `#[cfg(debug_assertions)]` で用意し、
|
||||
Loop/If の形が想定どおりかを assert できるようにする。
|
||||
|
||||
## タスク粒度(25.1f TODO)
|
||||
|
||||
### F‑1: ControlForm / Shape の設計ドキュメント
|
||||
|
||||
- 本 README で:
|
||||
- `LoopShape` / `IfShape` / `ControlKind` / `ControlForm` の責務とフィールドを明文化。
|
||||
- LoopForm v2 との対応関係(preheader/header/latch/exit/continue/break)を図解レベルで通るところまで整理。
|
||||
- 25.1e の LoopForm 仕様(Carrier/Pinned/Invariant / break/continue / exit PHI)と整合していることを確認。
|
||||
|
||||
### F‑2: Rust 側のスケルトン実装(導線のみ)
|
||||
|
||||
- `src/mir/control_form.rs` を追加し、以下のみ実装:
|
||||
- 型定義(`LoopShape` / `IfShape` / `ControlKind` / `ControlForm`)。
|
||||
- `ControlForm::from_loop(&LoopForm)` / `ControlForm::from_if(&IfForm)` の雛形。
|
||||
- `debug_dump()` と `debug_validate()`(`#[cfg(debug_assertions)]` 前提、もしくはテスト専用)。
|
||||
- 既存のビルダー/PHI ロジックは **まだ ControlForm を使わない**:
|
||||
- 25.1e で安定した Conservative PHI 実装を壊さないため、Phase 25.1f では「観測オンリー」に留める。
|
||||
|
||||
### F‑3: Stage‑1 / Stage‑B テストへの観測フック
|
||||
|
||||
- 対象テスト:
|
||||
- `src/tests/mir_stage1_using_resolver_verify.rs` 系(Stage‑1 UsingResolver の min/full)。
|
||||
- Stage‑B 風ループ/Program v0 PHI スモーク(`mir_loopform_exit_phi.rs` / `mir_stageb_loop_break_continue.rs` / `tools/smokes/v2/...`)。
|
||||
- 方針:
|
||||
- `NYASH_CONTROL_FORM_TRACE=1` などの dev フラグが立っているときだけ、
|
||||
- LoopForm v2 から `ControlForm` を生成し、
|
||||
- `debug_dump()` で構造をトレースログに出す。
|
||||
- これにより、Stage‑B ハーネスを組む前に「実際にどんな Loop/If 形が発生しているか」を CFG レベルで確認できる。
|
||||
|
||||
### F‑4: Conservative PHI との接続計画(設計のみ)
|
||||
|
||||
- 25.1e で実装した Conservative PHI Box(If/Loop)のロジックを整理し、将来像を設計として固定する:
|
||||
- 目標: `merge_modified_at_merge_with` / LoopForm v2 Exit PHI 生成などを、
|
||||
- `ControlForm` ベースの API で呼べるようにする(例: `build_phi_for_control(form: &ControlForm, ...)`)。
|
||||
- 25.1f では:
|
||||
- どの関数をどこまで ControlForm 受けにするか、
|
||||
- 既存 API との互換性をどう保つか、
|
||||
を README 上で設計するところまで。
|
||||
- 実際の実装切り替え(PHI ロジックを ControlForm ベースに差し替える)は、Stage‑B ハーネスと合わせて **別フェーズ(25.1g または 25.2 以降)** に送る。
|
||||
|
||||
### F‑5: Stage‑B ハーネスへの橋渡し準備
|
||||
|
||||
- Stage‑B 最小ハーネス(`tools/test_stageb_min.sh` / `lang/src/compiler/tests/stageb_min_sample.hako`)における:
|
||||
- ループパターン(`skip_ws` などの単純ループ、複数 break/continue を含むループ)。
|
||||
- if + loop のネスト構造。
|
||||
を洗い出し、LoopForm v2 + IfShape + ControlForm ですべて表現できることを確認する。
|
||||
- 将来のタスク(このフェーズでは設計のみ):
|
||||
- Stage‑B ハーネスの SSA/PHI 検証を `ControlForm` 経由で行う Rust テストをどう設計するかをまとめる。
|
||||
- Stage‑B 側の .hako LoopSSA(`lang/src/compiler/builder/ssa/loopssa.hako`)が、LoopForm v2 / ControlForm の設計と齟齬を起こさないように、必要な制約・前提条件を明記する。
|
||||
|
||||
### F‑6: .hako 側 ControlFormBox(Layer 2 の箱)定義
|
||||
|
||||
- 目的:
|
||||
- Rust 側 `LoopShape` / `IfShape` / `ControlForm` に対応する **Hakorune 実装版の箱** を用意し、
|
||||
Stage‑B / LoopSSA が Rust と同じモデルでループ/if を扱えるようにする。
|
||||
- 将来の LoopSSA 実装は、この箱経由で構造を受け取ることを前提に設計する。
|
||||
- 現行構文版(Layer 2):
|
||||
- ファイル案: `lang/src/shared/mir/control_form_box.hako`
|
||||
- 定義案(BlockId は現状 i64/IntegerBox で表現):
|
||||
```hako
|
||||
static box ControlFormBox {
|
||||
kind_name: StringBox // "loop" or "if"
|
||||
entry: IntegerBox // BasicBlockId 相当
|
||||
exits: ArrayBox // of IntegerBox (BlockId)
|
||||
|
||||
// Loop fields (kind_name == "loop" の時のみ有効)
|
||||
loop_preheader: IntegerBox
|
||||
loop_header: IntegerBox
|
||||
loop_body: IntegerBox
|
||||
loop_latch: IntegerBox
|
||||
loop_exit: IntegerBox
|
||||
|
||||
// If fields (kind_name == "if" の時のみ有効)
|
||||
if_cond: IntegerBox
|
||||
if_then: IntegerBox
|
||||
if_else: IntegerBox
|
||||
if_merge: IntegerBox
|
||||
|
||||
birth(kind) {
|
||||
me.kind_name = kind
|
||||
me.exits = new ArrayBox()
|
||||
}
|
||||
|
||||
is_loop() {
|
||||
return me.kind_name == "loop"
|
||||
}
|
||||
|
||||
is_if() {
|
||||
return me.kind_name == "if"
|
||||
}
|
||||
}
|
||||
```
|
||||
- 対応表(Rust ↔ .hako):
|
||||
- Rust `LoopShape.preheader/header/body/latch/exit`
|
||||
↔ Hako `loop_preheader/loop_header/loop_body/loop_latch/loop_exit`
|
||||
- Rust `IfShape.cond_block/then_block/else_block/merge_block`
|
||||
↔ Hako `if_cond/if_then/if_else/if_merge`
|
||||
- Rust `ControlForm.entry/exits`
|
||||
↔ Hako `entry` / `exits`(`exits` は BlockId の配列)
|
||||
- 将来構文版(Layer 3 の理想形・variant 導入前提):
|
||||
- 将来の Nyash variant 構文が入ったら、`ControlKind` を enum 的に表現し、
|
||||
```hako
|
||||
box ControlKind {
|
||||
variant Loop { preheader: BlockIdBox, header: BlockIdBox, ... }
|
||||
variant If { cond_block: BlockIdBox, then_block: BlockIdBox, ... }
|
||||
}
|
||||
|
||||
static box ControlFormBox {
|
||||
kind: ControlKind
|
||||
entry: BlockIdBox
|
||||
exits: ArrayBox
|
||||
}
|
||||
```
|
||||
のような形に寄せる(現段階では設計メモのみ)。
|
||||
- 25.1f でのスコープ:
|
||||
- `control_form_box.hako` に上記 Layer 2 版 `ControlFormBox` を実装する。
|
||||
- ただし Stage‑B / LoopSSA からはまだ使用しない(コンパイルが通る最小限の実装+将来用の箱)。
|
||||
- Stage‑B LoopSSA 統合(ControlFormBox を実際に使って JSON v0→MIR を整理する)は、次フェーズに回す。
|
||||
|
||||
## 移行ステップ(Option A → B → C のロードマップ)
|
||||
|
||||
このフェーズ(25.1f)では、あくまで **Option A = 観測レイヤーの完成** までをスコープにするよ。その上で、将来の B/C も含めて合意しておきたい移行順序はこうだよ:
|
||||
|
||||
1. **Option A: 観測レイヤーを完璧にする(Phase 25.1f)**
|
||||
- Rust:
|
||||
- `LoopShape` / `IfShape` / `ControlForm` 実装済み。
|
||||
- `LoopBuilder` から LoopForm v2 / `lower_if_in_loop` の出口で `ControlForm::Loop/If` を生成して `debug_dump` 済み。
|
||||
- `NYASH_CONTROL_FORM_TRACE` は「未設定=ON, 0/false=OFF」のヘルパーに統一済み。
|
||||
- .hako:
|
||||
- `ControlFormBox`(kind_name + loop_* / if_* + entry/exits)の箱だけ定義(まだ未使用)。
|
||||
- テスト/スモーク:
|
||||
- `mir_stage1_using_resolver_*` / `mir_loopform_exit_phi.rs` / `mir_stageb_loop_break_continue.rs` / `tools/test_stageb_min.sh` を回しつつ、
|
||||
ControlForm トレースが panic せずに構造ログだけを出すことを確認する。
|
||||
|
||||
2. **Option B: Conservative PHI ↔ ControlForm の統合(別フェーズ: 25.1g 想定)**
|
||||
- ねらい:
|
||||
- いま `merge_modified_at_merge_with`(If)や LoopForm v2 Exit PHI が直接 BlockId/ValueId を持っている部分を、
|
||||
`ControlForm` 経由で読めるように段階的に寄せていく。
|
||||
- 方針:
|
||||
- まず If から(`ControlKind::If`)→ ループ Exit PHI(`ControlKind::Loop`)の順に小さく進める。
|
||||
- 各ステップごとに:
|
||||
- 対応するテスト(Stage‑1 / Program v0 / Stage‑B 風)+ `test_stageb_min.sh` を回し、
|
||||
SSA/PHI の赤ログが増えていないことを確認しながら移行する。
|
||||
- 注意:
|
||||
- これは 25.1f のスコープ外。Phase 25.1g(仮)として小さな差分に分割しながら実装する。
|
||||
|
||||
3. **Option C: LoopBuilder/If 降下の ControlForm ベース正規化(さらに後ろのフェーズ)**
|
||||
- ねらい:
|
||||
- 最終的には「LoopBuilder/If 降下がまず ControlForm を組み立てる」スタイルに寄せ、
|
||||
Conservative PHI / LoopSSA / .hako 側 LoopSSA が同じ ControlForm を揃って見る状態にする。
|
||||
- 規模:
|
||||
- 数百行単位のリファクタになるため、Phase 25.2 以降(Selfhost/Stage‑B の安定を見ながら)に分割してやる。
|
||||
- ガード:
|
||||
- 各ステップで代表スモーク(Stage‑1 / Stage‑B / Program v0 / `test_stageb_min.sh`)を流しながら進める。
|
||||
- `NYASH_CONTROL_FORM_TRACE` と `.hako ControlFormBox` を使って、常に「形」が崩れていないかを観測できるようにしておく。
|
||||
|
||||
このフェーズ(25.1f)は「Option A をやり切って足場を固める」ことに専念し、その上で 25.1g 以降で Option B/C に進む、というロードマップで進めるよ。
|
||||
|
||||
## このフェーズで「やらないこと」
|
||||
|
||||
- if を loop に書き換えるような、意味論レベルの正規化は **行わない**:
|
||||
- If は IfShape、Loop は LoopShape として、それぞれの形を尊重する。
|
||||
- Stage‑B ハーネス本体の導入・既存パイプラインの切り替え:
|
||||
- `test_stageb_min.sh` の経路変更や `.hako` コンパイラ側の LoopSSA 実装変更は、25.1f では触らず、
|
||||
ControlForm の設計と観測レイヤ整備が完了してから別フェーズで扱う。
|
||||
- Conservative PHI ロジックの大規模リライト:
|
||||
- 25.1e で安定させた If/Loop PHI 実装を、いきなり ControlForm ベースに書き換えることはしない。
|
||||
- まずは「どう書き換えるのが構造的に美しいか」を、このフェーズの README に設計として落とす。
|
||||
118
docs/development/roadmap/phases/phase-25.1g/README.md
Normal file
118
docs/development/roadmap/phases/phase-25.1g/README.md
Normal file
@ -0,0 +1,118 @@
|
||||
# Phase 25.1g — Conservative PHI ↔ ControlForm 統合(設計+小さな導線)
|
||||
|
||||
Status: planning(設計・導線追加/既存挙動は変えない)
|
||||
|
||||
## ゴール
|
||||
|
||||
- 25.1f で整えた **ControlForm 観測レイヤー**(LoopShape / IfShape + ControlForm)を、
|
||||
Conservative PHI Box(If/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 を取り出して、既存の関数に委譲するだけ」の薄いラッパにする。
|
||||
|
||||
## タスク粒度
|
||||
|
||||
### G‑1: 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 対応が設計どおりかを確認。
|
||||
|
||||
### G‑2: 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 誘発系の赤ログが増えていないことを確認。
|
||||
|
||||
### G‑3: 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 以降の仕事として残しておく。
|
||||
Reference in New Issue
Block a user