summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2017-10-16 12:40:04 -0700
committerGitHub <noreply@github.com>2017-10-16 12:40:04 -0700
commit73c04954fa52addb709d7de3f2364ec3082c408b (patch)
tree2adc4cc5d5909bd2d18763f327e7ef2d0359060d
parentfaaa20b4950351528fd00888040fdd2b14a5a084 (diff)
downloadbinaryen-73c04954fa52addb709d7de3f2364ec3082c408b.tar.gz
binaryen-73c04954fa52addb709d7de3f2364ec3082c408b.tar.bz2
binaryen-73c04954fa52addb709d7de3f2364ec3082c408b.zip
Use the type system to check if something is flowed out of (#1224)
now that the type system has a proper unreachable, we don't need obviouslyDoesNotFlowOut
-rw-r--r--src/ast_utils.h12
-rw-r--r--src/passes/RemoveUnusedBrs.cpp6
-rw-r--r--test/passes/remove-unused-brs.txt43
-rw-r--r--test/passes/remove-unused-brs.wast19
4 files changed, 53 insertions, 27 deletions
diff --git a/src/ast_utils.h b/src/ast_utils.h
index dfa233f26..6e5251860 100644
--- a/src/ast_utils.h
+++ b/src/ast_utils.h
@@ -55,18 +55,6 @@ struct ExpressionAnalyzer {
return !curr->condition && !curr->value;
}
- // Checks if an expression does not flow out in an obvious way.
- // We return true if it cannot flow out. If it can flow out, we
- // might still return true, as the analysis here is simple and fast.
- static bool obviouslyDoesNotFlowOut(Expression* curr) {
- if (auto* br = curr->dynCast<Break>()) {
- if (!br->condition) return true;
- } else if (auto* block = curr->dynCast<Block>()) {
- if (block->list.size() > 0 && obviouslyDoesNotFlowOut(block->list.back()) && !BranchUtils::BranchSeeker::hasReachable(block, block->name)) return true;
- }
- return false;
- }
-
using ExprComparer = std::function<bool(Expression*, Expression*)>;
static bool flexibleEqual(Expression* left, Expression* right, ExprComparer comparer);
diff --git a/src/passes/RemoveUnusedBrs.cpp b/src/passes/RemoveUnusedBrs.cpp
index 7903534b6..d2cdec7ad 100644
--- a/src/passes/RemoveUnusedBrs.cpp
+++ b/src/passes/RemoveUnusedBrs.cpp
@@ -250,7 +250,7 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
// let's try to move the code going to the top of the loop into the if-else
if (!iff->ifFalse) {
// we need the ifTrue to break, so it cannot reach the code we want to move
- if (ExpressionAnalyzer::obviouslyDoesNotFlowOut(iff->ifTrue)) {
+ if (iff->ifTrue->type == unreachable) {
iff->ifFalse = builder.stealSlice(block, i + 1, list.size());
iff->finalize();
block->finalize();
@@ -288,12 +288,12 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
return block;
};
- if (ExpressionAnalyzer::obviouslyDoesNotFlowOut(iff->ifTrue)) {
+ if (iff->ifTrue->type == unreachable) {
iff->ifFalse = blockifyMerge(iff->ifFalse, builder.stealSlice(block, i + 1, list.size()));
iff->finalize();
block->finalize();
return true;
- } else if (ExpressionAnalyzer::obviouslyDoesNotFlowOut(iff->ifFalse)) {
+ } else if (iff->ifFalse->type == unreachable) {
iff->ifTrue = blockifyMerge(iff->ifTrue, builder.stealSlice(block, i + 1, list.size()));
iff->finalize();
block->finalize();
diff --git a/test/passes/remove-unused-brs.txt b/test/passes/remove-unused-brs.txt
index 39a4d89f3..607b8ecb4 100644
--- a/test/passes/remove-unused-brs.txt
+++ b/test/passes/remove-unused-brs.txt
@@ -8,6 +8,7 @@
(type $6 (func (param i32) (result i64)))
(type $7 (func (result i64)))
(type $8 (func (result f32)))
+ (type $9 (func (param i32) (result f32)))
(memory $0 256 256)
(func $b0-yes (type $0) (param $i1 i32)
(block $topmost
@@ -483,11 +484,12 @@
)
(loop $in45
(block $out46
- (if
- (i32.const 0)
- (unreachable)
+ (br_if $in45
+ (i32.eqz
+ (i32.const 0)
+ )
)
- (br $in45)
+ (unreachable)
)
)
(loop $in48
@@ -1123,18 +1125,35 @@
)
(func $unreachable-return-loop-value (type $7) (result i64)
(loop $loop
- (br_if $loop
- (i32.eqz
- (i32.const 1)
+ (if
+ (i32.const 1)
+ (block $block
+ (br_if $block
+ (br $loop)
+ )
+ (br $loop)
)
)
- (block $block
- (br_if $block
- (br $loop)
+ (br $loop)
+ )
+ )
+ (func $obviously-flows-out-maybe (type $9) (param $var$0 i32) (result f32)
+ (block $label$1 (result f32)
+ (br $label$1
+ (f32.const 1)
+ )
+ (loop $label$5
+ (if
+ (i32.const 11)
+ (block $label$8
+ (br_if $label$8
+ (unreachable)
+ )
+ (br $label$5)
+ )
)
- (br $loop)
+ (br $label$5)
)
)
- (unreachable)
)
)
diff --git a/test/passes/remove-unused-brs.wast b/test/passes/remove-unused-brs.wast
index 14b4abc4c..731a9f88f 100644
--- a/test/passes/remove-unused-brs.wast
+++ b/test/passes/remove-unused-brs.wast
@@ -1020,5 +1020,24 @@
(br $loop) ;; we 100% go back to the loop top, the loop is never exited. but opts move code around so that is not obvious anymore, and the loop becomes a nop, but the func has a return value
)
)
+ (func $obviously-flows-out-maybe (param $var$0 i32) (result f32)
+ (block $label$1 (result f32)
+ (br $label$1
+ (f32.const 1)
+ )
+ (loop $label$5
+ (if
+ (i32.const 11)
+ (block $label$8 ;; this block is none - it has a break, even if not taken - and so looks like it might flow out,
+ (br_if $label$8 ;; and so we can't move it outside to be the end of the loop's block
+ (unreachable)
+ )
+ (br $label$5)
+ )
+ )
+ (br $label$5)
+ )
+ )
+ )
)