summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2016-06-11 17:31:12 -0700
committerAlon Zakai <alonzakai@gmail.com>2016-06-11 17:31:12 -0700
commita3c339c259d0dafc87fac565fac308e9699726f9 (patch)
treeb41f8ceaacaf162a67fa374d5c884612ade90293
parent59542c98459771905ef25c5fe48079f3353d6869 (diff)
downloadbinaryen-a3c339c259d0dafc87fac565fac308e9699726f9.tar.gz
binaryen-a3c339c259d0dafc87fac565fac308e9699726f9.tar.bz2
binaryen-a3c339c259d0dafc87fac565fac308e9699726f9.zip
fix br_if with value optimization in remove-unused-brs
-rw-r--r--src/passes/RemoveUnusedBrs.cpp7
-rw-r--r--test/passes/remove-unused-brs.txt41
-rw-r--r--test/passes/remove-unused-brs.wast39
-rw-r--r--test/unit.asm.js12
-rw-r--r--test/unit.fromasm13
-rw-r--r--test/unit.fromasm.imprecise13
-rw-r--r--test/unit.fromasm.imprecise.no-opts24
-rw-r--r--test/unit.fromasm.no-opts24
8 files changed, 173 insertions, 0 deletions
diff --git a/src/passes/RemoveUnusedBrs.cpp b/src/passes/RemoveUnusedBrs.cpp
index ffdba0768..3f909c32e 100644
--- a/src/passes/RemoveUnusedBrs.cpp
+++ b/src/passes/RemoveUnusedBrs.cpp
@@ -128,6 +128,13 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs, Visitor<R
// if without an else. try to reduce if (condition) br => br_if (condition)
Break* br = curr->ifTrue->dynCast<Break>();
if (br && !br->condition) { // TODO: if there is a condition, join them
+ // if the br has a value, then if => br_if means we always execute the value, and also the order is value,condition vs condition,value
+ if (br->value) {
+ EffectAnalyzer value(br->value);
+ if (value.hasSideEffects()) return;
+ EffectAnalyzer condition(curr->condition);
+ if (condition.invalidates(value)) return;
+ }
br->condition = curr->condition;
replaceCurrent(br);
anotherCycle = true;
diff --git a/test/passes/remove-unused-brs.txt b/test/passes/remove-unused-brs.txt
index a8e7f29be..c3ac71057 100644
--- a/test/passes/remove-unused-brs.txt
+++ b/test/passes/remove-unused-brs.txt
@@ -281,4 +281,45 @@
)
)
)
+ (func $side-effects-and-order (result i32)
+ (local $x i32)
+ (block $do-once$0
+ (br_if $do-once$0
+ (i32.const 0)
+ (call $b13)
+ )
+ (i32.const 1)
+ )
+ (block $do-once$0
+ (if
+ (call $b13)
+ (br $do-once$0
+ (call $b14)
+ )
+ )
+ (i32.const 1)
+ )
+ (block $do-once$0
+ (if
+ (i32.const 0)
+ (br $do-once$0
+ (call $b14)
+ )
+ )
+ (i32.const 1)
+ )
+ (block $do-once$0
+ (if
+ (set_local $x
+ (i32.const 1)
+ )
+ (br $do-once$0
+ (set_local $x
+ (i32.const 2)
+ )
+ )
+ )
+ (i32.const 1)
+ )
+ )
)
diff --git a/test/passes/remove-unused-brs.wast b/test/passes/remove-unused-brs.wast
index 8b9d42bc1..b7dc1cc25 100644
--- a/test/passes/remove-unused-brs.wast
+++ b/test/passes/remove-unused-brs.wast
@@ -297,5 +297,44 @@
)
)
)
+ (func $side-effects-and-order (result i32)
+ (local $x i32)
+ (block $do-once$0
+ (if
+ (call $b13)
+ (br $do-once$0
+ (i32.const 0)
+ )
+ )
+ (i32.const 1)
+ )
+ (block $do-once$0
+ (if
+ (call $b13)
+ (br $do-once$0
+ (call $b14)
+ )
+ )
+ (i32.const 1)
+ )
+ (block $do-once$0
+ (if
+ (i32.const 0)
+ (br $do-once$0
+ (call $b14)
+ )
+ )
+ (i32.const 1)
+ )
+ (block $do-once$0
+ (if
+ (set_local $x (i32.const 1))
+ (br $do-once$0
+ (set_local $x (i32.const 2))
+ )
+ )
+ (i32.const 1)
+ )
+ )
)
diff --git a/test/unit.asm.js b/test/unit.asm.js
index 2f307e085..b0e4e7594 100644
--- a/test/unit.asm.js
+++ b/test/unit.asm.js
@@ -247,6 +247,18 @@ function asm(global, env, buffer) {
}
}
+ function phi() {
+ var x = 0;
+ do {
+ if (lb(1) | 0) {
+ x = 0;
+ break;
+ }
+ x = 1;
+ } while (0);
+ return x | 0;
+ }
+
function z() {
}
function w() {
diff --git a/test/unit.fromasm b/test/unit.fromasm
index 3fb76981d..54b790edf 100644
--- a/test/unit.fromasm
+++ b/test/unit.fromasm
@@ -453,4 +453,17 @@
)
)
)
+ (func $phi (result i32)
+ (block $do-once$0
+ (if
+ (call $lb
+ (i32.const 1)
+ )
+ (br $do-once$0
+ (i32.const 0)
+ )
+ )
+ (i32.const 1)
+ )
+ )
)
diff --git a/test/unit.fromasm.imprecise b/test/unit.fromasm.imprecise
index a4716941d..b7b25e9b8 100644
--- a/test/unit.fromasm.imprecise
+++ b/test/unit.fromasm.imprecise
@@ -445,4 +445,17 @@
)
)
)
+ (func $phi (result i32)
+ (block $do-once$0
+ (if
+ (call $lb
+ (i32.const 1)
+ )
+ (br $do-once$0
+ (i32.const 0)
+ )
+ )
+ (i32.const 1)
+ )
+ )
)
diff --git a/test/unit.fromasm.imprecise.no-opts b/test/unit.fromasm.imprecise.no-opts
index c3da01359..9f49824f3 100644
--- a/test/unit.fromasm.imprecise.no-opts
+++ b/test/unit.fromasm.imprecise.no-opts
@@ -721,6 +721,30 @@
)
)
)
+ (func $phi (result i32)
+ (local $x i32)
+ (block $do-once$0
+ (block
+ (if
+ (call $lb
+ (i32.const 1)
+ )
+ (block
+ (set_local $x
+ (i32.const 0)
+ )
+ (br $do-once$0)
+ )
+ )
+ (set_local $x
+ (i32.const 1)
+ )
+ )
+ )
+ (return
+ (get_local $x)
+ )
+ )
(func $z
(nop)
)
diff --git a/test/unit.fromasm.no-opts b/test/unit.fromasm.no-opts
index 92d2d2add..ccf89c5b6 100644
--- a/test/unit.fromasm.no-opts
+++ b/test/unit.fromasm.no-opts
@@ -725,6 +725,30 @@
)
)
)
+ (func $phi (result i32)
+ (local $x i32)
+ (block $do-once$0
+ (block
+ (if
+ (call $lb
+ (i32.const 1)
+ )
+ (block
+ (set_local $x
+ (i32.const 0)
+ )
+ (br $do-once$0)
+ )
+ )
+ (set_local $x
+ (i32.const 1)
+ )
+ )
+ )
+ (return
+ (get_local $x)
+ )
+ )
(func $z
(nop)
)