refactor(mir): Phase 25.1o - do_break/continue 共通化(LoopExitKind型統一)

【変更内容】
1. LoopExitKind enum定義
   - Break / Continue の型安全な区別

2. do_loop_exit() 共通メソッド作成(47行)
   - スナップショット取得(共通処理)
   - kind別のスナップショット保存
   - kind別のジャンプターゲット
   - unreachable ブロック切り替え(共通処理)

3. do_break/continue をthin wrapperに変換
   - do_break: 13行 → 4行
   - do_continue: 12行 → 4行
   - 合計21行削減

【効果】
- 構造改善: break/continue の共通ロジック一箇所に集約
- 保守性向上: デバッグログなどの共通処理が統一管理
- 拡張性向上: labeled break/continue等の将来拡張が容易

【検証結果】
- ビルド成功(警告なし)
- mir_stageb_loop_break_continue_verifies: PASS
- /tmp/loop_continue_fixed.hako: RC=3(期待通り)

関連: Phase 25.1m (continue PHI修正), Phase 25.1n (レガシー削除)
This commit is contained in:
nyash-codex
2025-11-19 08:56:44 +09:00
parent 77fc670cd3
commit 75f3df2505
11 changed files with 92 additions and 89 deletions

View File

@ -89,16 +89,9 @@ pub fn build_loop(
condition: &ASTNode,
body: &Vec<ASTNode>,
) -> Result<ValueId, String> {
// Check feature flag
let use_loopform_v2 = std::env::var("NYASH_LOOPFORM_PHI_V2")
.map(|v| v == "1" || v.to_lowercase() == "true")
.unwrap_or(false);
if use_loopform_v2 {
self.build_loop_with_loopform(condition, body)
} else {
self.build_loop_legacy(condition, body)
}
// 設計当初は feature flagNYASH_LOOPFORM_PHI_V2で切り替える案だったが、
// 現在は LoopForm v2 が既定実装なので常に build_loop_with_loopform を使う。
self.build_loop_with_loopform(condition, body)
}
fn build_loop_with_loopform(
@ -177,8 +170,7 @@ fn build_loop_legacy(
# Build with new implementation
cargo build --release
# Test fibonacci
export NYASH_LOOPFORM_PHI_V2=1
# Test fibonacci(現在はフラグ不要)
./target/release/nyash local_tests/fib_multi_carrier.hako
# Expected output: 8
@ -186,8 +178,7 @@ export NYASH_LOOPFORM_PHI_V2=1
**Debugging**:
```bash
# Enable MIR dump
export NYASH_LOOPFORM_PHI_V2=1
# Enable MIR dump(現在はフラグ不要)
./target/release/nyash --dump-mir local_tests/fib_multi_carrier.hako
# Check for:
@ -202,9 +193,7 @@ export NYASH_LOOPFORM_PHI_V2=1
**Run existing tests**:
```bash
export NYASH_LOOPFORM_PHI_V2=1
# Simple loops
# Simple loopsLoopForm v2 は既定 ON
tools/smokes/v2/run.sh --profile quick --filter "loop_simple"
# Multi-carrier loops

View File

@ -100,11 +100,13 @@ preheader → header (PHI nodes) → body → latch → header
### Integration Points
**Feature Flag**: `NYASH_LOOPFORM_PHI_V2=1` (environment variable)
**Status**: 当初は `NYASH_LOOPFORM_PHI_V2=1` で opt-in する Feature Flag 案だったが、
現在は LoopFormBuilder を用いた PHI 生成が **常に既定実装** になっている。
過去の段階的移行案(参考・設計メモとして残す):
**Migration Strategy**:
```rust
// In mir/loop_builder.rs
// In mir/loop_builder.rs (設計当初の案。現在は v2 が常時有効)
if std::env::var("NYASH_LOOPFORM_PHI_V2").is_ok() {
// Use new LoopFormBuilder
let mut loopform = LoopFormBuilder::new(preheader_id, header_id);
@ -148,38 +150,10 @@ if std::env::var("NYASH_LOOPFORM_PHI_V2").is_ok() {
## Testing Strategy
### Phase 1: Smoke Tests
```bash
# Enable new implementation
export NYASH_LOOPFORM_PHI_V2=1
### Phase 13: 現在の運用メモ
# Test fibonacci multi-carrier
cargo build --release
./target/release/nyash local_tests/fib_multi_carrier.hako
# Expected: 8 (correct fibonacci(6))
# Run all loop tests
tools/smokes/v2/run.sh --profile quick --filter "loop"
```
### Phase 2: Regression Testing
```bash
# Compare output with/without new implementation
for test in local_tests/loop_*.hako; do
echo "Testing $test"
NYASH_LOOPFORM_PHI_V2=0 ./target/release/nyash "$test" > /tmp/old.out
NYASH_LOOPFORM_PHI_V2=1 ./target/release/nyash "$test" > /tmp/new.out
diff /tmp/old.out /tmp/new.out || echo "MISMATCH: $test"
done
```
### Phase 3: Performance Validation
```bash
# Ensure no performance regression
hyperfine \
'NYASH_LOOPFORM_PHI_V2=0 ./target/release/nyash bench/loop_heavy.hako' \
'NYASH_LOOPFORM_PHI_V2=1 ./target/release/nyash bench/loop_heavy.hako'
```
- 実装が LoopForm v2 に一本化されたため、`NYASH_LOOPFORM_PHI_V2` による A/B 比較フェーズは既に完了済み。
- 以降の性能比較や回帰テストでは、単に `./target/release/nyash` を直接叩けばよい(フラグ不要)。
---

View File

@ -18,7 +18,7 @@ Status: design+partial implementationStage1 ビルド導線の初期版まで
- 担当: StageB/Stage1/selfhost で見えている Undefined Value / nondominating use を、まず Rust 階層だけで止血する。
- **25.1e — LoopForm PHI v2 MigrationRust**
- ねらい: ループの PHI 生成の「SSOT」を LoopForm v2 + `phi_core` に寄せ、Legacy LoopBuilder 経路との二重管理を解消する。
- 担当: `NYASH_LOOPFORM_PHI_V2=1` を使って Stage1 / StageB 代表ループ(`_find_from` や stageb_minを通し、`phi pred mismatch` / ValueId 二重定義を構造的に解消する。
- 担当: 当初は `NYASH_LOOPFORM_PHI_V2=1` を使って Stage1 / StageB 代表ループ(`_find_from` や stageb_minを通し、`phi pred mismatch` / ValueId 二重定義を構造的に解消する計画だったが、現在は LoopForm v2 が既定実装となっており、フラグは不要(互換目的のみ)
ざっくりとした進行順は「25.1a/c で配線と箱分割 → 25.1d/e で Rust MIR/LoopForm を根治 → その結果を踏まえて 25.1bselfhost MirBuilder/LoopSSA側に寄せていく」というイメージだよ。

View File

@ -30,9 +30,10 @@ Status: planningLoopForm/PHI 正規化フェーズ・挙動は変えない/
- **SSOT を決める**:
- ループの PHI 生成の「正」は LoopForm v2 (`LoopFormBuilder` + `LoopFormOps` + `phi_core::loop_phi/if_phi`) に置く。
- `build_loop_legacy` + `prepare_loop_variables_with` は「互換レイヤ/移行レイヤ」と位置づけ、最終的には LoopForm v2 の薄いラッパに縮退させる。
- **Feature Flag で段階導入**:
- `NYASH_LOOPFORM_PHI_V2=1` のときだけ LoopForm v2 経路を使い、当面は StageB / Stage1 / selfhost 用テストの中でピンポイントに有効化する。
- デフォルト挙動は変えない(フラグ未設定時はこれまでどおり legacy 経路
- **Feature Flag で段階導入(※この段階の設計メモ)**:
- 当初は `NYASH_LOOPFORM_PHI_V2=1` のときだけ LoopForm v2 経路を使う案だったが、
現在は LoopForm v2 が既定実装となっておりlegacy 経路は撤去済み
- `NYASH_LOOPFORM_PHI_V2` は互換性のために残っているが、挙動切り替えには使われない。
- **1 バグ 1 パターンで前進**:
- `mir_stage1_using_resolver_full_collect_entries_verifies` や StageB 最小ハーネスで見えている赤ログは、それぞれ最小 Hako に絞って LoopForm v2 側で再現・修正する。
- 同時に legacy 側からは同じ責務PHI 生成ロジック)を抜いていき、二重管理を減らす。
@ -41,9 +42,9 @@ Status: planningLoopForm/PHI 正規化フェーズ・挙動は変えない/
### 1. LoopForm v2 の足場をテストで固める
1.1 LoopForm v2 専用テストモードの追加
- `mir_stage1_using_resolver_full_collect_entries_verifies` をベースに、`NYASH_LOOPFORM_PHI_V2=1` を立てた状態でのみ走るサブテストを追加。
- 目的: v2 経路で `_find_from` ループの SSA/PHI が整合していることを検証する足場を作る(まだ赤でもよい)。
1.1 LoopForm v2 専用テストモードの追加(→ 現在は「LoopForm v2 が既定」の前提で完了)
- `mir_stage1_using_resolver_full_collect_entries_verifies` は LoopForm v2 前提で緑になっており、
もはやフラグは不要(テスト内の `NYASH_LOOPFORM_PHI_V2` 設定も削除済み)。
1.2 StageB 最小ハーネス用ループ抜き出しテスト
- `lang/src/compiler/tests/stageb_min_sample.hako` から、代表的なループだけを抜き出した Hako を作り、LoopForm v2 経路(`NYASH_LOOPFORM_PHI_V2=1`)で `MirVerifier` を通すテストを追加。