- ✅ [LoopForm] タグで統一コメント追加 - src/mir/loop_builder.rs - header-cond: Case A/B分岐説明 - exit-break path / continue-backedge path - exit PHI for Case A/B - src/mir/phi_core/loop_snapshot_merge.rs - Case A/B分岐: header ∈ exit_preds判定ロジック - src/mir/phi_core/exit_phi_builder.rs - LoopForm Process ステップバイステップ説明 - ✅ UsingCollectorBox Region+next_i化 - lang/src/compiler/parser/using/using_collector_box.hako - 全ループをLoopForm v2形式に統一 - next_i, next_j, next_k, next_t パターン導入 - SSA安全化(未定義変数撲滅) - ✅ LoopForm v2 ケース表完成 - docs/development/architecture/loops/loopform_ssot.md - Case A/B/C/D の完全な表 - テスト対応マッピング - 実装ファイル対応表 🎯 成果: LoopForm v2の「形」をソース・テスト・ドキュメントで完全固定
4.7 KiB
4.7 KiB
LoopForm SSOT(単一起点)設計ノート
目的
- ループのPHI整形・前処理(preheader Copy、header PHI seed、latch/continue 合流)を単一モジュールに集約してドリフトを防ぐ。
- ビルダー(Direct MIR)とブリッジ(JSON v0 → MIR)の双方で同一の規約と検証を通す。
SSOT(Single Source of Truth)
- 中心:
src/mir/phi_core/loop_phi.rs- 型:
IncompletePhi,VarSnapshot - API:
prepare_loop_variables_with,seal_incomplete_phis_with,build_exit_phis_with - デバッグ:
phi_core::common::debug_verify_phi_inputs(到達検証・重複検出)
- 型:
- Direct MIR(既にSSOT使用)
src/mir/loop_builder.rsがLoopPhiOpsを実装し、prepare/seal/exitを phi_core へ委譲。- 形状:
preheader → header(φ) → body → latch → header|exit(LoopForm準拠)。
- JSON v0 Bridge(段階移行→完了済みの範囲)
- header PHI(seed/完成)・exit PHI を
LoopPhiOpsアダプタ経由で SSOT API に委譲。 - break/continue スナップショットは thread‑local stack で収集し、seal/build_exit に渡す。
- 代表 parity カナリア(opt‑in)で Direct と Bridge の一致を検証。
- header PHI(seed/完成)・exit PHI を
規約(不変条件)
- header の PHI 入力は「preheader 経由の定義済み値」と「latch/continue からの値」だけ。
- preheader で Copy を先行挿入し、PHI 入力は Copy の出力を参照する(Use-Before-Def回避)。
- 1 predecessor なら直接 bind(PHI省略)、2つ以上で PHI を生成。
- 検証は Fail‑Fast ではなく開発時 WARN(
debug_assert)だが、将来 Core 側で整形に移管予定。
今後の移行
- Bridge 側に
LoopPhiOps実装を追加し、prepare/seal/exitを直接呼ぶ。 - ループ形状の生成をユーティリティ化(builder/bridge 双方から共通呼び出し)。
LoopForm v2 ケース表
| Case | loop 条件形 | exit preds の構成 | 想定される PHI 入力の形 | 対応テスト | 対応 .hako |
|---|---|---|---|---|---|
| A | loop(i < n) |
header / body | header fallthrough + break | loop_conditional_reassign_exit_phi_header_and_break |
- |
| B | loop(1 == 1) |
body のみ | break のみ | loop_constant_true_exit_phi_dominates |
apps/tests/minimal_ssa_skip_ws.hako |
| C | loop(1 == 1) + body-local |
body のみ(一部の経路のみ定義) | break のみ(BodyLocalInternal は除外) | loop_body_local_exit_phi_body_only |
- |
| D | loop(i < n) + continue |
header / body / continue_merge | header + break + continue_merge | loop_continue_merge_header_exit |
- |
ケース説明
Case A: header+break(標準パターン)
- 条件:
loop(i < n)のような動的条件 - 特徴: header→exit と body→exit の両方が CFG 上存在
- exit PHI: header fallthrough + break 経路の両方を含む
- 検証:
loop_conditional_reassign_exit_phi_header_and_break
Case B: constant-true+break-only(header 除外パターン)
- 条件:
loop(1 == 1)のような定数 true - 特徴: exit pred は break 経路のみ(
header→exitは無い) - exit PHI: break 経路のみ(header は CFG predecessor でないため除外)
- 検証:
loop_constant_true_exit_phi_dominates+minimal_ssa_skip_ws.hako
Case C: body-local変数(BodyLocalInternal 除外パターン)
- 条件: body 内で宣言された変数が一部の exit 経路でのみ定義される
- 特徴: 変数が全 exit predecessors で定義されていない
- exit PHI: BodyLocalInternal 変数は除外(PHI 生成しない)
- 検証:
loop_body_local_exit_phi_body_only
Case D: continue+break(continue_merge パターン)
- 条件: continue 文を含むループ
- 特徴:
continue_merge → header → exitの経路あり - exit PHI: header + break + continue_merge の 3 系統
- 検証:
loop_continue_merge_header_exit
実装ファイル
| ファイル | 役割 |
|---|---|
src/mir/loop_builder.rs |
ループ構造生成・[LoopForm] コメント付き |
src/mir/phi_core/loop_snapshot_merge.rs |
Case A/B 分岐ロジック |
src/mir/phi_core/exit_phi_builder.rs |
Exit PHI 生成・Phantom block 除外 |
src/tests/mir_loopform_conditional_reassign.rs |
4 ケース全てのテスト([LoopForm-Test] タグ付き) |
関連
src/mir/loop_builder.rssrc/runner/json_v0_bridge/lowering/loop_.rssrc/mir/phi_core/common.rssrc/mir/phi_core/loop_snapshot_merge.rssrc/mir/phi_core/exit_phi_builder.rssrc/tests/mir_loopform_conditional_reassign.rs