Files
hakorune/docs/development/current/main/phases/phase-188.3/P1-INSTRUCTIONS.md
tomoaki c6ffc06660 feat(joinir): Phase 188.3-P3.1,3.2 - AST extraction & validation helpers
Phase 3-1 完了: extract_inner_loop_ast() 実装
- 外側 loop body から内側 loop を抽出
- 正確に 1 つの inner loop を検証
- 0 個 or 2+ 個の場合は明示エラー (Fail-Fast)

Phase 3-2 完了: validate_strict_mode() プレースホルダー
- 現在は大半の検証を is_pattern6_lowerable() で実施
- 将来の strict mode チェック用の足場

ドキュメント追加:
- P1-INSTRUCTIONS.md: Phase 3-3 実装指示書 (4関数モデル詳細)
- README.md: max_loop_depth 定義の明確化
- 10-Now.md: Phase 188.3 方針の整合性維持

次タスク: Phase 3-3 (Continuation 生成) - P1-INSTRUCTIONS.md 参照

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-27 06:22:59 +09:00

5.1 KiB
Raw Blame History

Phase 188.3 P1: Pattern6NestedLoopMinimallowering を “実装済み” にする

Date: 2025-12-27
Scope: Pattern6 の lowering 実装fixture を PASS
Non-goals: 汎用 nested loop / break/continue / 多段ネスト / 多重 inner loop


Success Criteria

  • apps/tests/phase1883_nested_minimal.hako--backend vmexit=9
  • ./tools/smokes/v2/run.sh --profile quick154/154 PASS
  • integration selfhost が FAIL=0 維持
  • Pattern6 を選んだ後に silent fallback しないFail-Fast

SSOT / Constraints

  • ネスト深さ SSOT: StepTreeFeatures.max_loop_depth
  • Pattern6 選択 SSOT: src/mir/builder/control_flow/joinir/routing.rs::choose_pattern_kind()
  • Phase 188.2: strict では depth > 2 を明示エラー
  • 本タスクで触るのは “lowering stub を実装” のみ

Fixture目標

apps/tests/phase1883_nested_minimal.hako を SSOT とするAdd/Compare のみ)。


実装方針(重要)

1) sum は carrier として渡す(グローバル禁止)

inner loop が outer の sum を更新しているので、JoinIR では sum を引数で運び、k_inner_exit で outer に戻す

  • sum を “グローバル変数” 扱いにしてはいけない(箱理論と Fail-Fast 的にも事故る)

2) merge の「loop_step 選定」を壊さない

JoinIR merge は「main でも continuation でもない関数」を 1つ選んで “loop header” とみなす。 nested loop では inner_step が混ざるので、inner_step / k_inner_exit を boundary の continuation_func_ids に入れて除外する。

これをしないと、merge が誤って inner_step を loop header として選び、PHI/exit binding が壊れる。


実装タスク(順番)

Task A: lowering を実装する

対象: src/mir/builder/control_flow/joinir/patterns/pattern6_nested_minimal.rs

やること:

  • lower()Err している stub を置き換えて、JoinIR pipeline を呼ぶ
  • 最小形だけ対応し、外れた形は Pattern6 選択前に落とすis_pattern6_lowerable() 側を強化)か、ここで明示エラー

推奨構成Pattern1 と同じ流儀):

  • JoinIR 生成は src/mir/join_ir/lowering/nested_loop_minimal.rs(新規)に切り出す
  • builder 側は「context 作成 → JoinModule → boundary → conversion pipeline」のみ

(ただし PoC なので builder 側に直書きでも可。差分は最小に。)

Task B: JoinIRnested minimalを生成する

参考: src/mir/join_ir/lowering/simple_while_minimal.rs

最小形の JoinIR 関数構成(推奨):

  • main(i0, sum0):
    • Call(loop_step, [i0, sum0])
    • Ret 0statement-position
  • loop_step(i, sum)outer:
    • exit_cond = !(i < N_outer)
    • Jump(k_exit, [sum], cond=exit_cond)
    • Call(inner_step, [j0, i, sum])
  • inner_step(j, i_outer, sum):
    • exit_cond = !(j < N_inner)
    • Jump(k_inner_exit, [i_outer, sum], cond=exit_cond)
    • sum_next = sum + 1
    • j_next = j + 1
    • Call(inner_step, [j_next, i_outer, sum_next])
  • k_inner_exit(i, sum):
    • i_next = i + 1
    • Call(loop_step, [i_next, sum])
  • k_exit(sum):
    • Ret sum

命名:

  • k_exit は canonical name: src/mir/join_ir/lowering/canonical_names.rs::K_EXIT
  • loop_step は canonical name: ...::LOOP_STEP
  • inner_step / k_inner_exit は Phase 188.3 で追加(文字列でよいが、可能なら canonical_names に追加)

Task C: boundaryexit binding + continuation funcsを正しく構築する

参考: src/mir/builder/control_flow/joinir/patterns/pattern1_minimal.rs

必須:

  • join_inputs/host_inputs は JoinModule.entry.params と同順・同数
  • exit_bindingssum を host slot に reconnect
    • join_exit_value は k_exit の paramPattern1 と同じく join_module.require_function("k_exit").params[0] から取得)
  • continuation_func_ids に以下を含める:
    • k_exit
    • k_inner_exit
    • inner_step

Task D: integration smoke を追加するexit code SSOT

新規:

  • tools/smokes/v2/profiles/integration/joinir/phase1883_nested_minimal_vm.sh
    • apps/tests/phase1883_nested_minimal.hako を実行し、exit code == 9 で PASS
    • stdout 比較はしない

注意:

  • tools/smokes/v2manifest.txt 方式ではない(find ベース)
  • 既存の helper を使う: source tools/smokes/v2/lib/test_runner.sh

検証手順

  1. cargo build --release
  2. ./target/release/hakorune --backend vm apps/tests/phase1883_nested_minimal.hakoexit=9
  3. ./tools/smokes/v2/run.sh --profile integration --filter "phase1883_nested_minimal"
  4. ./tools/smokes/v2/run.sh --profile quick154/154 PASS
  5. ./tools/smokes/v2/run.sh --profile integration --filter "selfhost_"FAIL=0

追加の注意Fail-Fast

  • Pattern6 が選ばれたあとに Ok(None) で他パターンに流すのは禁止silent fallback
  • “選ぶ前に落とす” が最も安全:
    • is_pattern6_lowerable() を「lowering が確実に通る形だけ true」に強化する