diff options
Diffstat (limited to 'src/ir/properties.h')
-rw-r--r-- | src/ir/properties.h | 193 |
1 files changed, 103 insertions, 90 deletions
diff --git a/src/ir/properties.h b/src/ir/properties.h index cf481218c..7cbbe73f0 100644 --- a/src/ir/properties.h +++ b/src/ir/properties.h @@ -22,51 +22,62 @@ namespace wasm { -struct Properties { - static bool emitsBoolean(Expression* curr) { - if (auto* unary = curr->dynCast<Unary>()) { - return unary->isRelational(); - } else if (auto* binary = curr->dynCast<Binary>()) { - return binary->isRelational(); - } - return false; - } +namespace Properties { - static bool isSymmetric(Binary* binary) { - switch (binary->op) { - case AddInt32: - case MulInt32: - case AndInt32: - case OrInt32: - case XorInt32: - case EqInt32: - case NeInt32: - - case AddInt64: - case MulInt64: - case AndInt64: - case OrInt64: - case XorInt64: - case EqInt64: - case NeInt64: return true; - - default: return false; - } +inline bool emitsBoolean(Expression* curr) { + if (auto* unary = curr->dynCast<Unary>()) { + return unary->isRelational(); + } else if (auto* binary = curr->dynCast<Binary>()) { + return binary->isRelational(); } - - // Check if an expression is a sign-extend, and if so, returns the value - // that is extended, otherwise nullptr - static 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; - } + return false; +} + +inline bool isSymmetric(Binary* binary) { + switch (binary->op) { + case AddInt32: + case MulInt32: + case AndInt32: + case OrInt32: + case XorInt32: + case EqInt32: + case NeInt32: + + case AddInt64: + case MulInt64: + case AndInt64: + case OrInt64: + case XorInt64: + case EqInt64: + case NeInt64: return true; + + default: return false; + } +} + +// Check if an expression is a control flow construct with a name, +// which implies it may have breaks to it. +inline bool isNamedControlFlow(Expression* curr) { + if (auto* block = curr->dynCast<Block>()) { + return block->name.is(); + } else if (auto* loop = curr->dynCast<Loop>()) { + return loop->name.is(); + } + return false; +} + +// 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; } } } @@ -74,28 +85,28 @@ struct Properties { } } } - return nullptr; - } - - // gets the size of the sign-extended value - static Index getSignExtBits(Expression* curr) { - return 32 - Bits::getEffectiveShifts(curr->cast<Binary>()->right); } - - // 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) - static 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; - } + return nullptr; +} + +// gets the size of the sign-extended value +inline Index getSignExtBits(Expression* curr) { + return 32 - Bits::getEffectiveShifts(curr->cast<Binary>()->right); +} + +// 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; } } } @@ -103,39 +114,41 @@ struct Properties { } } } - return nullptr; - } - - // gets the size of the almost sign-extended value, as well as the - // extra shifts, if any - static Index getAlmostSignExtBits(Expression* curr, Index& extraShifts) { - extraShifts = Bits::getEffectiveShifts(curr->cast<Binary>()->left->cast<Binary>()->right) - - Bits::getEffectiveShifts(curr->cast<Binary>()->right); - return getSignExtBits(curr); } - - // Check if an expression is a zero-extend, and if so, returns the value - // that is extended, otherwise nullptr - static 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; - } + 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); + 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; } } } - return nullptr; } + return nullptr; +} - // gets the size of the sign-extended value - static Index getZeroExtBits(Expression* curr) { - return Bits::getMaskedBits(curr->cast<Binary>()->right->cast<Const>()->value.geti32()); - } -}; +// gets the size of the sign-extended value +inline Index getZeroExtBits(Expression* curr) { + return Bits::getMaskedBits(curr->cast<Binary>()->right->cast<Const>()->value.geti32()); +} + +} // Properties } // wasm -#endif // wams_ir_properties_h +#endif // wasm_ir_properties_h |