Files
hakorune/docs/development/roadmap/phases/phase-25.1i/README.md
nyash-codex 80f8a7bc8c 🔧 Hotfix 7 (Enhanced): ValueId receiver alias tracking for nested loops
- Problem: Pinned receiver variables in loops cause undefined ValueId errors
- Enhanced fix: Update all receiver aliases (me + all __pin$N$@recv levels)
- Handles nested loops by updating previous pin levels
- Test status: Partial improvement, ValueId(50) → ValueId(40)
- Further investigation needed for complete fix

Files modified:
- src/mir/phi_core/loopform_builder.rs (emit_header_phis)
2025-11-19 00:02:41 +09:00

115 lines
7.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.1i — LoopSSA v2 (.hako) & ControlFormBox 統合StageB 入口)
Status: in-progress.hako 側 LoopSSA 設計足場実装Rust挙動は変えない
## ゴール
- Rust 側で整えた LoopForm v2 / ControlFormLoopShape / IfShapeを、.hako 側 LoopSSA にも導入し、
StageB 最小ハーネス(`tools/test_stageb_min.sh`で見えている「exit PHI / break 周りの赤ログ」に構造的にアプローチできる足場を作る。
- 25.1i のスコープでは、まず:
- LoopSSA の責務を ControlFormBox 中心の設計に書き換える(設計+薄い実装)。
- 既存の文字列ベース `_find_loops` / `_collect_phi_vars` を温存しつつ、
ControlFormBox に loop/if の形を写し取るための API を導入する。
- StageB Test 2/3 の赤ログundefined ValueId / `%0`)は「再現と観測」まで(このフェーズで「必ず全部直す」とはしない)。
## 現状25.1g/25.1i 途中時点)
- Rust:
- Loop/If:
- LoopForm v2 + Conservative PHI Box が ControlFormLoopShape/IfShape経由で統合済み。
- レガシー `build_loop_legacy` / 旧ヘルパーは削除済みLoopForm v2 が唯一のループ構築経路)。
- テスト:
- `mir_loopform_exit_phi` / `mir_stage1_using_resolver_*` / `mir_stageb_loop_break_continue` 緑。
- `tools/test_stageb_min.sh`:
- Test 1直接 VM 実行): 0 exit。
- Test 2StageB 経由): `BreakFinderBox.find_breaks/1` まわりで undefined ValueId(96)。
- Test 3MIR verify: `%0` 由来の undefined value が残っている。
- .hako:
- `lang/src/compiler/builder/ssa/loopssa.hako`:
- `LoopSSA.stabilize_merges(stage1_json)` が BreakFinderBox + PhiInjectorBox を呼び出す簡易パイプライン。
- `lang/src/compiler/builder/ssa/exit_phi/break_finder.hako`:
- 文字列ベースで `"loop_header":` / `"loop_exit":` マーカーを探して `_find_loops`
- loop body を「header_id < id < exit_id のブロック群として推定する `_find_loop_body`
- break jump target exit_id blockとして検出
- `lang/src/compiler/builder/ssa/exit_phi/phi_injector.hako`:
- 共通変数名のリストi, n, item, ...)」から `_block_uses_var` で使用有無チェック `_get_var_value` synthetic value_id を組み立てて PHI JSON を注入する簡易版
- `lang/src/shared/mir/control_form_box.hako`:
- `static box ControlFormBox`kind_name + loop_* / if_* + entry/exitsの箱を定義
- 25.1i 未来構文だった `field: TypeBox` 形式を撤去し現行構文に合わせたフィールド宣言`kind_name` などに修正済み
- `from_loop` / `from_if` を追加しLoopSSA/BreakFinderBox から loop/if 形を写し取るための足場として利用開始
- StageB ハーネス:
- `tools/test_stageb_min.sh` Test 2 `compiler_stageb.hako` parse error`Unexpected token COLON` ControlFormBox の型注釈撤去と
`using lang.compiler.parser.parser_box as ParserBox` への修正で解消
- 現在は `MIR compilation error: Undefined variable: trace` で停止しておりこれは LoopSSA/PhiInjector 側の未実装ロジック由来として
次フェーズ25.1j 以降のターゲットに残している
## 方針LoopSSA v2 / ControlFormBox 作戦)
- 25.1i では **一気に全部作り替えない**:
- 既存の BreakFinderBox / PhiInjectorBox は当面残しつつ
ControlFormBox 経由で loop/if の形を扱うための導線を増やす
- まずはLoopSSA / BreakFinderBox の責務分割 ControlFormBox の利用ポイントを設計として固定する
- 段階:
1. LoopSSA 設計の整理LoopScope / IfScope / Carrier/Pinned .hako に翻訳
2. ControlFormBox を使った loop/if 形の復元 API を追加
3. BreakFinderBox / PhiInjectorBox 入力/出力 ControlFormBox 前提に徐々に寄せる
4. StageB Test2/3 undefined ValueId / `%0` の原因箇所を観測し次フェーズで本格修正
## タスク粒度25.1i
### I1: LoopSSA / ControlFormBox の責務整理(設計)
- 目的:
- LoopSSA フェーズで何をやるべきかRust LoopForm v2 / ControlForm の設計に揃えて文章化する
- ステップ:
- `LoopSSA.stabilize_merges` のコメントを拡張し
- input: Stage1 JSON v0単一関数 or Program
- output: exit PHI が入った JSON v0
- 内部ステップ: BreakFinderBox LoopForm v2 的な Exit PHI パターンを .hako で再現
を書く
- ControlFormBox に対応する Rust LoopShape/IfShape のフィールドと責務を README で対応づける
### I2: ControlFormBox ユーティリティの追加Layer 2
- 目的:
- `ControlFormBox` を単なるフィールド集合から実際に JSON v0 から Loop/If 形を復元するためのミニモデルに昇格させる
- ステップ:
- `lang/src/shared/mir/control_form_box.hako` 最低限のメソッドを追加:
- `from_loop(header_id, exit_id, body_blocks)`:
- header / exit / body block id 群を受け取り
- `kind_name = "loop"`
- `entry = header_id` or preheader 相当
- `loop_header` / `loop_exit` / `loop_body` / `loop_preheader` / `loop_latch` を設定
- 初期はheader/exit/body の簡易版 OKpreheader/latch は後から詰める)。
- `from_if(cond_block, then_block, else_block, merge_block)`:
- IfShape に対応する形で `kind_name = "if"` と各フィールドを設定
- これらはまだ LoopSSA からは呼ばずユニットテスト小さな JSON or 擬似値で構築が通ることだけ確認
### I3: BreakFinderBox を ControlFormBox ベースに寄せる準備
- 目的:
- ループの header/exit/body ControlFormBox に落とし込む第一歩を作る
- ステップ:
- `BreakFinderBox._find_loops` で作っている `loop_info`header/exit/bodyに対して:
- `ControlFormBox.from_loop(header_id, exit_id, body_blocks)` を呼び出して ControlFormBox を生成
- trace=1 のとき `"[loopssa/control] Loop header=..., exit=..., body=[...]"` のようなログを追加
- まだ `LoopSSA.stabilize_merges` の戻り値には影響させない従来どおり breaks PhiInjectorBox のまま)。
### I4: StageB Test2/3 の観測ポイント整備
- 目的:
- `tools/test_stageb_min.sh` Test 2/3 実行時にLoopSSA/ControlFormBox まわりの情報を拾えるようにする
- ステップ:
- `HAKO_COMPILER_BUILDER_TRACE=1` 時のログにLoopSSA BreakFinderBox/ControlFormBox の状況を追加:
- 例: `[loopssa] loop count=N`, `[loopssa/control] loop#i header=..., exit=..., body=[...]`
- `.hako` 側ではまだ Exit PHI ControlFormBox 経由にはしていないので
どの loop/exit に対してどんな breaks が検出されているかを見るところまでで止める
## このフェーズで「しない」こと
- `.hako` LoopSSA で本格的に Exit PHI を再実装すること:
- synthetic value_id をやめて Rust 側同等の SSA/PHI .hako で完全再現するのは次フェーズの大仕事として分ける
- StageB 最小ハーネスの赤ログを必ずゼロにすること:
- 25.1i はあくまで LoopSSA v2 / ControlFormBox を設計組み込み始めるフェーズ
- undefined ValueId / `%0` 問題の根治は 25.1j 以降のターゲットにする