refactor(mir): Phase 7-H完了 - レガシーヘルパー Phase 2B削除 🎉 1000行切り達成!

**削除内容**(孤立関数2個):
-  prepare_loop_variables() (51行) - build_loop_legacy削除で呼び出し喪失
-  find_copy_source() (28行) - デバッグ観測専用、未使用

**削減効果**:
- **削減行数**: 79行(Task先生予測と完全一致)
- **削減率**: 7.2%(1096行 → 1017行)
- **🎉 1000行切り達成!🎉**
- **テスト**: 全グリーン維持 

**技術的成果**:
- loop_builder.rs: 1422行 → 1017行(**28.5%削減!**)
- Phase 1-2合計削除: 405行(286行 Phase 1 + 119行 Phase 2)
- LoopForm v2統一完了の証明

**残存警告(Phase 2C保留)**:
- 2つの dead_code 警告(Task先生が保留推奨)
  - emit_safepoint (4行) - GC/安全点実装時に将来必要
  - mark_block_sealed (12行) - 基盤API

**テスト結果(全グリーン維持)**:
-  mir_loopform_exit_phi (4 tests)
-  mir_stage1_using_resolver (1 test)
-  mir_stageb_loop_break_continue (2 tests)

**Phase 7完全達成**:
- 7-A: LoopForm v2デフォルト化
- 7-B: Conservative PHI実装
- 7-C: Stage-1 resolver完全検証
- 7-D: ControlForm導線追加
- 7-E: ControlForm統合実装
- 7-F: レガシーループ削除 Phase 1
- 7-G: レガシーヘルパー Phase 2A
- 7-H: レガシーヘルパー Phase 2B ← 🎉 1000行切り達成!

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
nyash-codex
2025-11-18 20:38:30 +09:00
parent 71653a4af5
commit 263affe379

View File

@ -51,34 +51,6 @@ impl<'a> LoopBuilder<'a> {
/// Find the source value of a Copy instruction in a given block /// Find the source value of a Copy instruction in a given block
/// If `dst` is defined by a Copy instruction `dst = copy src`, return Some(src) /// If `dst` is defined by a Copy instruction `dst = copy src`, return Some(src)
/// Otherwise return None /// Otherwise return None
fn find_copy_source(&self, block_id: BasicBlockId, dst: ValueId) -> Option<ValueId> {
let func = self.parent_builder.current_function.as_ref()?;
let block = func.blocks.get(&block_id)?;
let trace = std::env::var("NYASH_LOOP_TRACE").ok().as_deref() == Some("1");
if trace {
eprintln!("[loop/copy-trace] searching for dst={:?} in block={:?}, {} instructions",
dst, block_id, block.instructions.len());
}
for (idx, inst) in block.instructions.iter().enumerate() {
if let MirInstruction::Copy { dst: inst_dst, src } = inst {
if trace {
eprintln!("[loop/copy-trace] inst#{}: %{} = copy %{}", idx, inst_dst.0, src.0);
}
if *inst_dst == dst {
if trace {
eprintln!("[loop/copy-trace] FOUND! dst={:?} src={:?}", dst, src);
}
return Some(*src);
}
}
}
if trace {
eprintln!("[loop/copy-trace] NOT FOUND for dst={:?}", dst);
}
None
}
// ============================================================= // =============================================================
// Control Helpers — break/continue/jumps/unreachable handling // Control Helpers — break/continue/jumps/unreachable handling
@ -415,57 +387,6 @@ impl<'a> LoopBuilder<'a> {
/// - ループキャリア(ループ本体で再代入される変数)と pinned 変数のみを PHI 対象とする。 /// - ループキャリア(ループ本体で再代入される変数)と pinned 変数のみを PHI 対象とする。
/// - ループ不変のローカルtext_len / pattern_len など)は preheader 値をそのまま使い、 /// - ループ不変のローカルtext_len / pattern_len など)は preheader 値をそのまま使い、
/// 不要な PHI を張らないことで SSA 破綻(同一 ValueId の二重定義)を防ぐ。 /// 不要な PHI を張らないことで SSA 破綻(同一 ValueId の二重定義)を防ぐ。
fn prepare_loop_variables(
&mut self,
header_id: BasicBlockId,
preheader_id: BasicBlockId,
pre_vars_snapshot: &std::collections::HashMap<String, ValueId>,
assigned_vars: &[String],
) -> Result<Vec<crate::mir::phi_core::loop_phi::IncompletePhi>, String> {
use std::sync::atomic::{AtomicUsize, Ordering};
static CALL_COUNT: AtomicUsize = AtomicUsize::new(0);
let count = CALL_COUNT.fetch_add(1, Ordering::SeqCst);
// Use the variable map captured at preheader (before switching to header),
// but filter to:
// - ループキャリアassigned_vars に含まれる変数)
// - pinned 変数__pin$*: 受信箱など、ループをまたいで値を運ぶ必要があるもの
let mut current_vars = std::collections::HashMap::new();
for (name, &val) in pre_vars_snapshot.iter() {
if name.starts_with("__pin$") {
current_vars.insert(name.clone(), val);
continue;
}
if assigned_vars.iter().any(|v| v == name) {
current_vars.insert(name.clone(), val);
}
}
// Debug: print current_vars before prepare (guarded by env)
let dbg = std::env::var("NYASH_BUILDER_DEBUG").ok().as_deref() == Some("1");
if dbg {
eprintln!("[DEBUG] prepare_loop_variables call #{}", count);
eprintln!("[DEBUG] current_vars = {:?}", current_vars);
eprintln!(
"[DEBUG] preheader_id = {:?}, header_id = {:?}",
preheader_id, header_id
);
}
crate::mir::phi_core::loop_phi::save_block_snapshot(
&mut self.block_var_maps,
preheader_id,
&current_vars,
);
let incs = crate::mir::phi_core::loop_phi::prepare_loop_variables_with(
self,
header_id,
preheader_id,
&current_vars,
)?;
// Defer variable rebinding to PHI IDs until after the loop condition is emitted.
// Store incomplete PHIs for later sealing and for rebinding after branch emission.
self.incomplete_phis.insert(header_id, incs.clone());
Ok(incs)
}
/// ブロックをシールし、不完全なPhi nodeを完成させる /// ブロックをシールし、不完全なPhi nodeを完成させる