Files
hakorune/docs/development/roadmap/phases/phase-25.1k/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

91 lines
5.9 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.1k — LoopSSA v2 実装 & StageB SSA 安定化(.hako 本体版)
Status: planning.hako 側 LoopSSA v2 本体実装Rust 側は既存 SSA/PHI を SSOT として維持)
## ゴール
- 25.1j までに固めた LoopSSA/BreakFinderBox/PhiInjectorBox の責務・設計をベースに、
`.hako` 側 LoopSSA v2 の **実装本体** に踏み込むフェーズだよ。
- 具体的には:
- StageB minimal harness`tools/test_stageb_min.sh`)の Test 2/3 で出ている:
- `BreakFinderBox._find_loops/2` 周辺の `use of undefined value ValueId(50)`Rust VM 側エラー)
- `%0` 由来の SSA エラー(`NYASH_VM_VERIFY_MIR=1` 時)
**LoopSSA v2 の改善によって減らす/消す** ことを狙う。
- 文字列ハードコードベースの `_collect_phi_vars` / synthetic `"r{block}_{var}"` を、
Carrier/Pinned ベースの設計に一歩近づける(完全置き換えまでは行かなくても OK
## 前提25.1j までで揃っているもの)
- Rust 側:
- LoopForm v2 + Conservative PHI Box + ControlForm が統合済みで、If/Loop の SSA/PHI は緑。
- StageB 風ループRust テスト)も LoopForm v2 / Conservative PHI で安定している。
- `.hako` 側:
- LoopSSA パス:
- `LoopSSA.stabilize_merges(stage1_json)``BreakFinderBox.find_breaks(json, trace_flag)`
`PhiInjectorBox.inject_exit_phis(json, breaks, trace_flag)` の 2 段構成で動作。
- trace/ENV 解釈は LoopSSA に一元化され、下流には 0/1 の `trace_flag` だけ渡す構造に整理済み。
- BreakFinderBox:
- `_find_loops(json_str, trace)``"loop_header":` / `"loop_exit":` から loop を検出。
- `loop_info``{"header", "exit", "body", "control"}` を格納し、`control` に ControlFormBox を添付。
- PhiInjectorBox:
- 現状は `common_vars = ["i","n","item","j","count","val"]` に対する簡易版 `_collect_phi_vars`
- value_id は `"r{block_id}_{var_name}"` 形式の synthetic 値(観測用のダミー)を返している。
- ドキュメント:
- 25.1j の README で LoopSSA/BreakFinderBox/PhiInjectorBox の責務境界と Carrier/Pinned/Invariants 概念を明文化済み。
## 方針25.1k: LoopSSA v2 の「中身」を少し前に進める)
### KA: StageB Test2 の ValueId(50) 問題の最小再現と LoopSSA 切り分け
- 目的:
- `BreakFinderBox._find_loops/2` で発生している `use of undefined value ValueId(50)` を、
「LoopSSA が生成した JSON の問題なのか」「他フェーズの JSON なのか」切り分ける。
- ステップ:
1. `tools/test_stageb_min.sh` Test2 の JSON 出力を一時ファイルに保存StageB → Program(JSON v0) 直後)。
2. その JSON に対して:
- Rust 側 MirBuilder に直接食わせて `NYASH_VM_VERIFY_MIR=1` を通す。
- `.hako` 側 LoopSSA を単独で呼び出す(`LoopSSA.stabilize_merges(json)`)最小ハーネスを用意。
3. どの時点で ValueId(50) が未定義になるかを特定し、
それが LoopSSA の改変前後で変わっているかを確認する。
### KB: BreakFinderBox の LoopScope 精度の向上(保守的に)
- 目的:
- `_find_loop_body` の「header_id < id < exit_idヒューリスティックが過剰/過少に body を拾っていないかを確認改善する
- ステップ:
- ControlFormBox を活用して LoopScope の妥当性をチェック:
- header/exit/body に対して Rust LoopForm v2 の期待と比較しやすい形でログを出すblock id 範囲など)。
- 必要であれば:
- body 集合をexit から逆到達できる blockなどより保守的な条件に修正文字列ベースの範囲内で)。
- ゴール:
- LoopSSA 本来そのループに属さない block body に含めないようにするValueId(50) のような飛び火を防ぐ)。
### KC: PhiInjectorBox の v2 への一歩Carrier/Pinned の入口だけ作る)
- 目的:
- `_collect_phi_vars` の完全置き換えまでは行かずに今後の移行先となる v2 API の入口を整える
- ステップ:
- `PhiInjectorBox` に新しい内部ヘルパーを追加例: `_collect_phi_vars_v2(json_str, break_list, loop_info)`:
- まだ中身は stub でもよいが、「Carrier/Pinned/Invariants 3 区分を引数/戻り値で表現できる形にする
- 25.1k では v1 実装`_collect_phi_vars`を実際に置き換えずtrace=1 の時だけ v2 の診断ログを出すくらいに留める
- `loop_info.get("control")` ControlFormBox から header/exit/body を読み取り
どの変数が本来の Carrier に相当しそうかをログに出すまだ PHI には使わない)。
### KD: StageB Test3 (%0) の「悪化していない」ことの確認
- 目的:
- LoopSSA v2 の変更がStageB Test3 `%0` SSA 問題を悪化させていないことを確認する
- ステップ:
- `NYASH_VM_VERIFY_MIR=1` Test3 を流したときのエラー位置関数名/ブロック/命令を記録
- 25.1k の差分適用前後で比較しLoopSSA 関連の変更による新規エラーが出ていないことを確認
- 必要ならTest3 から LoopSSA を一時オフ`HAKO_LOOPSSA_EXIT_PHI=0`にした場合のログも取っておき
LoopSSA が原因の部分それ以外を明確に切り分ける
## このフェーズで「しない」こと
- PhiInjectorBox `_collect_phi_vars` / `_get_var_value` **完全刷新すること**:
- これは 25.1k の次25.1l 以降の本格 v2 実装のタスクとして分ける
- Rust LoopForm v2 / Conservative PHI の設計を変えること:
- Rust 側はあくまで SSOT であり、.hako 側はそれに追従する形で徐々に近づける