diff options
author | Alon Zakai <alonzakai@gmail.com> | 2017-02-17 08:00:23 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-02-17 08:00:23 -0800 |
commit | dafe89619cfae269b8f3e9e01ead6102a9d168ad (patch) | |
tree | af8b4f4e9fbe969934e1751a268549f60ae80b62 /src/ast/properties.h | |
parent | c6ea79d1532face076c2dfeb8eadb58319e4e5fd (diff) | |
parent | 67fd2a8bece9b4ecad4d0bef2d357245492a66bb (diff) | |
download | binaryen-dafe89619cfae269b8f3e9e01ead6102a9d168ad.tar.gz binaryen-dafe89619cfae269b8f3e9e01ead6102a9d168ad.tar.bz2 binaryen-dafe89619cfae269b8f3e9e01ead6102a9d168ad.zip |
Merge pull request #906 from WebAssembly/opts-super-4
Misc opts
Diffstat (limited to 'src/ast/properties.h')
-rw-r--r-- | src/ast/properties.h | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/src/ast/properties.h b/src/ast/properties.h index 9834c73d0..9121deba5 100644 --- a/src/ast/properties.h +++ b/src/ast/properties.h @@ -18,6 +18,7 @@ #define wasm_ast_properties_h #include "wasm.h" +#include "ast/bits.h" namespace wasm { @@ -52,6 +53,82 @@ struct Properties { default: return false; } } + + // 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 (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 nullptr; + } + + // gets the size of the sign-extended value + static Index getSignExtBits(Expression* curr) { + return 32 - curr->cast<Binary>()->right->cast<Const>()->value.geti32(); + } + + // 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 (auto* inner = outer->left->dynCast<Binary>()) { + if (inner->op == ShlInt32) { + if (auto* innerConst = inner->right->dynCast<Const>()) { + if (outerConst->value.leU(innerConst->value).geti32()) { + return inner->left; + } + } + } + } + } + } + } + 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 = curr->cast<Binary>()->left->cast<Binary>()->right->cast<Const>()->value.geti32() - + curr->cast<Binary>()->right->cast<Const>()->value.geti32(); + 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 sign-extended value + static Index getZeroExtBits(Expression* curr) { + return Bits::getMaskedBits(curr->cast<Binary>()->right->cast<Const>()->value.geti32()); + } }; } // wasm |