docs(loops): LoopForm SSOT設計ノートを追加し、Bridge側ループ降下にPHI到達検証を導入(debug時)。\n\n- 新規: docs/development/architecture/loops/loopform_ssot.md\n- 修正: src/runner/json_v0_bridge/lowering/loop_.rs に debug_verify_phi_inputs 呼び出しを追加\n- 方針: Direct MIR は既に phi_core を使用。Bridge は段階的に LoopPhiOps アダプタでSSOTに寄せる

This commit is contained in:
nyash-codex
2025-11-01 16:37:16 +09:00
parent 01b4417c5d
commit eef6fca8cd
2 changed files with 53 additions and 0 deletions

View File

@ -0,0 +1,33 @@
# LoopForm SSOT単一起点設計ート
目的
- ループのPHI整形・前処理preheader Copy、header PHI seed、latch/continue 合流)を単一モジュールに集約してドリフトを防ぐ。
- ビルダーDirect MIRとブリッジJSON v0 → MIRの双方で同一の規約と検証を通す。
SSOTSingle 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段階移行
- まず同等の順序・検証を導入Copy→Phi→Latch更新時の検証
- 将来的に `LoopPhiOps` アダプタを追加して SSOT API を直接呼び出す。
規約(不変条件)
- header の PHI 入力は「preheader 経由の定義済み値」と「latch/continue からの値」だけ。
- preheader で Copy を先行挿入し、PHI 入力は Copy の出力を参照するUse-Before-Def回避
- 1 predecessor なら直接 bindPHI省略、2つ以上で PHI を生成。
- 検証は FailFast ではなく開発時 WARN`debug_assert`)だが、将来 Core 側で整形に移管予定。
今後の移行
- Bridge 側に `LoopPhiOps` 実装を追加し、`prepare/seal/exit` を直接呼ぶ。
- ループ形状の生成をユーティリティ化builder/bridge 双方から共通呼び出し)。
関連
- `src/mir/loop_builder.rs`
- `src/runner/json_v0_bridge/lowering/loop_.rs`
- `src/mir/phi_core/common.rs`

View File

@ -54,6 +54,15 @@ pub(super) fn lower_loop_stmt(
inputs: vec![(cur_bb, copy_val)], inputs: vec![(cur_bb, copy_val)],
}); });
} }
// 開発時検証SSOTと同等の不変条件チェック
#[cfg(debug_assertions)]
{
crate::mir::phi_core::common::debug_verify_phi_inputs(
f,
cond_bb,
&[(cur_bb, copy_val)],
);
}
phi_map.insert(name.clone(), dst); phi_map.insert(name.clone(), dst);
} }
} }
@ -90,6 +99,17 @@ pub(super) fn lower_loop_stmt(
for (name, &phi_dst) in &phi_map { for (name, &phi_dst) in &phi_map {
if let Some(&latch_val) = body_vars.get(name) { if let Some(&latch_val) = body_vars.get(name) {
bb.update_phi_input(phi_dst, (bend, latch_val))?; bb.update_phi_input(phi_dst, (bend, latch_val))?;
// 2要素目preheader copy + latchの到達検証
#[cfg(debug_assertions)]
{
if let Some(&pre_copy) = copy_map.get(name) {
crate::mir::phi_core::common::debug_verify_phi_inputs(
f,
cond_bb,
&[(cur_bb, pre_copy), (bend, latch_val)],
);
}
}
} }
} }
} }