summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2016-09-10 16:05:04 -0700
committerAlon Zakai <alonzakai@gmail.com>2016-09-10 16:05:16 -0700
commit3d6b218cc288bb1c9f234cb9a54796f512294107 (patch)
tree3d1c5883c4b47f026616f11525dd973310127754 /src
parent7c0edee0dec829f6c739533aa4c4631978ff4632 (diff)
downloadbinaryen-3d6b218cc288bb1c9f234cb9a54796f512294107.tar.gz
binaryen-3d6b218cc288bb1c9f234cb9a54796f512294107.tar.bz2
binaryen-3d6b218cc288bb1c9f234cb9a54796f512294107.zip
refactor an optimizeBoolean method
Diffstat (limited to 'src')
-rw-r--r--src/passes/OptimizeInstructions.cpp44
-rw-r--r--src/passes/OptimizeInstructions.wast15
-rw-r--r--src/passes/OptimizeInstructions.wast.processed15
3 files changed, 24 insertions, 50 deletions
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp
index ec646d89f..8381a0e1f 100644
--- a/src/passes/OptimizeInstructions.cpp
+++ b/src/passes/OptimizeInstructions.cpp
@@ -214,37 +214,41 @@ struct OptimizeInstructions : public WalkerPass<PostWalker<OptimizeInstructions,
if (get && get->name == set->name) {
ExpressionManipulator::nop(curr);
}
+ } else if (auto* iff = curr->dynCast<If>()) {
+ iff->condition = optimizeBoolean(iff->condition);
} else if (auto* select = curr->dynCast<Select>()) {
+ select->condition = optimizeBoolean(select->condition);
auto* condition = select->condition->dynCast<Unary>();
if (condition && condition->op == EqZInt32) {
- auto* condition2 = condition->value->dynCast<Unary>();
- if (condition2 && condition2->op == EqZInt32) {
- // double eqz
- select->condition = condition2->value;
- } else {
- // flip select, eqz input and flippable
- EffectAnalyzer ifTrue(select->ifTrue);
- EffectAnalyzer ifFalse(select->ifFalse);
- if (!ifTrue.invalidates(ifFalse)) {
- select->condition = condition->value;
- std::swap(select->ifTrue, select->ifFalse);
- }
+ // flip select to remove eqz, if we can reorder
+ EffectAnalyzer ifTrue(select->ifTrue);
+ EffectAnalyzer ifFalse(select->ifFalse);
+ if (!ifTrue.invalidates(ifFalse)) {
+ select->condition = condition->value;
+ std::swap(select->ifTrue, select->ifFalse);
}
}
} else if (auto* br = curr->dynCast<Break>()) {
if (br->condition) {
- auto* condition = br->condition->dynCast<Unary>();
- if (condition && condition->op == EqZInt32) {
- auto* condition2 = condition->value->dynCast<Unary>();
- if (condition2 && condition2->op == EqZInt32) {
- // double eqz
- br->condition = condition2->value;
- }
- }
+ br->condition = optimizeBoolean(br->condition);
}
}
return nullptr;
}
+
+private:
+
+ Expression* optimizeBoolean(Expression* boolean) {
+ auto* condition = boolean->dynCast<Unary>();
+ if (condition && condition->op == EqZInt32) {
+ auto* condition2 = condition->value->dynCast<Unary>();
+ if (condition2 && condition2->op == EqZInt32) {
+ // double eqz
+ return condition2->value;
+ }
+ }
+ return boolean;
+ }
};
Pass *createOptimizeInstructionsPass() {
diff --git a/src/passes/OptimizeInstructions.wast b/src/passes/OptimizeInstructions.wast
index d5f8148ec..48a4e2c9d 100644
--- a/src/passes/OptimizeInstructions.wast
+++ b/src/passes/OptimizeInstructions.wast
@@ -34,21 +34,6 @@
(call_import $any.expr (i32.const 1))
)
)
- ;; eqz^2 is eliminatable if the output is boolean (note that for if-else, the above rule handles it in two operations)
- (block
- (if
- (i32.eqz
- (i32.eqz
- (call_import $i32.expr (i32.const 0))
- )
- )
- (call_import $any.expr (i32.const 1))
- )
- (if
- (call_import $i32.expr (i32.const 0))
- (call_import $any.expr (i32.const 1))
- )
- )
;; equal 0 => eqz
(block
(i32.eq
diff --git a/src/passes/OptimizeInstructions.wast.processed b/src/passes/OptimizeInstructions.wast.processed
index 78e5e7476..13ccc8241 100644
--- a/src/passes/OptimizeInstructions.wast.processed
+++ b/src/passes/OptimizeInstructions.wast.processed
@@ -34,21 +34,6 @@
"(call_import $any.expr (i32.const 1))\n"
")\n"
")\n"
-";; eqz^2 is eliminatable if the output is boolean (note that for if-else, the above rule handles it in two operations)\n"
-"(block\n"
-"(if\n"
-"(i32.eqz\n"
-"(i32.eqz\n"
-"(call_import $i32.expr (i32.const 0))\n"
-")\n"
-")\n"
-"(call_import $any.expr (i32.const 1))\n"
-")\n"
-"(if\n"
-"(call_import $i32.expr (i32.const 0))\n"
-"(call_import $any.expr (i32.const 1))\n"
-")\n"
-")\n"
";; equal 0 => eqz\n"
"(block\n"
"(i32.eq\n"