constant_propagation_pass: Fold Mul32 and Mul64 cases where applicable
Multiplication operations can currently be folded if: 1. Both arguments are known constant values 2. Either operand is zero (in which case the result is also zero) 3. Either operand is one (in which case the result is the non-one operand).
This commit is contained in:
parent
546cfbc0ee
commit
72daf37208
1 changed files with 37 additions and 0 deletions
|
@ -74,6 +74,39 @@ void FoldEOR(IR::Inst& inst, bool is_32_bit) {
|
|||
}
|
||||
}
|
||||
|
||||
// Folds multiplication operations based on the following:
|
||||
//
|
||||
// 1. imm_x * imm_y -> result
|
||||
// 2. x * 0 -> 0
|
||||
// 3. 0 * y -> 0
|
||||
// 4. x * 1 -> x
|
||||
// 5. 1 * y -> y
|
||||
//
|
||||
void FoldMultiply(IR::Inst& inst, bool is_32_bit) {
|
||||
const auto lhs = inst.GetArg(0);
|
||||
const auto rhs = inst.GetArg(1);
|
||||
|
||||
if (lhs.IsImmediate() && rhs.IsImmediate()) {
|
||||
const u64 result = lhs.GetImmediateAsU64() * rhs.GetImmediateAsU64();
|
||||
|
||||
if (is_32_bit) {
|
||||
inst.ReplaceUsesWith(IR::Value{static_cast<u32>(result)});
|
||||
} else {
|
||||
inst.ReplaceUsesWith(IR::Value{result});
|
||||
}
|
||||
} else if (lhs.IsZero() || rhs.IsZero()) {
|
||||
if (is_32_bit) {
|
||||
inst.ReplaceUsesWith(IR::Value{u32{0}});
|
||||
} else {
|
||||
inst.ReplaceUsesWith(IR::Value{u64{0}});
|
||||
}
|
||||
} else if (lhs.IsUnsignedImmediate(1)) {
|
||||
inst.ReplaceUsesWith(rhs);
|
||||
} else if (rhs.IsUnsignedImmediate(1)) {
|
||||
inst.ReplaceUsesWith(lhs);
|
||||
}
|
||||
}
|
||||
|
||||
// Folds NOT operations if the contained value is an immediate.
|
||||
void FoldNOT(IR::Inst& inst, bool is_32_bit) {
|
||||
const auto operand = inst.GetArg(0);
|
||||
|
@ -174,6 +207,10 @@ void ConstantPropagation(IR::Block& block) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
case IR::Opcode::Mul32:
|
||||
case IR::Opcode::Mul64:
|
||||
FoldMultiply(inst, opcode == IR::Opcode::Mul32);
|
||||
break;
|
||||
case IR::Opcode::And32:
|
||||
case IR::Opcode::And64:
|
||||
FoldAND(inst, opcode == IR::Opcode::And32);
|
||||
|
|
Loading…
Reference in a new issue