feat(phi): Step 5-1/5-2/5-4実装 - Writes収集+ValueId比較+PHI縮約

🎯 **実装内容**:
- Step 5-1: Writes集合収集(Snapshot比較で再代入検出)
- Step 5-2: ValueId比較ロジック(preheader_vars保存)
- Step 5-4: φ縮約実装(optimize_same_value()でself-φ撲滅)

📦 **変更ファイル**:
- loopform_builder.rs: preheader_vars追加、seal_phis()にPHI縮約ロジック
- loop_.rs (JSON): Writes収集実装
- loop_builder.rs (AST): Writes収集実装(JSON経路と統一)

 **テスト結果**: 266 PASS / 1 FAIL (既知のmir_funcscanner_skip_ws)
🔧 **Box Theory**: 各箱が単一責任を保持、段階的実装完了

📋 **残タスク**:
- Step 5-5: mir_funcscanner_skip_wsのPHI pred mismatch解決
- ValueId(712)の生成箇所特定(body-local PHI疑惑)
This commit is contained in:
nyash-codex
2025-11-20 13:26:57 +09:00
parent 146b167e49
commit 2cdef5432a
3 changed files with 137 additions and 12 deletions

View File

@ -335,6 +335,30 @@ impl<'a> LoopBuilder<'a> {
// Capture variable snapshot at end of body (before jumping to latch)
let body_end_vars = self.get_current_variable_map();
// Step 5-1: Writes集合収集選択肢2+3統合: Snapshot比較で再代入検出
// current_vars (preheader) と body_end_vars を比較し、ValueId が変わった変数を特定
use std::collections::HashSet;
let mut writes = HashSet::new();
for (name, &body_value) in &body_end_vars {
if let Some(&base_value) = current_vars.get(name) {
if body_value != base_value {
writes.insert(name.clone());
}
}
// else: body で新規定義された変数body-local、header PHI 不要
}
// DEBUG: Log writes collection
if std::env::var("NYASH_LOOPFORM_DEBUG").is_ok() {
eprintln!("[loopform/writes] === WRITES COLLECTION (Step 5-1) ===");
eprintln!("[loopform/writes] {} variables modified in loop body", writes.len());
let mut sorted_writes: Vec<_> = writes.iter().collect();
sorted_writes.sort();
for name in &sorted_writes {
eprintln!("[loopform/writes] WRITE: {}", name);
}
}
// Jump to latch if not already terminated
let actual_latch_id = if !is_current_block_terminated(self.parent_builder)? {
self.emit_jump(latch_id)?;
@ -487,7 +511,8 @@ impl<'a> LoopBuilder<'a> {
} else {
vec![(continue_merge_id, merged_snapshot.clone())]
};
loopform.seal_phis(self, actual_latch_id, &continue_snaps)?;
// Step 5-1/5-2: Pass writes 集合 for PHI縮約
loopform.seal_phis(self, actual_latch_id, &continue_snaps, &writes)?;
// Step 3: seal body-local PHIs (complete the inputs)
if !body_local_vars.is_empty() {
@ -547,7 +572,6 @@ impl<'a> LoopBuilder<'a> {
// Phase 25.1h: ControlForm統合版に切り替え
// continue / break のターゲットブロックをユニーク化して収集
use std::collections::HashSet;
let mut break_set: HashSet<BasicBlockId> = HashSet::new();
for (bb, _) in &self.exit_snapshots {
break_set.insert(*bb);