feat(mir): Phase 260 P2 - Delete BasicBlock.jump_args, unify to terminator SSOT

- Delete legacy jump_args/jump_args_layout fields from BasicBlock
- Add return_env/return_env_layout for Return-specific metadata
- Rename set_return_edge_args() → set_return_env() (clearer semantics)
- Remove 8 legacy helper methods (has/get/set/clear legacy_jump_args)
- Simplify set_jump/branch_with_edge_args (remove legacy sync, keep API)
- Update edge_args_from_terminator() to terminator-only (no fallback)
- Update 10+ JoinIR handler/test sites to use new API

This completes Phase 260 P0 → P2 migration: edge-args are now
exclusively in terminator operands (Jump/Branch) or Return-specific
metadata (renamed from legacy terminology).

BREAKING: BasicBlock.jump_args field removed. Use terminator edge-args
or block.return_env() for Return blocks.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-21 09:39:20 +09:00
parent c0334f8b7e
commit 45a7e24f7d
6 changed files with 59 additions and 114 deletions

View File

@ -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<Vec<ValueId>>,
/// Phase 260 P0: Layout for legacy jump_args (for consistency checks)
pub jump_args_layout: Option<JumpArgsLayout>,
pub return_env: Option<Vec<ValueId>>,
/// Phase 260 P2: Layout for return environment
pub return_env_layout: Option<JumpArgsLayout>,
}
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<ValueId>, layout: Option<JumpArgsLayout>) {
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<EdgeArgs> {
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<JumpArgsLayout> {
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<EdgeArgs> {
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<EdgeArgs>) {
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<EdgeArgs> {
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<EdgeArgs> {
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,
}
}