phase29ao(p8): ssot compose preserves edgeargs for valuejoin
This commit is contained in:
@ -133,3 +133,47 @@ pub(crate) fn cleanup(
|
||||
branches,
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::cleanup;
|
||||
use crate::mir::basic_block::{BasicBlockId, EdgeArgs};
|
||||
use crate::mir::builder::control_flow::edgecfg::api::edge_stub::EdgeStub;
|
||||
use crate::mir::builder::control_flow::edgecfg::api::exit_kind::ExitKind;
|
||||
use crate::mir::builder::control_flow::edgecfg::api::frag::Frag;
|
||||
use crate::mir::join_ir::lowering::inline_boundary::JumpArgsLayout;
|
||||
use crate::mir::ValueId;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
#[test]
|
||||
fn cleanup_preserves_edgeargs_for_return_exit() {
|
||||
let main = Frag::new(BasicBlockId::new(1));
|
||||
let cleanup_entry = BasicBlockId::new(2);
|
||||
let args = EdgeArgs {
|
||||
layout: JumpArgsLayout::ExprResultPlusCarriers,
|
||||
values: vec![ValueId(30)],
|
||||
};
|
||||
let mut exits = BTreeMap::new();
|
||||
exits.insert(
|
||||
ExitKind::Return,
|
||||
vec![EdgeStub {
|
||||
from: cleanup_entry,
|
||||
kind: ExitKind::Return,
|
||||
target: None,
|
||||
args: args.clone(),
|
||||
}],
|
||||
);
|
||||
let cleanup_frag = Frag {
|
||||
entry: cleanup_entry,
|
||||
exits,
|
||||
wires: vec![],
|
||||
branches: vec![],
|
||||
};
|
||||
|
||||
let composed =
|
||||
cleanup(main, cleanup_frag, None, None).expect("cleanup ok");
|
||||
assert_eq!(composed.wires.len(), 1);
|
||||
assert_eq!(composed.wires[0].args, args);
|
||||
assert!(composed.wires[0].target.is_none());
|
||||
}
|
||||
}
|
||||
|
||||
@ -137,3 +137,93 @@ pub(crate) fn if_(
|
||||
branches, // Phase 267 P0: header の BranchStub + t/e/join の branches
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::if_;
|
||||
use crate::mir::basic_block::{BasicBlockId, EdgeArgs};
|
||||
use crate::mir::builder::control_flow::edgecfg::api::edge_stub::EdgeStub;
|
||||
use crate::mir::builder::control_flow::edgecfg::api::exit_kind::ExitKind;
|
||||
use crate::mir::builder::control_flow::edgecfg::api::frag::Frag;
|
||||
use crate::mir::join_ir::lowering::inline_boundary::JumpArgsLayout;
|
||||
use crate::mir::value_id::ValueId;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
#[test]
|
||||
fn if_preserves_edgeargs_for_then_else_normal_exits() {
|
||||
let header = BasicBlockId::new(1);
|
||||
let then_entry = BasicBlockId::new(2);
|
||||
let else_entry = BasicBlockId::new(3);
|
||||
let join_entry = BasicBlockId::new(4);
|
||||
let cond = ValueId(10);
|
||||
let then_entry_args = EdgeArgs {
|
||||
layout: JumpArgsLayout::CarriersOnly,
|
||||
values: vec![],
|
||||
};
|
||||
let else_entry_args = EdgeArgs {
|
||||
layout: JumpArgsLayout::CarriersOnly,
|
||||
values: vec![],
|
||||
};
|
||||
let then_args = EdgeArgs {
|
||||
layout: JumpArgsLayout::ExprResultPlusCarriers,
|
||||
values: vec![ValueId(20)],
|
||||
};
|
||||
let else_args = EdgeArgs {
|
||||
layout: JumpArgsLayout::ExprResultPlusCarriers,
|
||||
values: vec![ValueId(21)],
|
||||
};
|
||||
|
||||
let mut then_exits = BTreeMap::new();
|
||||
then_exits.insert(
|
||||
ExitKind::Normal,
|
||||
vec![EdgeStub {
|
||||
from: then_entry,
|
||||
kind: ExitKind::Normal,
|
||||
target: None,
|
||||
args: then_args.clone(),
|
||||
}],
|
||||
);
|
||||
let then_frag = Frag {
|
||||
entry: then_entry,
|
||||
exits: then_exits,
|
||||
wires: vec![],
|
||||
branches: vec![],
|
||||
};
|
||||
|
||||
let mut else_exits = BTreeMap::new();
|
||||
else_exits.insert(
|
||||
ExitKind::Normal,
|
||||
vec![EdgeStub {
|
||||
from: else_entry,
|
||||
kind: ExitKind::Normal,
|
||||
target: None,
|
||||
args: else_args.clone(),
|
||||
}],
|
||||
);
|
||||
let else_frag = Frag {
|
||||
entry: else_entry,
|
||||
exits: else_exits,
|
||||
wires: vec![],
|
||||
branches: vec![],
|
||||
};
|
||||
|
||||
let join_frag = Frag::new(join_entry);
|
||||
let composed = if_(
|
||||
header,
|
||||
cond,
|
||||
then_frag,
|
||||
then_entry_args,
|
||||
else_frag,
|
||||
else_entry_args,
|
||||
join_frag,
|
||||
);
|
||||
|
||||
assert_eq!(composed.wires.len(), 2);
|
||||
assert!(composed.wires.iter().any(|stub| {
|
||||
stub.target == Some(join_entry) && stub.args == then_args
|
||||
}));
|
||||
assert!(composed.wires.iter().any(|stub| {
|
||||
stub.target == Some(join_entry) && stub.args == else_args
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -87,3 +87,44 @@ pub(crate) fn seq(a: Frag, b: Frag) -> Frag {
|
||||
branches, // Phase 267 P0: a.branches + b.branches
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::seq;
|
||||
use crate::mir::basic_block::{BasicBlockId, EdgeArgs};
|
||||
use crate::mir::builder::control_flow::edgecfg::api::edge_stub::EdgeStub;
|
||||
use crate::mir::builder::control_flow::edgecfg::api::exit_kind::ExitKind;
|
||||
use crate::mir::builder::control_flow::edgecfg::api::frag::Frag;
|
||||
use crate::mir::join_ir::lowering::inline_boundary::JumpArgsLayout;
|
||||
use crate::mir::ValueId;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
#[test]
|
||||
fn seq_preserves_edgeargs_for_normal_exit() {
|
||||
let a_entry = BasicBlockId::new(1);
|
||||
let b_entry = BasicBlockId::new(2);
|
||||
let args = EdgeArgs {
|
||||
layout: JumpArgsLayout::ExprResultPlusCarriers,
|
||||
values: vec![ValueId(10)],
|
||||
};
|
||||
let stub = EdgeStub {
|
||||
from: a_entry,
|
||||
kind: ExitKind::Normal,
|
||||
target: None,
|
||||
args: args.clone(),
|
||||
};
|
||||
let mut exits = BTreeMap::new();
|
||||
exits.insert(ExitKind::Normal, vec![stub]);
|
||||
let a = Frag {
|
||||
entry: a_entry,
|
||||
exits,
|
||||
wires: vec![],
|
||||
branches: vec![],
|
||||
};
|
||||
let b = Frag::new(b_entry);
|
||||
let composed = seq(a, b);
|
||||
assert_eq!(composed.wires.len(), 1);
|
||||
assert_eq!(composed.wires[0].target, Some(b_entry));
|
||||
assert_eq!(composed.wires[0].args, args);
|
||||
}
|
||||
}
|
||||
|
||||
@ -397,16 +397,21 @@ mod tests {
|
||||
use crate::mir::basic_block::EdgeArgs;
|
||||
use crate::mir::builder::control_flow::edgecfg::api::{EdgeStub, ExitKind, Frag};
|
||||
use crate::mir::builder::control_flow::plan::CorePhiInfo;
|
||||
#[cfg(debug_assertions)]
|
||||
use crate::mir::builder::control_flow::plan::facts::feature_facts::{
|
||||
LoopFeatureFacts, ValueJoinFacts,
|
||||
};
|
||||
#[cfg(debug_assertions)]
|
||||
use crate::mir::builder::control_flow::plan::facts::loop_facts::LoopFacts;
|
||||
#[cfg(debug_assertions)]
|
||||
use crate::mir::builder::control_flow::plan::facts::scan_shapes::{
|
||||
ConditionShape, StepShape,
|
||||
};
|
||||
#[cfg(debug_assertions)]
|
||||
use crate::mir::builder::control_flow::plan::facts::skeleton_facts::{
|
||||
SkeletonFacts, SkeletonKind,
|
||||
};
|
||||
#[cfg(debug_assertions)]
|
||||
use crate::mir::builder::control_flow::plan::normalize::canonicalize_loop_facts;
|
||||
use crate::mir::join_ir::lowering::inline_boundary::JumpArgsLayout;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
Reference in New Issue
Block a user