From 4a3c064b156c6bfe09b239484ce8521fb64e3783 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Thu, 4 Oct 2018 04:52:44 -0400 Subject: [PATCH] ir/value: Add an IsZero() member function to Value's interface By far, one of the most common things to check for is whether or not a value is zero, as it typically allows folding away unnecesary operations (other close contenders that can help with eliding operations are 1 and -1). So instead of requiring a check for an immediate and then actually retrieving the integral value and checking it, we can wrap it within a function to make it more convenient. --- src/frontend/ir/value.cpp | 4 ++++ src/frontend/ir/value.h | 9 +++++++++ src/ir_opt/constant_propagation_pass.cpp | 20 +++++++------------- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/frontend/ir/value.cpp b/src/frontend/ir/value.cpp index a7ef2e65..5c3eb4b5 100644 --- a/src/frontend/ir/value.cpp +++ b/src/frontend/ir/value.cpp @@ -194,4 +194,8 @@ bool Value::HasAllBitsSet() const { } } +bool Value::IsZero() const { + return IsImmediate() && GetImmediateAsU64() == 0; +} + } // namespace Dynarmic::IR diff --git a/src/frontend/ir/value.h b/src/frontend/ir/value.h index 80f5970c..a8496d7b 100644 --- a/src/frontend/ir/value.h +++ b/src/frontend/ir/value.h @@ -82,6 +82,15 @@ public: */ bool HasAllBitsSet() const; + /** + * Whether or not the current value contains a representation of zero. + * + * Note that this function will always return false if the contained + * value is not a a constant value. In other words, if IsImmediate() + * would return false on an instance, then so will this function. + */ + bool IsZero() const; + private: Type type; diff --git a/src/ir_opt/constant_propagation_pass.cpp b/src/ir_opt/constant_propagation_pass.cpp index 4d323bf3..aec32546 100644 --- a/src/ir_opt/constant_propagation_pass.cpp +++ b/src/ir_opt/constant_propagation_pass.cpp @@ -36,7 +36,7 @@ void FoldAND(IR::Inst& inst, bool is_32_bit) { } else { inst.ReplaceUsesWith(IR::Value{result}); } - } else if ((is_lhs_immediate && lhs.GetImmediateAsU64() == 0) || (is_rhs_immediate && rhs.GetImmediateAsU64() == 0)) { + } else if (lhs.IsZero() || rhs.IsZero()) { if (is_32_bit) { inst.ReplaceUsesWith(IR::Value{u32{0}}); } else { @@ -59,10 +59,7 @@ void FoldEOR(IR::Inst& inst, bool is_32_bit) { const auto lhs = inst.GetArg(0); const auto rhs = inst.GetArg(1); - const bool is_lhs_immediate = lhs.IsImmediate(); - const bool is_rhs_immediate = rhs.IsImmediate(); - - if (is_lhs_immediate && is_rhs_immediate) { + if (lhs.IsImmediate() && rhs.IsImmediate()) { const u64 result = lhs.GetImmediateAsU64() ^ rhs.GetImmediateAsU64(); if (is_32_bit) { @@ -70,9 +67,9 @@ void FoldEOR(IR::Inst& inst, bool is_32_bit) { } else { inst.ReplaceUsesWith(IR::Value{result}); } - } else if (is_lhs_immediate && lhs.GetImmediateAsU64() == 0) { + } else if (lhs.IsZero()) { inst.ReplaceUsesWith(rhs); - } else if (is_rhs_immediate && rhs.GetImmediateAsU64() == 0) { + } else if (rhs.IsZero()) { inst.ReplaceUsesWith(lhs); } } @@ -102,10 +99,7 @@ void FoldOR(IR::Inst& inst, bool is_32_bit) { const auto lhs = inst.GetArg(0); const auto rhs = inst.GetArg(1); - const bool is_lhs_immediate = lhs.IsImmediate(); - const bool is_rhs_immediate = rhs.IsImmediate(); - - if (is_lhs_immediate && is_rhs_immediate) { + if (lhs.IsImmediate() && rhs.IsImmediate()) { const u64 result = lhs.GetImmediateAsU64() | rhs.GetImmediateAsU64(); if (is_32_bit) { @@ -113,9 +107,9 @@ void FoldOR(IR::Inst& inst, bool is_32_bit) { } else { inst.ReplaceUsesWith(IR::Value{result}); } - } else if (is_lhs_immediate && lhs.GetImmediateAsU64() == 0) { + } else if (lhs.IsZero()) { inst.ReplaceUsesWith(rhs); - } else if (is_rhs_immediate && rhs.GetImmediateAsU64() == 0) { + } else if (rhs.IsZero()) { inst.ReplaceUsesWith(lhs); } }