summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2018-11-28 16:44:26 -0800
committerGitHub <noreply@github.com>2018-11-28 16:44:26 -0800
commit2de7b22f2b245ab2cf4efffab500a88511972bd8 (patch)
tree2c4821efb77147282ebbd975572b40231654b46c /src
parent5d92d866d8326b1908328485cccd2f8ebe57ac75 (diff)
downloadbinaryen-2de7b22f2b245ab2cf4efffab500a88511972bd8.tar.gz
binaryen-2de7b22f2b245ab2cf4efffab500a88511972bd8.tar.bz2
binaryen-2de7b22f2b245ab2cf4efffab500a88511972bd8.zip
Start to implement #1764 (#1776)
This adds a first instance of the rules discussed in #1764 , specifically, x == y || x > y => x >= y
Diffstat (limited to 'src')
-rw-r--r--src/passes/OptimizeInstructions.cpp34
1 files changed, 34 insertions, 0 deletions
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp
index e0c7217a5..1dd05dd0a 100644
--- a/src/passes/OptimizeInstructions.cpp
+++ b/src/passes/OptimizeInstructions.cpp
@@ -516,6 +516,12 @@ struct OptimizeInstructions : public WalkerPass<PostWalker<OptimizeInstructions,
return ret;
}
}
+ // for or, we can potentially combine
+ if (binary->op == OrInt32) {
+ if (auto* ret = combineOr(binary)) {
+ return ret;
+ }
+ }
// relation/comparisons allow for math optimizations
if (binary->isRelational()) {
if (auto* ret = optimizeRelational(binary)) {
@@ -979,6 +985,34 @@ private:
}
}
+ // We can combine `or` operations, e.g.
+ // (x > y) | (x == y) ==> x >= y
+ Expression* combineOr(Binary* binary) {
+ assert(binary->op == OrInt32);
+ if (auto* left = binary->left->dynCast<Binary>()) {
+ if (auto* right = binary->right->dynCast<Binary>()) {
+ if (left->op != right->op &&
+ ExpressionAnalyzer::equal(left->left, right->left) &&
+ ExpressionAnalyzer::equal(left->right, right->right) &&
+ !EffectAnalyzer(getPassOptions(), left->left).hasSideEffects() &&
+ !EffectAnalyzer(getPassOptions(), left->right).hasSideEffects()) {
+ switch (left->op) {
+ // (x > y) | (x == y) ==> x >= y
+ case EqInt32: {
+ if (right->op == GtSInt32) {
+ left->op = GeSInt32;
+ return left;
+ }
+ break;
+ }
+ default: {}
+ }
+ }
+ }
+ }
+ return nullptr;
+ }
+
// fold constant factors into the offset
void optimizeMemoryAccess(Expression*& ptr, Address& offset) {
// ptr may be a const, but it isn't worth folding that in (we still have a const); in fact,