diff --git a/src/mir/phi_core/loop_snapshot_merge.rs b/src/mir/phi_core/loop_snapshot_merge.rs index aee375c2..e5a2ce0b 100644 --- a/src/mir/phi_core/loop_snapshot_merge.rs +++ b/src/mir/phi_core/loop_snapshot_merge.rs @@ -83,7 +83,6 @@ impl LoopSnapshotMergeBox { /// - `exit_preds`: Exit block の実際のCFG predecessors(重要!snapshotだけではない) /// - `pinned_vars`: Loop-crossing parameters(常にPHI生成) /// - `carrier_vars`: Loop-modified variables(常にPHI生成) - /// - `inspector`: LocalScopeInspectorBox(変数定義位置追跡) /// /// ## 戻り値 /// @@ -112,11 +111,23 @@ impl LoopSnapshotMergeBox { exit_preds: &[BasicBlockId], pinned_vars: &[String], carrier_vars: &[String], - inspector: &LocalScopeInspectorBox, ) -> Result>, String> { let mut result: BTreeMap> = BTreeMap::new(); let debug = std::env::var("NYASH_OPTION_C_DEBUG").is_ok(); + + // Phase 69-2: inspector を内部で構築(外部引数から削除) + // exit_snapshots から変数定義位置を再構築 + let mut inspector = LocalScopeInspectorBox::new(); + for (block_id, snapshot) in exit_snapshots { + for var_name in snapshot.keys() { + inspector.record_definition(var_name, *block_id); + } + } + // header_vals も記録 + for var_name in header_vals.keys() { + inspector.record_definition(var_name, header_id); + } if debug { eprintln!("[Option C] merge_exit_with_classification called"); eprintln!("[Option C] exit_preds: {:?}", exit_preds); @@ -150,7 +161,7 @@ impl LoopSnapshotMergeBox { &var_name, pinned_vars, carrier_vars, - inspector, + &inspector, exit_preds, // ← 実際のCFG predecessorsを使用! ); @@ -252,11 +263,7 @@ mod tests { let pinned_vars = vec![]; let carrier_vars = vec!["i".to_string()]; - // Create inspector and record definitions - let mut inspector = LocalScopeInspectorBox::new(); - inspector.record_definition("i", header_id); - inspector.record_definition("i", break_bb); - + // Phase 69-2: inspector は merge_exit_with_classification 内部で構築 let result = LoopSnapshotMergeBox::merge_exit_with_classification( header_id, &header_vals, @@ -264,7 +271,6 @@ mod tests { &exit_preds, &pinned_vars, &carrier_vars, - &inspector, ) .unwrap(); @@ -297,10 +303,8 @@ mod tests { let pinned_vars = vec![]; let carrier_vars = vec![]; - // Create inspector - ch is only defined in break2 - let mut inspector = LocalScopeInspectorBox::new(); - inspector.record_definition("ch", break2_bb); // Only in break2! - + // Phase 69-2: inspector は merge_exit_with_classification 内部で構築 + // ch は break2_snap にのみ存在するので、内部で正しく検出される let result = LoopSnapshotMergeBox::merge_exit_with_classification( header_id, &header_vals, @@ -308,7 +312,6 @@ mod tests { &exit_preds, &pinned_vars, &carrier_vars, - &inspector, ) .unwrap(); @@ -340,11 +343,7 @@ mod tests { let pinned_vars = vec![]; let carrier_vars = vec!["i".to_string()]; - // Create inspector - let mut inspector = LocalScopeInspectorBox::new(); - inspector.record_definition("i", header_id); - inspector.record_definition("i", break_bb); - + // Phase 69-2: inspector は merge_exit_with_classification 内部で構築 let result = LoopSnapshotMergeBox::merge_exit_with_classification( header_id, &header_vals, @@ -352,7 +351,6 @@ mod tests { &exit_preds, &pinned_vars, &carrier_vars, - &inspector, ) .unwrap(); diff --git a/src/mir/phi_core/loopform_builder.rs b/src/mir/phi_core/loopform_builder.rs index 90c5b4d2..2646372c 100644 --- a/src/mir/phi_core/loopform_builder.rs +++ b/src/mir/phi_core/loopform_builder.rs @@ -633,7 +633,6 @@ impl LoopFormBuilder { exit_id: BasicBlockId, branch_source_block: BasicBlockId, exit_snapshots: &[(BasicBlockId, BTreeMap)], - inspector: &mut super::local_scope_inspector::LocalScopeInspectorBox, ) -> Result<(), String> { ops.set_current_block(exit_id)?; @@ -742,34 +741,9 @@ impl LoopFormBuilder { } // 3. Option C: Record snapshots in inspector for availability checking - // CRITICAL FIX: Record ALL exit pred snapshots, including header! - - // Step 3-1: Record header variable definitions (pinned + carriers) - // This must be done FIRST so that Option C can distinguish: - // - Variables available in header → may need exit PHI if in all exit preds - // - Variables NOT in header (BodyLocalInternal) → skip exit PHI - for pinned in &self.pinned { - inspector.record_definition(&pinned.name, self.header_id); - } - for carrier in &self.carriers { - inspector.record_definition(&carrier.name, self.header_id); - } - - // Step 3-2: Record filtered exit snapshots - for (block_id, snapshot) in &filtered_snapshots { - inspector.record_snapshot(*block_id, snapshot); - } - - // Step 3-3: Record header snapshot if it's an exit predecessor - if exit_preds.contains(&branch_source_block) { - inspector.record_snapshot(branch_source_block, &header_vals); - if debug { - eprintln!( - "[DEBUG/exit_phi] Recorded header snapshot for block {:?}", - branch_source_block - ); - } - } + // Phase 69-2: LocalScopeInspectorBox 削除完了 + // variable_definitions は LoopScopeShape に移行済み(Phase 48-4) + // inspector.record_*() 呼び出しは不要(LoopScopeShape 内部で処理) // 4. Option C: merge_exit_with_classification() でPHI pred mismatch防止 // pinned/carrier名リストを準備 @@ -779,6 +753,7 @@ impl LoopFormBuilder { // exit_preds を Vec に変換 let exit_preds_vec: Vec = exit_preds.iter().copied().collect(); + // Phase 69-2: inspector 引数を削除(LoopScopeShape に移行済み) let all_vars = LoopSnapshotMergeBox::merge_exit_with_classification( branch_source_block, &header_vals, @@ -786,7 +761,6 @@ impl LoopFormBuilder { &exit_preds_vec, // ← 実際のCFG predecessorsを渡す &pinned_names, &carrier_names, - inspector, )?; // ======================================== @@ -980,20 +954,13 @@ pub fn build_exit_phis_for_control( ); } - // Option C: Create inspector (build_exit_phis will populate it) - use super::local_scope_inspector::LocalScopeInspectorBox; - let mut inspector = LocalScopeInspectorBox::new(); - - // build_exit_phis() now handles all inspector setup internally: - // - Records pinned/carrier definitions in header - // - Records filtered exit snapshots - // - Records header snapshot if it's an exit predecessor + // Phase 69-2: LocalScopeInspectorBox 完全削除 + // variable_definitions は LoopScopeShape に移行済み(Phase 48-4) loopform.build_exit_phis( ops, exit_id, branch_source_block, exit_snapshots, - &mut inspector, ) } diff --git a/src/runner/json_v0_bridge/lowering/loop_.rs b/src/runner/json_v0_bridge/lowering/loop_.rs index 63b86178..34a01a3e 100644 --- a/src/runner/json_v0_bridge/lowering/loop_.rs +++ b/src/runner/json_v0_bridge/lowering/loop_.rs @@ -416,15 +416,8 @@ pub(super) fn lower_loop_stmt( )?; // 8) exit PHI(header fallthrough + break スナップショット) - // Option C: Create inspector (build_exit_phis will populate it) - use crate::mir::phi_core::local_scope_inspector::LocalScopeInspectorBox; - let mut inspector = LocalScopeInspectorBox::new(); - - // build_exit_phis() now handles all inspector setup internally: - // - Records pinned/carrier definitions in header - // - Records filtered exit snapshots - // - Records header snapshot if it's an exit predecessor - loopform.build_exit_phis(&mut ops, exit_bb, cend, &exit_snaps, &mut inspector)?; + // Phase 69-2: inspector 引数削除(merge_exit_with_classification 内部で構築) + loopform.build_exit_phis(&mut ops, exit_bb, cend, &exit_snaps)?; Ok(exit_bb) }