diff options
author | Alon Zakai <alonzakai@gmail.com> | 2017-10-24 20:36:28 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-10-24 20:36:28 -0700 |
commit | 47c9021401a69d407a3e730012824cae75dd66f9 (patch) | |
tree | f03c6077a08f5eb404f31ca415c121415f35934c /src/ir/properties.h | |
parent | 93f5f167d7674e87f634eca1f5980baee4de5053 (diff) | |
download | binaryen-47c9021401a69d407a3e730012824cae75dd66f9.tar.gz binaryen-47c9021401a69d407a3e730012824cae75dd66f9.tar.bz2 binaryen-47c9021401a69d407a3e730012824cae75dd66f9.zip |
notation change: AST => IR (#1245)
The IR is indeed a tree, but not an "abstract syntax tree" since there is no language for which it is the syntax (except in the most trivial and meaningless sense).
Diffstat (limited to 'src/ir/properties.h')
-rw-r--r-- | src/ir/properties.h | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/src/ir/properties.h b/src/ir/properties.h new file mode 100644 index 000000000..cf481218c --- /dev/null +++ b/src/ir/properties.h @@ -0,0 +1,141 @@ +/* + * Copyright 2016 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef wasm_ir_properties_h +#define wasm_ir_properties_h + +#include "wasm.h" +#include "ir/bits.h" + +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; + } + + 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; + } + } + + // 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 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 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 sign-extended value + static Index getZeroExtBits(Expression* curr) { + return Bits::getMaskedBits(curr->cast<Binary>()->right->cast<Const>()->value.geti32()); + } +}; + +} // wasm + +#endif // wams_ir_properties_h + |