diff options
author | Alon Zakai <alonzakai@gmail.com> | 2017-10-16 12:40:04 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-10-16 12:40:04 -0700 |
commit | 73c04954fa52addb709d7de3f2364ec3082c408b (patch) | |
tree | 2adc4cc5d5909bd2d18763f327e7ef2d0359060d | |
parent | faaa20b4950351528fd00888040fdd2b14a5a084 (diff) | |
download | binaryen-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.h | 12 | ||||
-rw-r--r-- | src/passes/RemoveUnusedBrs.cpp | 6 | ||||
-rw-r--r-- | test/passes/remove-unused-brs.txt | 43 | ||||
-rw-r--r-- | test/passes/remove-unused-brs.wast | 19 |
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) + ) + ) + ) ) |