diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ir/properties.h | 86 |
1 files changed, 38 insertions, 48 deletions
diff --git a/src/ir/properties.h b/src/ir/properties.h index 7ec1701d6..1331eeb73 100644 --- a/src/ir/properties.h +++ b/src/ir/properties.h @@ -19,6 +19,7 @@ #include "ir/bits.h" #include "ir/effects.h" +#include "ir/match.h" #include "wasm.h" namespace wasm { @@ -131,84 +132,73 @@ inline Literals getLiterals(const Expression* curr) { // Check if an expression is a sign-extend, and if so, returns the value // that is extended, otherwise nullptr inline Expression* getSignExtValue(Expression* curr) { - if (auto* outer = curr->dynCast<Binary>()) { - if (outer->op == ShrSInt32) { - if (auto* outerConst = outer->right->dynCast<Const>()) { - if (outerConst->value.geti32() != 0) { - if (auto* inner = outer->left->dynCast<Binary>()) { - if (inner->op == ShlInt32) { - if (auto* innerConst = inner->right->dynCast<Const>()) { - if (outerConst->value == innerConst->value) { - return inner->left; - } - } - } - } - } - } - } + using namespace Match; + int32_t leftShift = 0, rightShift = 0; + Expression* extended = nullptr; + if (matches(curr, + binary(ShrSInt32, + binary(ShlInt32, any(&extended), i32(&leftShift)), + i32(&rightShift))) && + leftShift == rightShift && leftShift != 0) { + return extended; } return nullptr; } // gets the size of the sign-extended value inline Index getSignExtBits(Expression* curr) { - return 32 - Bits::getEffectiveShifts(curr->cast<Binary>()->right); + assert(curr->type == Type::i32); + auto* rightShift = curr->cast<Binary>()->right; + return 32 - Bits::getEffectiveShifts(rightShift); } // Check if an expression is almost a sign-extend: perhaps the inner shift // is too large. We can split the shifts in that case, which is sometimes // useful (e.g. if we can remove the signext) inline Expression* getAlmostSignExt(Expression* curr) { - if (auto* outer = curr->dynCast<Binary>()) { - if (outer->op == ShrSInt32) { - if (auto* outerConst = outer->right->dynCast<Const>()) { - if (outerConst->value.geti32() != 0) { - if (auto* inner = outer->left->dynCast<Binary>()) { - if (inner->op == ShlInt32) { - if (auto* innerConst = inner->right->dynCast<Const>()) { - if (Bits::getEffectiveShifts(outerConst) <= - Bits::getEffectiveShifts(innerConst)) { - return inner->left; - } - } - } - } - } - } - } + using namespace Match; + int32_t leftShift = 0, rightShift = 0; + Expression* extended = nullptr; + if (matches(curr, + binary(ShrSInt32, + binary(ShlInt32, any(&extended), i32(&leftShift)), + i32(&rightShift))) && + Bits::getEffectiveShifts(rightShift, Type::i32) <= + Bits::getEffectiveShifts(leftShift, Type::i32) && + rightShift != 0) { + return extended; } return nullptr; } // gets the size of the almost sign-extended value, as well as the // extra shifts, if any -inline Index getAlmostSignExtBits(Expression* curr, Index& extraShifts) { - extraShifts = Bits::getEffectiveShifts( - curr->cast<Binary>()->left->cast<Binary>()->right) - - Bits::getEffectiveShifts(curr->cast<Binary>()->right); +inline Index getAlmostSignExtBits(Expression* curr, Index& extraLeftShifts) { + auto* leftShift = curr->cast<Binary>()->left->cast<Binary>()->right; + auto* rightShift = curr->cast<Binary>()->right; + extraLeftShifts = + Bits::getEffectiveShifts(leftShift) - Bits::getEffectiveShifts(rightShift); return getSignExtBits(curr); } // Check if an expression is a zero-extend, and if so, returns the value // that is extended, otherwise nullptr inline Expression* getZeroExtValue(Expression* curr) { - if (auto* binary = curr->dynCast<Binary>()) { - if (binary->op == AndInt32) { - if (auto* c = binary->right->dynCast<Const>()) { - if (Bits::getMaskedBits(c->value.geti32())) { - return binary->right; - } - } - } + using namespace Match; + int32_t mask = 0; + Expression* extended = nullptr; + if (matches(curr, binary(AndInt32, any(&extended), i32(&mask))) && + Bits::getMaskedBits(mask) != 0) { + return extended; } return nullptr; } // gets the size of the sign-extended value inline Index getZeroExtBits(Expression* curr) { - return Bits::getMaskedBits( - curr->cast<Binary>()->right->cast<Const>()->value.geti32()); + assert(curr->type == Type::i32); + int32_t mask = curr->cast<Binary>()->right->cast<Const>()->value.geti32(); + return Bits::getMaskedBits(mask); } // Returns a falling-through value, that is, it looks through a local.tee |