feat(phi): Option C実装 - 箱分割設計でPHIバグ根本修正(基本実装)
## 実装内容 ### 新規モジュール(箱理論設計) 1. **LocalScopeInspectorBox** (280行, 13テスト) - 各変数がどのブロックで定義されているか追跡 - is_defined_in_all() で全exit predsでの定義チェック - record_snapshot() でスナップショット記録 2. **LoopVarClassBox** (220行, 10テスト) - 変数を4種類に分類: Pinned/Carrier/BodyLocalExit/BodyLocalInternal - needs_exit_phi() でPHI生成要否判定 - filter_exit_phi_candidates() で候補フィルタリング ### 既存モジュール修正 3. **loop_snapshot_merge.rs** - merge_exit_with_classification() 追加 - Option Cロジック実装: 全exit predsで定義されていない変数はSKIP - デバッグログ追加 (NYASH_OPTION_C_DEBUG) 4. **loopform_builder.rs** - build_exit_phis() シグネチャ拡張 (inspector追加) - 実際のCFG predecessors使用 (ops.get_block_predecessors) - build_exit_phis_for_control() でinspector構築 5. **loop_.rs (JSON bridge)** - build_exit_phis() 呼び出し修正 - header/exit snapshots記録 ## 技術的成果 ### ✅ 理論的に正しい設計確立 - 変数スコープを厳密に追跡 - CFGベースの正確な判定 - 汎用的で拡張性の高い基盤 ### ✅ 部分的動作確認済み - 多数のループで BodyLocalInternal が正しくSKIPされる - ログ: "[Option C] → SKIP exit PHI for 'ch'" 確認 - 23個のユニットテスト全PASS ### ⚠️ 残存課題 - header snapshot記録漏れによる一部誤判定 - 次回修正で完全動作見込み ## 設計哲学(箱理論) 各箱が単一責任を持つ: - LocalScopeInspectorBox: 変数定義位置の追跡のみ - LoopVarClassBox: 変数分類のみ - LoopSnapshotMergeBox: PHI入力生成のみ → 保守性・再利用性・テスタビリティの向上 Related: #skip_whitespace PHI bug 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -327,7 +327,24 @@ pub(super) fn lower_loop_stmt(
|
||||
loopform.seal_phis(&mut ops, latch_bb, &canonical_continue_snaps)?;
|
||||
|
||||
// 8) exit PHI(header fallthrough + break スナップショット)
|
||||
loopform.build_exit_phis(&mut ops, exit_bb, cend, &exit_snaps)?;
|
||||
// Option C: Build LocalScopeInspectorBox from exit snapshots
|
||||
use crate::mir::phi_core::local_scope_inspector::LocalScopeInspectorBox;
|
||||
let mut inspector = LocalScopeInspectorBox::new();
|
||||
|
||||
// Record header variable definitions (pinned + carriers)
|
||||
for pinned in &loopform.pinned {
|
||||
inspector.record_definition(&pinned.name, loopform.header_id);
|
||||
}
|
||||
for carrier in &loopform.carriers {
|
||||
inspector.record_definition(&carrier.name, loopform.header_id);
|
||||
}
|
||||
|
||||
// Record all variable definitions from exit snapshots
|
||||
for (block_id, snapshot) in &exit_snaps {
|
||||
inspector.record_snapshot(*block_id, snapshot);
|
||||
}
|
||||
|
||||
loopform.build_exit_phis(&mut ops, exit_bb, cend, &exit_snaps, &inspector)?;
|
||||
|
||||
Ok(exit_bb)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user