mirror of
https://github.com/kmc7468/cs420.git
synced 2025-12-15 15:08:52 +00:00
Fix ir equiv
This commit is contained in:
132
src/ir/equiv.rs
132
src/ir/equiv.rs
@@ -110,13 +110,143 @@ fn is_equiv_block(lhs: &Block, rhs: &Block, map: &HashMap<BlockId, BlockId>) ->
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if lhs.instructions != rhs.instructions {
|
if lhs.instructions.len() != rhs.instructions.len() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (l, r) in izip!(&lhs.instructions, &rhs.instructions) {
|
||||||
|
if !is_equiv_instruction(l, r, map) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
is_equiv_block_exit(&lhs.exit, &rhs.exit, map)
|
is_equiv_block_exit(&lhs.exit, &rhs.exit, map)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_equiv_instruction(
|
||||||
|
lhs: &Instruction,
|
||||||
|
rhs: &Instruction,
|
||||||
|
map: &HashMap<BlockId, BlockId>,
|
||||||
|
) -> bool {
|
||||||
|
match (lhs, rhs) {
|
||||||
|
(Instruction::Nop, Instruction::Nop) => true,
|
||||||
|
(
|
||||||
|
Instruction::BinOp {
|
||||||
|
op,
|
||||||
|
lhs,
|
||||||
|
rhs,
|
||||||
|
dtype,
|
||||||
|
},
|
||||||
|
Instruction::BinOp {
|
||||||
|
op: op_other,
|
||||||
|
lhs: lhs_other,
|
||||||
|
rhs: rhs_other,
|
||||||
|
dtype: dtype_other,
|
||||||
|
},
|
||||||
|
) => {
|
||||||
|
op == op_other
|
||||||
|
&& is_equiv_operand(lhs, lhs_other, map)
|
||||||
|
&& is_equiv_operand(rhs, rhs_other, map)
|
||||||
|
&& dtype == dtype_other
|
||||||
|
}
|
||||||
|
(
|
||||||
|
Instruction::UnaryOp { op, operand, dtype },
|
||||||
|
Instruction::UnaryOp {
|
||||||
|
op: op_other,
|
||||||
|
operand: operand_other,
|
||||||
|
dtype: dtype_other,
|
||||||
|
},
|
||||||
|
) => {
|
||||||
|
op == op_other && is_equiv_operand(operand, operand_other, map) && dtype == dtype_other
|
||||||
|
}
|
||||||
|
(
|
||||||
|
Instruction::Store { ptr, value },
|
||||||
|
Instruction::Store {
|
||||||
|
ptr: ptr_other,
|
||||||
|
value: value_other,
|
||||||
|
},
|
||||||
|
) => is_equiv_operand(ptr, ptr_other, map) && is_equiv_operand(value, value_other, map),
|
||||||
|
(Instruction::Load { ptr }, Instruction::Load { ptr: ptr_other }) => {
|
||||||
|
is_equiv_operand(ptr, ptr_other, map)
|
||||||
|
}
|
||||||
|
(
|
||||||
|
Instruction::Call {
|
||||||
|
callee,
|
||||||
|
args,
|
||||||
|
return_type,
|
||||||
|
},
|
||||||
|
Instruction::Call {
|
||||||
|
callee: callee_other,
|
||||||
|
args: args_other,
|
||||||
|
return_type: return_type_other,
|
||||||
|
},
|
||||||
|
) => {
|
||||||
|
is_equiv_operand(callee, callee_other, map)
|
||||||
|
&& args.len() == args_other.len()
|
||||||
|
&& izip!(args, args_other).all(|(l, r)| is_equiv_operand(l, r, map))
|
||||||
|
&& return_type == return_type_other
|
||||||
|
}
|
||||||
|
(
|
||||||
|
Instruction::TypeCast {
|
||||||
|
value,
|
||||||
|
target_dtype,
|
||||||
|
},
|
||||||
|
Instruction::TypeCast {
|
||||||
|
value: value_other,
|
||||||
|
target_dtype: target_dtype_other,
|
||||||
|
},
|
||||||
|
) => is_equiv_operand(value, value_other, map) && target_dtype == target_dtype_other,
|
||||||
|
(
|
||||||
|
Instruction::GetElementPtr { ptr, offset, dtype },
|
||||||
|
Instruction::GetElementPtr {
|
||||||
|
ptr: ptr_other,
|
||||||
|
offset: offset_other,
|
||||||
|
dtype: dtype_other,
|
||||||
|
},
|
||||||
|
) => {
|
||||||
|
is_equiv_operand(ptr, ptr_other, map)
|
||||||
|
&& is_equiv_operand(offset, offset_other, map)
|
||||||
|
&& dtype == dtype_other
|
||||||
|
}
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_equiv_operand(lhs: &Operand, rhs: &Operand, map: &HashMap<BlockId, BlockId>) -> bool {
|
||||||
|
match (lhs, rhs) {
|
||||||
|
(Operand::Constant(_), Operand::Constant(_)) => lhs == rhs,
|
||||||
|
(
|
||||||
|
Operand::Register { rid, dtype },
|
||||||
|
Operand::Register {
|
||||||
|
rid: rid_other,
|
||||||
|
dtype: dtype_other,
|
||||||
|
},
|
||||||
|
) => is_equiv_rid(rid, rid_other, map) && dtype == dtype_other,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_equiv_rid(lhs: &RegisterId, rhs: &RegisterId, map: &HashMap<BlockId, BlockId>) -> bool {
|
||||||
|
match (lhs, rhs) {
|
||||||
|
(RegisterId::Local { .. }, RegisterId::Local { .. }) => lhs == rhs,
|
||||||
|
(
|
||||||
|
RegisterId::Arg { bid, aid },
|
||||||
|
RegisterId::Arg {
|
||||||
|
bid: bid_other,
|
||||||
|
aid: aid_other,
|
||||||
|
},
|
||||||
|
) => map.get(bid) == Some(bid_other) && aid == aid_other,
|
||||||
|
(
|
||||||
|
RegisterId::Temp { bid, iid },
|
||||||
|
RegisterId::Temp {
|
||||||
|
bid: bid_other,
|
||||||
|
iid: iid_other,
|
||||||
|
},
|
||||||
|
) => map.get(bid) == Some(bid_other) && iid == iid_other,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn is_equiv_block_exit(lhs: &BlockExit, rhs: &BlockExit, map: &HashMap<BlockId, BlockId>) -> bool {
|
fn is_equiv_block_exit(lhs: &BlockExit, rhs: &BlockExit, map: &HashMap<BlockId, BlockId>) -> bool {
|
||||||
match (lhs, rhs) {
|
match (lhs, rhs) {
|
||||||
(BlockExit::Jump { arg }, BlockExit::Jump { arg: arg_other }) => {
|
(BlockExit::Jump { arg }, BlockExit::Jump { arg: arg_other }) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user