diff --git a/src/mir/basic_block.rs b/src/mir/basic_block.rs index 6b2dbcf4..7e22d4c9 100644 --- a/src/mir/basic_block.rs +++ b/src/mir/basic_block.rs @@ -92,13 +92,14 @@ pub struct BasicBlock { /// Is this block sealed? (all predecessors are known) pub sealed: bool, - /// Phase 246-EX: Jump args metadata for exit PHI construction + /// Phase 260 P2: Return environment metadata + /// Return has no edge-args operand, so we keep metadata for continuation. /// When a JoinIR Jump is converted to MIR Return, this field preserves /// all the Jump args (not just the first one) so that exit PHI can correctly /// merge carrier values from multiple exit paths. - pub jump_args: Option>, - /// Phase 260 P0: Layout for legacy jump_args (for consistency checks) - pub jump_args_layout: Option, + pub return_env: Option>, + /// Phase 260 P2: Layout for return environment + pub return_env_layout: Option, } impl BasicBlock { @@ -115,8 +116,8 @@ impl BasicBlock { effects: EffectMask::PURE, reachable: false, sealed: false, - jump_args: None, // Phase 246-EX: No jump args by default - jump_args_layout: None, // Phase 260 P0: Unknown by default + return_env: None, // Phase 260 P2: No return env by default + return_env_layout: None, // Phase 260 P2: Unknown by default } } @@ -236,7 +237,7 @@ impl BasicBlock { .. }) => vec![OutEdge { target, - args: edge_args.clone().or_else(|| self.legacy_edge_args()), + args: edge_args.clone(), // Phase 260 P2: No fallback, terminator SSOT }], _ => Vec::new(), } @@ -250,59 +251,33 @@ impl BasicBlock { .and_then(|edge| edge.args) } - /// Set legacy jump args metadata (migration helper) - pub fn set_legacy_jump_args(&mut self, values: Vec, layout: Option) { - self.jump_args = Some(values.clone()); - self.jump_args_layout = layout; - if let (Some(layout), Some(MirInstruction::Jump { target, edge_args: None })) = - (layout, self.terminator.clone()) - { - let edge_args = EdgeArgs { layout, values }; - self.set_jump_with_edge_args(target, Some(edge_args)); - } - } - - /// Record edge-args for Return terminators (migration helper) + /// Set Return environment metadata (Return-specific) /// - /// Return has no edge-args operand, so we keep this metadata for now. - pub fn set_return_edge_args(&mut self, edge_args: EdgeArgs) { + /// Return has no edge-args operand, so we keep this metadata for continuation. + pub fn set_return_env(&mut self, env: EdgeArgs) { if !matches!(self.terminator, Some(MirInstruction::Return { .. })) { - panic!("set_return_edge_args requires Return terminator"); + panic!("set_return_env requires Return terminator"); } - self.jump_args = Some(edge_args.values); - self.jump_args_layout = Some(edge_args.layout); + self.return_env = Some(env.values); + self.return_env_layout = Some(env.layout); } - /// Clear legacy jump args metadata (migration helper) - pub fn clear_legacy_jump_args(&mut self) { - self.jump_args = None; - self.jump_args_layout = None; + /// Get Return environment metadata + pub fn return_env(&self) -> Option { + if matches!(self.terminator, Some(MirInstruction::Return { .. })) { + match (self.return_env.as_ref(), self.return_env_layout) { + (Some(values), Some(layout)) => Some(EdgeArgs { + layout, + values: values.clone(), + }), + _ => None, + } + } else { + None + } } - /// Check if legacy jump args metadata exists - pub fn has_legacy_jump_args(&self) -> bool { - self.jump_args.is_some() - } - - /// Access legacy jump args values (read-only, migration helper) - pub fn legacy_jump_args_values(&self) -> Option<&[ValueId]> { - self.jump_args.as_deref() - } - - /// Access legacy jump args layout (read-only, migration helper) - pub fn legacy_jump_args_layout(&self) -> Option { - self.jump_args_layout - } - - /// Build edge args from legacy values with an explicit layout (migration helper) - pub fn legacy_edge_args_with_layout(&self, layout: JumpArgsLayout) -> Option { - self.jump_args.as_ref().map(|values| EdgeArgs { - layout, - values: values.clone(), - }) - } - - /// Set jump terminator with edge args and legacy metadata (SSOT write helper) + /// Set jump terminator with edge args (SSOT write helper) pub fn set_jump_with_edge_args(&mut self, target: BasicBlockId, edge_args: Option) { let terminator = MirInstruction::Jump { target, @@ -315,16 +290,10 @@ impl BasicBlock { self.effects = self.effects | terminator.effects(); self.terminator = Some(terminator); self.terminator_span = Some(Span::unknown()); - if let Some(args) = edge_args { - self.jump_args = Some(args.values.clone()); - self.jump_args_layout = Some(args.layout); - } else { - self.clear_legacy_jump_args(); - } self.update_successors_from_terminator(); } - /// Set branch terminator with per-edge args (clears legacy metadata) + /// Set branch terminator with per-edge args pub fn set_branch_with_edge_args( &mut self, condition: ValueId, @@ -347,29 +316,16 @@ impl BasicBlock { self.effects = self.effects | terminator.effects(); self.terminator = Some(terminator); self.terminator_span = Some(Span::unknown()); - self.clear_legacy_jump_args(); self.update_successors_from_terminator(); } - fn legacy_edge_args(&self) -> Option { - let values = self.jump_args.as_ref()?; - let layout = self.jump_args_layout?; - Some(EdgeArgs { - layout, - values: values.clone(), - }) - } - - /// Get edge-args from the current terminator (migration helper) + /// Get edge-args from the current terminator /// - /// Jump uses its edge-args operand when present, otherwise falls back to - /// stored metadata. Return relies on stored metadata. + /// Jump uses its edge-args operand. Return uses return_env metadata. pub fn edge_args_from_terminator(&self) -> Option { match self.terminator { - Some(MirInstruction::Jump { ref edge_args, .. }) => { - edge_args.clone().or_else(|| self.legacy_edge_args()) - } - Some(MirInstruction::Return { .. }) => self.legacy_edge_args(), + Some(MirInstruction::Jump { ref edge_args, .. }) => edge_args.clone(), + Some(MirInstruction::Return { .. }) => self.return_env(), _ => None, } } diff --git a/src/mir/control_tree/normalized_shadow/loop_true_break_once.rs b/src/mir/control_tree/normalized_shadow/loop_true_break_once.rs index 406cefe9..f003d30e 100644 --- a/src/mir/control_tree/normalized_shadow/loop_true_break_once.rs +++ b/src/mir/control_tree/normalized_shadow/loop_true_break_once.rs @@ -744,8 +744,8 @@ mod tests { .get(&entry) .expect("missing loop_body entry block"); assert!( - entry_block.has_legacy_jump_args(), - "loop_body entry block must have legacy jump_args metadata in bridged MIR" + entry_block.return_env().is_some(), + "loop_body entry block must have return_env metadata in bridged MIR" ); // Loop-only (the routing path in real lowering): still must encode loop_step as a tail-call. diff --git a/src/mir/join_ir_vm_bridge/handlers/call.rs b/src/mir/join_ir_vm_bridge/handlers/call.rs index 26bb3cc4..6090fc44 100644 --- a/src/mir/join_ir_vm_bridge/handlers/call.rs +++ b/src/mir/join_ir_vm_bridge/handlers/call.rs @@ -198,8 +198,8 @@ where terminator, ); if let Some(block) = mir_func.blocks.get_mut(¤t_block_id) { - if block.terminator.is_some() && !block.has_legacy_jump_args() { - block.set_return_edge_args(crate::mir::EdgeArgs { + if matches!(block.terminator, Some(MirInstruction::Return { .. })) && block.return_env().is_none() { + block.set_return_env(crate::mir::EdgeArgs { layout: JumpArgsLayout::CarriersOnly, values: args.to_vec(), }); @@ -365,12 +365,10 @@ mod tests { _ => panic!("Expected Return terminator"), } - // Check legacy jump args metadata - assert!(block.has_legacy_jump_args()); - let jump_args = block.legacy_jump_args_values().unwrap(); - let layout = block.legacy_jump_args_layout(); - assert_eq!(jump_args, &[ValueId(10), ValueId(20)]); - assert_eq!(layout, Some(JumpArgsLayout::CarriersOnly)); + // Check return environment metadata + let env = block.return_env().expect("Block should have return_env"); + assert_eq!(env.values, vec![ValueId(10), ValueId(20)]); + assert_eq!(env.layout, JumpArgsLayout::CarriersOnly); } #[test] diff --git a/src/mir/join_ir_vm_bridge/handlers/jump.rs b/src/mir/join_ir_vm_bridge/handlers/jump.rs index b54598be..97483c87 100644 --- a/src/mir/join_ir_vm_bridge/handlers/jump.rs +++ b/src/mir/join_ir_vm_bridge/handlers/jump.rs @@ -221,7 +221,7 @@ where exit_block.set_terminator(MirInstruction::Return { value: Some(call_result_id), }); - exit_block.set_return_edge_args(crate::mir::EdgeArgs { + exit_block.set_return_env(crate::mir::EdgeArgs { layout: JumpArgsLayout::CarriersOnly, values: args.to_vec(), }); @@ -250,8 +250,8 @@ where finalize_fn(mir_func, current_block_id, current_instructions, return_terminator); if let Some(block) = mir_func.blocks.get_mut(¤t_block_id) { - if block.terminator.is_some() && !block.has_legacy_jump_args() { - block.set_return_edge_args(crate::mir::EdgeArgs { + if matches!(block.terminator, Some(MirInstruction::Return { .. })) && block.return_env().is_none() { + block.set_return_env(crate::mir::EdgeArgs { layout: JumpArgsLayout::CarriersOnly, values: args.to_vec(), }); @@ -391,12 +391,10 @@ mod tests { _ => panic!("Expected Return terminator"), } - // Check legacy jump args metadata - assert!(block.has_legacy_jump_args()); - let jump_args = block.legacy_jump_args_values().unwrap(); - let layout = block.legacy_jump_args_layout(); - assert_eq!(jump_args, &[ValueId(10), ValueId(20)]); - assert_eq!(layout, Some(JumpArgsLayout::CarriersOnly)); + // Check return environment metadata + let env = block.return_env().expect("Block should have return_env"); + assert_eq!(env.values, vec![ValueId(10), ValueId(20)]); + assert_eq!(env.layout, JumpArgsLayout::CarriersOnly); } #[test] @@ -479,12 +477,10 @@ mod tests { _ => panic!("Expected Return terminator"), } - // Check legacy jump args metadata in exit block - assert!(exit_block.has_legacy_jump_args()); - let jump_args = exit_block.legacy_jump_args_values().unwrap(); - let layout = exit_block.legacy_jump_args_layout(); - assert_eq!(jump_args, &[ValueId(1), ValueId(2)]); - assert_eq!(layout, Some(JumpArgsLayout::CarriersOnly)); + // Check return environment metadata in exit block + let env = exit_block.return_env().expect("Exit block should have return_env"); + assert_eq!(env.values, vec![ValueId(1), ValueId(2)]); + assert_eq!(env.layout, JumpArgsLayout::CarriersOnly); // Check continue block exists and is empty let continue_block = mir_func.blocks.get(&BasicBlockId(2)).unwrap(); diff --git a/src/mir/join_ir_vm_bridge/joinir_block_converter.rs b/src/mir/join_ir_vm_bridge/joinir_block_converter.rs index cbf5a07c..20e7b17a 100644 --- a/src/mir/join_ir_vm_bridge/joinir_block_converter.rs +++ b/src/mir/join_ir_vm_bridge/joinir_block_converter.rs @@ -443,8 +443,8 @@ impl JoinIrBlockConverter { terminator, ); if let Some(block) = mir_func.blocks.get_mut(&self.current_block_id) { - if block.terminator.is_some() && !block.has_legacy_jump_args() { - block.set_return_edge_args(crate::mir::EdgeArgs { + if matches!(block.terminator, Some(MirInstruction::Return { .. })) && block.return_env().is_none() { + block.set_return_env(crate::mir::EdgeArgs { layout: JumpArgsLayout::CarriersOnly, values: args.to_vec(), }); @@ -521,7 +521,7 @@ impl JoinIrBlockConverter { }); exit_block.instruction_spans.push(Span::unknown()); exit_block.set_terminator(MirInstruction::Return { value: Some(call_result_id) }); - exit_block.set_return_edge_args(crate::mir::EdgeArgs { + exit_block.set_return_env(crate::mir::EdgeArgs { layout: JumpArgsLayout::CarriersOnly, values: args.to_vec(), }); @@ -557,8 +557,8 @@ impl JoinIrBlockConverter { return_terminator, ); if let Some(block) = mir_func.blocks.get_mut(&self.current_block_id) { - if block.terminator.is_some() && !block.has_legacy_jump_args() { - block.set_return_edge_args(crate::mir::EdgeArgs { + if matches!(block.terminator, Some(MirInstruction::Return { .. })) && block.return_env().is_none() { + block.set_return_env(crate::mir::EdgeArgs { layout: JumpArgsLayout::CarriersOnly, values: args.to_vec(), }); diff --git a/src/mir/join_ir_vm_bridge/normalized_bridge/direct.rs b/src/mir/join_ir_vm_bridge/normalized_bridge/direct.rs index d33ab8d6..8658587e 100644 --- a/src/mir/join_ir_vm_bridge/normalized_bridge/direct.rs +++ b/src/mir/join_ir_vm_bridge/normalized_bridge/direct.rs @@ -422,7 +422,7 @@ fn build_exit_or_tail_branch( block.instructions.clear(); block.instruction_spans.clear(); block.set_terminator(MirInstruction::Return { value: ret_val }); - block.set_return_edge_args(crate::mir::EdgeArgs { + block.set_return_env(crate::mir::EdgeArgs { layout: JumpArgsLayout::CarriersOnly, values: env.to_vec(), }); @@ -484,7 +484,6 @@ fn finalize_block( target, edge_args: None, }); - block.clear_legacy_jump_args(); } } MirInstruction::Branch { @@ -501,22 +500,18 @@ fn finalize_block( else_bb, else_edge_args, ); - block.clear_legacy_jump_args(); } MirInstruction::Return { .. } => { block.set_terminator(terminator); if let Some(args) = jump_args { - block.set_return_edge_args(crate::mir::EdgeArgs { + block.set_return_env(crate::mir::EdgeArgs { layout: JumpArgsLayout::CarriersOnly, values: args, }); - } else { - block.clear_legacy_jump_args(); } } other => { block.set_terminator(other); - block.clear_legacy_jump_args(); } } }