simple_gvn: recognize commutative operators (#6135)

* simple_gvn: recognize commutative operators

Normalize instructions with commutative opcodes by sorting the arguments. This
means instructions like `iadd v0, v1` and `iadd v1, v0` will be considered
identical by GVN and deduplicated.

* Remove `UsubSat` and `SsubSat` from `is_commutative`

They are not actually commutative

* Remove `TODO`s

* Move InstructionData normalization into helper fn

* Add normalization of commutative instructions in the epgrah implementation

* Handle reflexive icmp/fcmps in GVN

* Change formatting of `normalize_in_place`

* suggestions from code review
This commit is contained in:
Karl Meakin
2023-04-04 01:25:05 +01:00
committed by GitHub
parent bf1aaba06d
commit c85bf27ff8
12 changed files with 153 additions and 33 deletions

View File

@@ -35,6 +35,14 @@ struct HashKey<'a, 'f: 'a> {
ty: Type,
pos: &'a RefCell<FuncCursor<'f>>,
}
impl<'a, 'f: 'a> HashKey<'a, 'f> {
fn new(mut inst: InstructionData, ty: Type, pos: &'a RefCell<FuncCursor<'f>>) -> Self {
inst.normalize_in_place();
Self { inst, ty, pos }
}
}
impl<'a, 'f: 'a> Hash for HashKey<'a, 'f> {
fn hash<H: Hasher>(&self, state: &mut H) {
let pool = &self.pos.borrow().func.dfg.value_lists;
@@ -113,11 +121,7 @@ pub fn do_simple_gvn(func: &mut Function, domtree: &mut DominatorTree) {
}
let ctrl_typevar = func.dfg.ctrl_typevar(inst);
let key = HashKey {
inst: func.dfg.insts[inst],
ty: ctrl_typevar,
pos: &pos,
};
let key = HashKey::new(func.dfg.insts[inst], ctrl_typevar, &pos);
use crate::scoped_hash_map::Entry::*;
match visible_values.entry(key) {
Occupied(entry) => {