summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2016-09-10 14:24:11 -0700
committerAlon Zakai <alonzakai@gmail.com>2016-09-10 14:25:04 -0700
commit1c6a1375140c7b2ef720e706d7d97efe7140cdcc (patch)
treee1f6941d03ed1cd074743a071006d22f7a048ad4
parent91b33ce4d692c221336f2d6d4345eb239ead401e (diff)
downloadbinaryen-1c6a1375140c7b2ef720e706d7d97efe7140cdcc.tar.gz
binaryen-1c6a1375140c7b2ef720e706d7d97efe7140cdcc.tar.bz2
binaryen-1c6a1375140c7b2ef720e706d7d97efe7140cdcc.zip
optimize eqz^2 in select and br_if
-rw-r--r--src/passes/OptimizeInstructions.cpp31
-rw-r--r--test/emcc_hello_world.fromasm30
-rw-r--r--test/emcc_hello_world.fromasm.imprecise30
-rw-r--r--test/passes/optimize-instructions.txt7
-rw-r--r--test/passes/optimize-instructions.wast11
5 files changed, 59 insertions, 50 deletions
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp
index cd0610634..ec646d89f 100644
--- a/src/passes/OptimizeInstructions.cpp
+++ b/src/passes/OptimizeInstructions.cpp
@@ -215,20 +215,35 @@ struct OptimizeInstructions : public WalkerPass<PostWalker<OptimizeInstructions,
ExpressionManipulator::nop(curr);
}
} else if (auto* select = curr->dynCast<Select>()) {
- // flip select if eqz input and flippable
auto* condition = select->condition->dynCast<Unary>();
if (condition && condition->op == EqZInt32) {
- EffectAnalyzer ifTrue(select->ifTrue);
- EffectAnalyzer ifFalse(select->ifFalse);
- if (!ifTrue.invalidates(ifFalse)) {
- select->condition = condition->value;
- std::swap(select->ifTrue, select->ifFalse);
+ 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);
+ }
+ }
+ }
+ } 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;
+ }
}
}
}
return nullptr;
- // TODO:
- // * eqz^2 can be removed if flowing into a boolean context (we handle if, but need also br_if and select)
}
};
diff --git a/test/emcc_hello_world.fromasm b/test/emcc_hello_world.fromasm
index fb1163576..06b48ffd6 100644
--- a/test/emcc_hello_world.fromasm
+++ b/test/emcc_hello_world.fromasm
@@ -6601,15 +6601,11 @@
(get_local $41)
(block
(br_if $do-once$114
- (i32.eqz
- (i32.eqz
- (i32.and
- (i32.load
- (get_local $0)
- )
- (i32.const 32)
- )
+ (i32.and
+ (i32.load
+ (get_local $0)
)
+ (i32.const 32)
)
)
(drop
@@ -6955,15 +6951,11 @@
(i32.const 0)
)
(br_if $do-once$106
- (i32.eqz
- (i32.eqz
- (i32.and
- (i32.load
- (get_local $0)
- )
- (i32.const 32)
- )
+ (i32.and
+ (i32.load
+ (get_local $0)
)
+ (i32.const 32)
)
)
(drop
@@ -12923,11 +12915,7 @@
(get_local $16)
)
(br_if $do-once$63
- (i32.eqz
- (i32.eqz
- (get_local $16)
- )
- )
+ (get_local $16)
)
(i32.store
(i32.const 180)
diff --git a/test/emcc_hello_world.fromasm.imprecise b/test/emcc_hello_world.fromasm.imprecise
index 149c837ec..e83f2b757 100644
--- a/test/emcc_hello_world.fromasm.imprecise
+++ b/test/emcc_hello_world.fromasm.imprecise
@@ -6594,15 +6594,11 @@
(get_local $41)
(block
(br_if $do-once$114
- (i32.eqz
- (i32.eqz
- (i32.and
- (i32.load
- (get_local $0)
- )
- (i32.const 32)
- )
+ (i32.and
+ (i32.load
+ (get_local $0)
)
+ (i32.const 32)
)
)
(drop
@@ -6948,15 +6944,11 @@
(i32.const 0)
)
(br_if $do-once$106
- (i32.eqz
- (i32.eqz
- (i32.and
- (i32.load
- (get_local $0)
- )
- (i32.const 32)
- )
+ (i32.and
+ (i32.load
+ (get_local $0)
)
+ (i32.const 32)
)
)
(drop
@@ -12916,11 +12908,7 @@
(get_local $16)
)
(br_if $do-once$63
- (i32.eqz
- (i32.eqz
- (get_local $16)
- )
- )
+ (get_local $16)
)
(i32.store
(i32.const 180)
diff --git a/test/passes/optimize-instructions.txt b/test/passes/optimize-instructions.txt
index 6d83cbdbc..ca5f02849 100644
--- a/test/passes/optimize-instructions.txt
+++ b/test/passes/optimize-instructions.txt
@@ -205,5 +205,12 @@
)
)
)
+ (drop
+ (select
+ (i32.const 0)
+ (i32.const 1)
+ (i32.const 2)
+ )
+ )
)
)
diff --git a/test/passes/optimize-instructions.wast b/test/passes/optimize-instructions.wast
index 08868e23a..b1a7ab47e 100644
--- a/test/passes/optimize-instructions.wast
+++ b/test/passes/optimize-instructions.wast
@@ -240,5 +240,16 @@
)
)
)
+ (drop
+ (select
+ (i32.const 0)
+ (i32.const 1)
+ (i32.eqz
+ (i32.eqz
+ (i32.const 2)
+ )
+ )
+ )
+ )
)
)