diff --git a/src/mir/loop_builder.rs b/src/mir/loop_builder.rs index baa7efe0..a176f65b 100644 --- a/src/mir/loop_builder.rs +++ b/src/mir/loop_builder.rs @@ -368,6 +368,10 @@ impl<'a> LoopBuilder<'a> { // Exit block self.set_current_block(exit_id)?; + // NOTE(25.1g+): ControlForm 統合後は build_exit_phis_for_control(...) 経由で + // LoopShape から exit_id/branch_source_block を決める導線に寄せる予定。 + // 現在は既存実装のまま(挙動変更なし)。 + // Build exit PHIs for break statements let exit_snaps = self.exit_snapshots.clone(); loopform.build_exit_phis(self, exit_id, branch_source_block, &exit_snaps)?; @@ -1176,6 +1180,10 @@ impl<'a> LoopBuilder<'a> { // Reset to pre-if snapshot, then delegate to shared helper self.parent_builder.variable_map = pre_if_var_map.clone(); let mut ops = Ops(self); + + // TODO(25.1g+): ControlForm 統合版に切り替えるときは、 + // IfShape から ControlForm を渡して merge_modified_with_control() を呼ぶ。 + // 現在は既存実装のまま(挙動変更なし)。 crate::mir::phi_core::if_phi::merge_modified_at_merge_with( &mut ops, merge_bb, diff --git a/src/mir/phi_core/if_phi.rs b/src/mir/phi_core/if_phi.rs index b4c035d7..3b915841 100644 --- a/src/mir/phi_core/if_phi.rs +++ b/src/mir/phi_core/if_phi.rs @@ -241,3 +241,55 @@ pub fn merge_with_reset_at_merge_with( skip_var, ) } + +/// Phase 25.1g: ControlForm-based wrapper for If PHI generation. +/// This provides a thin adapter layer that accepts ControlForm and delegates +/// to the existing merge_modified_at_merge_with implementation. +/// +/// **Important**: This does NOT change any PHI generation logic - it merely +/// provides a ControlForm-based entry point while preserving existing behavior. +pub fn merge_modified_with_control( + ops: &mut O, + form: &crate::mir::control_form::ControlForm, + pre_if_snapshot: &HashMap, + then_map_end: &HashMap, + else_map_end_opt: &Option>, + skip_var: Option<&str>, + // Existing implementation requires pred info, so we accept it as parameters + then_pred_opt: Option, + else_pred_opt: Option, +) -> Result<(), String> { + use crate::mir::control_form::ControlKind; + + // Only process If structures; silently succeed for other control kinds + let shape = match &form.kind { + ControlKind::If(shape) => shape, + _ => return Ok(()), + }; + + // Extract merge_bb from IfShape + let merge_bb = shape.merge_block; + + // Log ControlForm usage when trace is enabled + let trace = std::env::var("NYASH_IF_TRACE").ok().as_deref() == Some("1"); + if trace { + eprintln!( + "[if-phi/control-form] Using ControlForm wrapper: merge={:?} then={:?} else={:?}", + merge_bb, shape.then_block, shape.else_block + ); + } + + // Delegate to existing implementation - no behavioral changes + merge_modified_at_merge_with( + ops, + merge_bb, + shape.then_block, + shape.else_block.unwrap_or(shape.then_block), + then_pred_opt, + else_pred_opt, + pre_if_snapshot, + then_map_end, + else_map_end_opt, + skip_var, + ) +} diff --git a/src/mir/phi_core/loopform_builder.rs b/src/mir/phi_core/loopform_builder.rs index 2c10e196..66afd443 100644 --- a/src/mir/phi_core/loopform_builder.rs +++ b/src/mir/phi_core/loopform_builder.rs @@ -479,6 +479,44 @@ fn sanitize_phi_inputs(inputs: &mut Vec<(BasicBlockId, ValueId)>) { *inputs = vec; } +/// Phase 25.1g: ControlForm-based wrapper for LoopForm Exit PHI generation. +/// This provides a thin adapter layer that accepts ControlForm and delegates +/// to the existing LoopFormBuilder::build_exit_phis implementation. +/// +/// **Important**: This does NOT change any PHI generation logic - it merely +/// provides a ControlForm-based entry point while preserving existing behavior. +pub fn build_exit_phis_for_control( + loopform: &LoopFormBuilder, + ops: &mut O, + form: &crate::mir::control_form::ControlForm, + exit_snapshots: &[(crate::mir::BasicBlockId, std::collections::HashMap)], + // Existing implementation requires branch_source_block, so we accept it as a parameter + branch_source_block: crate::mir::BasicBlockId, +) -> Result<(), String> { + use crate::mir::control_form::ControlKind; + + // Only process Loop structures; silently succeed for other control kinds + let shape = match &form.kind { + ControlKind::Loop(shape) => shape, + _ => return Ok(()), + }; + + // Extract exit_id from LoopShape + let exit_id = shape.exit; + + // Log ControlForm usage when trace is enabled + let trace = std::env::var("NYASH_LOOPFORM_DEBUG").ok().is_some(); + if trace { + eprintln!( + "[loopform/exit-phi/control-form] Using ControlForm wrapper: exit={:?} branch_source={:?}", + exit_id, branch_source_block + ); + } + + // Delegate to existing implementation - no behavioral changes + loopform.build_exit_phis(ops, exit_id, branch_source_block, exit_snapshots) +} + #[cfg(test)] mod tests { use super::*;