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

@ -227,6 +227,19 @@ pub(super) fn lower_loop_stmt(
// 1) preheader スナップショットEnv_in(loop)
let base_vars = vars.clone();
// DEBUG: Log preheader snapshot
if std::env::var("NYASH_LOOPFORM_DEBUG").is_ok() {
eprintln!("[loop_/lower] === PREHEADER SNAPSHOT (bb={:?}) ===", preheader_bb);
eprintln!("[loop_/lower] Function: {}", f.signature.name);
eprintln!("[loop_/lower] base_vars.len() = {}", base_vars.len());
let mut sorted: Vec<_> = base_vars.iter().collect();
sorted.sort_by_key(|(name, _)| name.as_str());
for (name, value) in &sorted {
eprintln!("[loop_/lower] preheader var: {} = {:?}", name, value);
}
}
let mut block_var_maps: HashMap<BasicBlockId, HashMap<String, ValueId>> = HashMap::new();
block_var_maps.insert(preheader_bb, base_vars.clone());
@ -258,6 +271,32 @@ pub(super) fn lower_loop_stmt(
let _ = super::pop_increment_hint();
let bend = bend_res?;
// Step 5-1: Writes集合収集選択肢2+3統合: Snapshot比較で再代入検出
// base_vars (preheader) と body_vars を比較し、ValueId が変わった変数を特定
use std::collections::HashSet;
let mut writes = HashSet::new();
for (name, &body_value) in &body_vars {
if let Some(&base_value) = base_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() {
let func_name = ops.f.signature.name.clone(); // Clone before borrowing
eprintln!("[loop_/lower] === WRITES COLLECTION (Step 5-1) ===");
eprintln!("[loop_/lower] Function: {}", func_name);
eprintln!("[loop_/lower] {} variables modified in loop body", writes.len());
let mut sorted_writes: Vec<_> = writes.iter().collect();
sorted_writes.sort();
for name in &sorted_writes {
eprintln!("[loop_/lower] WRITE: {}", name);
}
}
// スナップショット収集Env_out(loop) 用)
let continue_snaps = super::pop_continue_snapshots();
let exit_snaps = super::pop_exit_snapshots();
@ -324,7 +363,8 @@ pub(super) fn lower_loop_stmt(
};
// 7) header PHI seallatch + canonical continue_merge スナップショット)
loopform.seal_phis(&mut ops, latch_bb, &canonical_continue_snaps)?;
// Step 5-1/5-2: Pass writes 集合 for PHI縮約
loopform.seal_phis(&mut ops, latch_bb, &canonical_continue_snaps, &writes)?;
// 8) exit PHIheader fallthrough + break スナップショット)
// Option C: Create inspector (build_exit_phis will populate it)