constant_propagation_pass: deduplicate common 32/64 bit checking for results in folding functions
It's common for an folding operation to apply to both the 32-bit and 64-bit variant of the same opcode, which leads to checking which kind of result we need to store the value as. This moves it to its own function, so that we don't need to duplicate it in various functions.
This commit is contained in:
parent
72daf37208
commit
7ad6981437
1 changed files with 21 additions and 42 deletions
|
@ -13,6 +13,16 @@
|
||||||
namespace Dynarmic::Optimization {
|
namespace Dynarmic::Optimization {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
// Tiny helper to avoid the need to store based off the opcode
|
||||||
|
// bit size all over the place within folding functions.
|
||||||
|
void ReplaceUsesWith(IR::Inst& inst, bool is_32_bit, u64 value) {
|
||||||
|
if (is_32_bit) {
|
||||||
|
inst.ReplaceUsesWith(IR::Value{static_cast<u32>(value)});
|
||||||
|
} else {
|
||||||
|
inst.ReplaceUsesWith(IR::Value{value});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Folds AND operations based on the following:
|
// Folds AND operations based on the following:
|
||||||
//
|
//
|
||||||
// 1. imm_x & imm_y -> result
|
// 1. imm_x & imm_y -> result
|
||||||
|
@ -30,18 +40,9 @@ void FoldAND(IR::Inst& inst, bool is_32_bit) {
|
||||||
|
|
||||||
if (is_lhs_immediate && is_rhs_immediate) {
|
if (is_lhs_immediate && is_rhs_immediate) {
|
||||||
const u64 result = lhs.GetImmediateAsU64() & rhs.GetImmediateAsU64();
|
const u64 result = lhs.GetImmediateAsU64() & rhs.GetImmediateAsU64();
|
||||||
|
ReplaceUsesWith(inst, is_32_bit, result);
|
||||||
if (is_32_bit) {
|
|
||||||
inst.ReplaceUsesWith(IR::Value{static_cast<u32>(result)});
|
|
||||||
} else {
|
|
||||||
inst.ReplaceUsesWith(IR::Value{result});
|
|
||||||
}
|
|
||||||
} else if (lhs.IsZero() || rhs.IsZero()) {
|
} else if (lhs.IsZero() || rhs.IsZero()) {
|
||||||
if (is_32_bit) {
|
ReplaceUsesWith(inst, is_32_bit, 0);
|
||||||
inst.ReplaceUsesWith(IR::Value{u32{0}});
|
|
||||||
} else {
|
|
||||||
inst.ReplaceUsesWith(IR::Value{u64{0}});
|
|
||||||
}
|
|
||||||
} else if (is_lhs_immediate && lhs.HasAllBitsSet()) {
|
} else if (is_lhs_immediate && lhs.HasAllBitsSet()) {
|
||||||
inst.ReplaceUsesWith(rhs);
|
inst.ReplaceUsesWith(rhs);
|
||||||
} else if (is_rhs_immediate && rhs.HasAllBitsSet()) {
|
} else if (is_rhs_immediate && rhs.HasAllBitsSet()) {
|
||||||
|
@ -61,12 +62,7 @@ void FoldEOR(IR::Inst& inst, bool is_32_bit) {
|
||||||
|
|
||||||
if (lhs.IsImmediate() && rhs.IsImmediate()) {
|
if (lhs.IsImmediate() && rhs.IsImmediate()) {
|
||||||
const u64 result = lhs.GetImmediateAsU64() ^ rhs.GetImmediateAsU64();
|
const u64 result = lhs.GetImmediateAsU64() ^ rhs.GetImmediateAsU64();
|
||||||
|
ReplaceUsesWith(inst, is_32_bit, result);
|
||||||
if (is_32_bit) {
|
|
||||||
inst.ReplaceUsesWith(IR::Value{static_cast<u32>(result)});
|
|
||||||
} else {
|
|
||||||
inst.ReplaceUsesWith(IR::Value{result});
|
|
||||||
}
|
|
||||||
} else if (lhs.IsZero()) {
|
} else if (lhs.IsZero()) {
|
||||||
inst.ReplaceUsesWith(rhs);
|
inst.ReplaceUsesWith(rhs);
|
||||||
} else if (rhs.IsZero()) {
|
} else if (rhs.IsZero()) {
|
||||||
|
@ -88,18 +84,9 @@ void FoldMultiply(IR::Inst& inst, bool is_32_bit) {
|
||||||
|
|
||||||
if (lhs.IsImmediate() && rhs.IsImmediate()) {
|
if (lhs.IsImmediate() && rhs.IsImmediate()) {
|
||||||
const u64 result = lhs.GetImmediateAsU64() * rhs.GetImmediateAsU64();
|
const u64 result = lhs.GetImmediateAsU64() * rhs.GetImmediateAsU64();
|
||||||
|
ReplaceUsesWith(inst, is_32_bit, result);
|
||||||
if (is_32_bit) {
|
|
||||||
inst.ReplaceUsesWith(IR::Value{static_cast<u32>(result)});
|
|
||||||
} else {
|
|
||||||
inst.ReplaceUsesWith(IR::Value{result});
|
|
||||||
}
|
|
||||||
} else if (lhs.IsZero() || rhs.IsZero()) {
|
} else if (lhs.IsZero() || rhs.IsZero()) {
|
||||||
if (is_32_bit) {
|
ReplaceUsesWith(inst, is_32_bit, 0);
|
||||||
inst.ReplaceUsesWith(IR::Value{u32{0}});
|
|
||||||
} else {
|
|
||||||
inst.ReplaceUsesWith(IR::Value{u64{0}});
|
|
||||||
}
|
|
||||||
} else if (lhs.IsUnsignedImmediate(1)) {
|
} else if (lhs.IsUnsignedImmediate(1)) {
|
||||||
inst.ReplaceUsesWith(rhs);
|
inst.ReplaceUsesWith(rhs);
|
||||||
} else if (rhs.IsUnsignedImmediate(1)) {
|
} else if (rhs.IsUnsignedImmediate(1)) {
|
||||||
|
@ -111,15 +98,12 @@ void FoldMultiply(IR::Inst& inst, bool is_32_bit) {
|
||||||
void FoldNOT(IR::Inst& inst, bool is_32_bit) {
|
void FoldNOT(IR::Inst& inst, bool is_32_bit) {
|
||||||
const auto operand = inst.GetArg(0);
|
const auto operand = inst.GetArg(0);
|
||||||
|
|
||||||
if (operand.IsImmediate()) {
|
if (!operand.IsImmediate()) {
|
||||||
const u64 result = ~operand.GetImmediateAsU64();
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (is_32_bit) {
|
const u64 result = ~operand.GetImmediateAsU64();
|
||||||
inst.ReplaceUsesWith(IR::Value{static_cast<u32>(result)});
|
ReplaceUsesWith(inst, is_32_bit, result);
|
||||||
} else {
|
|
||||||
inst.ReplaceUsesWith(IR::Value{result});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Folds OR operations based on the following:
|
// Folds OR operations based on the following:
|
||||||
|
@ -134,12 +118,7 @@ void FoldOR(IR::Inst& inst, bool is_32_bit) {
|
||||||
|
|
||||||
if (lhs.IsImmediate() && rhs.IsImmediate()) {
|
if (lhs.IsImmediate() && rhs.IsImmediate()) {
|
||||||
const u64 result = lhs.GetImmediateAsU64() | rhs.GetImmediateAsU64();
|
const u64 result = lhs.GetImmediateAsU64() | rhs.GetImmediateAsU64();
|
||||||
|
ReplaceUsesWith(inst, is_32_bit, result);
|
||||||
if (is_32_bit) {
|
|
||||||
inst.ReplaceUsesWith(IR::Value{static_cast<u32>(result)});
|
|
||||||
} else {
|
|
||||||
inst.ReplaceUsesWith(IR::Value{result});
|
|
||||||
}
|
|
||||||
} else if (lhs.IsZero()) {
|
} else if (lhs.IsZero()) {
|
||||||
inst.ReplaceUsesWith(rhs);
|
inst.ReplaceUsesWith(rhs);
|
||||||
} else if (rhs.IsZero()) {
|
} else if (rhs.IsZero()) {
|
||||||
|
|
Loading…
Reference in a new issue