Add PartialEq to BoundKind and Value
Implement PartialEq for BoundKind to allow for structural equality checks during optimization. This enables the optimizer to terminate early when a node no longer changes. Also, implement PartialEq for Value to facilitate comparisons between different Value variants.
This commit is contained in:
@@ -114,6 +114,62 @@ pub enum BoundKind<T = ()> {
|
||||
Extension(Box<dyn BoundExtension<T>>),
|
||||
}
|
||||
|
||||
impl<T> PartialEq for BoundKind<T>
|
||||
where T: PartialEq {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
match (self, other) {
|
||||
(BoundKind::Nop, BoundKind::Nop) => true,
|
||||
(BoundKind::Constant(a), BoundKind::Constant(b)) => a == b,
|
||||
(BoundKind::Parameter { name: na, slot: sa }, BoundKind::Parameter { name: nb, slot: sb }) => {
|
||||
na == nb && sa == sb
|
||||
}
|
||||
(BoundKind::Get { addr: aa, name: na }, BoundKind::Get { addr: ab, name: nb }) => {
|
||||
aa == ab && na == nb
|
||||
}
|
||||
(BoundKind::Set { addr: aa, value: va }, BoundKind::Set { addr: ab, value: vb }) => {
|
||||
aa == ab && va == vb
|
||||
}
|
||||
(BoundKind::DefLocal { name: na, slot: sa, value: va, captured_by: ca },
|
||||
BoundKind::DefLocal { name: nb, slot: sb, value: vb, captured_by: cb }) => {
|
||||
na == nb && sa == sb && va == vb && ca == cb
|
||||
}
|
||||
(BoundKind::If { cond: ca, then_br: ta, else_br: ea },
|
||||
BoundKind::If { cond: cb, then_br: tb, else_br: eb }) => {
|
||||
ca == cb && ta == tb && ea == eb
|
||||
}
|
||||
(BoundKind::DefGlobal { name: na, global_index: ga, value: va },
|
||||
BoundKind::DefGlobal { name: nb, global_index: gb, value: vb }) => {
|
||||
na == nb && ga == gb && va == vb
|
||||
}
|
||||
(BoundKind::Lambda { params: pa, upvalues: ua, body: ba, positional_count: pca },
|
||||
BoundKind::Lambda { params: pb, upvalues: ub, body: bb, positional_count: pcb }) => {
|
||||
pa == pb && ua == ub && ba == bb && pca == pcb
|
||||
}
|
||||
(BoundKind::Call { callee: ca, args: aa }, BoundKind::Call { callee: cb, args: ab }) => {
|
||||
ca == cb && aa == ab
|
||||
}
|
||||
(BoundKind::TailCall { callee: ca, args: aa }, BoundKind::TailCall { callee: cb, args: ab }) => {
|
||||
ca == cb && aa == ab
|
||||
}
|
||||
(BoundKind::Block { exprs: ea }, BoundKind::Block { exprs: eb }) => {
|
||||
ea == eb
|
||||
}
|
||||
(BoundKind::Tuple { elements: ea }, BoundKind::Tuple { elements: eb }) => {
|
||||
ea == eb
|
||||
}
|
||||
(BoundKind::Record { fields: fa }, BoundKind::Record { fields: fb }) => {
|
||||
fa == fb
|
||||
}
|
||||
(BoundKind::Expansion { original_call: oa, bound_expanded: ba },
|
||||
BoundKind::Expansion { original_call: ob, bound_expanded: bb }) => {
|
||||
Rc::ptr_eq(oa, ob) && ba == bb
|
||||
}
|
||||
(BoundKind::Extension(_), BoundKind::Extension(_)) => false, // Currently no equality for extensions
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A single field in a Record literal (Key-Value pair)
|
||||
pub type RecordField<T> = (BoundNode<T>, BoundNode<T>);
|
||||
|
||||
|
||||
@@ -24,7 +24,9 @@ impl Optimizer {
|
||||
let mut current = node;
|
||||
for _ in 0..self.max_passes {
|
||||
let next = self.visit_node(current.clone());
|
||||
// TODO: Structural equality check to stop early
|
||||
if next == current {
|
||||
break;
|
||||
}
|
||||
current = next;
|
||||
}
|
||||
current
|
||||
|
||||
Reference in New Issue
Block a user