diff options
-rw-r--r-- | src/passes/MergeBlocks.cpp | 20 | ||||
-rw-r--r-- | test/emcc_hello_world.fromasm | 40 | ||||
-rw-r--r-- | test/emcc_hello_world.fromasm.clamp | 40 | ||||
-rw-r--r-- | test/emcc_hello_world.fromasm.imprecise | 40 | ||||
-rw-r--r-- | test/passes/1.txt | 4 | ||||
-rw-r--r-- | test/passes/merge-blocks.txt | 4 | ||||
-rw-r--r-- | test/passes/merge-blocks_remove-unused-brs.txt | 17 | ||||
-rw-r--r-- | test/passes/merge-blocks_remove-unused-brs.wast | 14 | ||||
-rw-r--r-- | test/passes/remove-unused-names_merge-blocks.txt | 26 |
9 files changed, 127 insertions, 78 deletions
diff --git a/src/passes/MergeBlocks.cpp b/src/passes/MergeBlocks.cpp index 50610afed..accb16395 100644 --- a/src/passes/MergeBlocks.cpp +++ b/src/passes/MergeBlocks.cpp @@ -189,9 +189,10 @@ static bool hasDeadCode(Block* block) { // core block optimizer routine static void optimizeBlock(Block* curr, Module* module, PassOptions& passOptions) { + auto& list = curr->list; + // Main merging loop. bool more = true; bool changed = false; - auto& list = curr->list; while (more) { more = false; for (size_t i = 0; i < list.size(); i++) { @@ -334,6 +335,23 @@ struct MergeBlocks : public WalkerPass<PostWalker<MergeBlocks>> { Pass* create() override { return new MergeBlocks; } void visitBlock(Block *curr) { + // If the block has a single child which is a loop, and the block is named, + // then it is the exit for the loop. It's better to move it into the loop, + // where it can be better optimized by other passes. + if (curr->name.is() && curr->list.size() == 1) { + if (auto* loop = curr->list[0]->dynCast<Loop>()) { + curr->list[0] = loop->body; + loop->body = curr; + auto oldOuterType = curr->type; + curr->finalize(curr->type); + loop->finalize(); + // After the flip, the outer type must be the same + assert(loop->type == oldOuterType); + replaceCurrent(loop); + // Fall through to optimize the block, which has a new child now. + } + } + // Otherwise, do the main merging optimizations. optimizeBlock(curr, getModule(), getPassOptions()); } diff --git a/test/emcc_hello_world.fromasm b/test/emcc_hello_world.fromasm index f730a33e7..c243b2c8e 100644 --- a/test/emcc_hello_world.fromasm +++ b/test/emcc_hello_world.fromasm @@ -269,32 +269,32 @@ (local $2 i32) (block $__rjto$1 (block $__rjti$1 - (block $__rjti$0 - (loop $while-in - (br_if $__rjti$0 - (i32.eq - (i32.load8_u offset=687 - (get_local $1) - ) - (get_local $0) + (loop $while-in + (if + (i32.ne + (i32.load8_u offset=687 + (get_local $1) ) + (get_local $0) ) - (br_if $while-in - (i32.ne - (tee_local $1 - (i32.add - (get_local $1) - (i32.const 1) + (block + (br_if $while-in + (i32.ne + (tee_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) ) + (i32.const 87) ) + ) + (set_local $1 (i32.const 87) ) + (br $__rjti$1) ) ) - (set_local $1 - (i32.const 87) - ) - (br $__rjti$1) ) (br_if $__rjti$1 (get_local $1) @@ -780,8 +780,8 @@ ) (block $__rjto$1 (block $__rjti$1 - (block $__rjti$0 - (loop $while-in + (loop $while-in + (block $__rjti$0 (if (i32.load (i32.const 16) diff --git a/test/emcc_hello_world.fromasm.clamp b/test/emcc_hello_world.fromasm.clamp index c9ca55f67..5ee4c0133 100644 --- a/test/emcc_hello_world.fromasm.clamp +++ b/test/emcc_hello_world.fromasm.clamp @@ -267,32 +267,32 @@ (local $2 i32) (block $__rjto$1 (block $__rjti$1 - (block $__rjti$0 - (loop $while-in - (br_if $__rjti$0 - (i32.eq - (i32.load8_u offset=687 - (get_local $1) - ) - (get_local $0) + (loop $while-in + (if + (i32.ne + (i32.load8_u offset=687 + (get_local $1) ) + (get_local $0) ) - (br_if $while-in - (i32.ne - (tee_local $1 - (i32.add - (get_local $1) - (i32.const 1) + (block + (br_if $while-in + (i32.ne + (tee_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) ) + (i32.const 87) ) + ) + (set_local $1 (i32.const 87) ) + (br $__rjti$1) ) ) - (set_local $1 - (i32.const 87) - ) - (br $__rjti$1) ) (br_if $__rjti$1 (get_local $1) @@ -778,8 +778,8 @@ ) (block $__rjto$1 (block $__rjti$1 - (block $__rjti$0 - (loop $while-in + (loop $while-in + (block $__rjti$0 (if (i32.load (i32.const 16) diff --git a/test/emcc_hello_world.fromasm.imprecise b/test/emcc_hello_world.fromasm.imprecise index 50bd5f37a..70aea54a9 100644 --- a/test/emcc_hello_world.fromasm.imprecise +++ b/test/emcc_hello_world.fromasm.imprecise @@ -266,32 +266,32 @@ (local $2 i32) (block $__rjto$1 (block $__rjti$1 - (block $__rjti$0 - (loop $while-in - (br_if $__rjti$0 - (i32.eq - (i32.load8_u offset=687 - (get_local $1) - ) - (get_local $0) + (loop $while-in + (if + (i32.ne + (i32.load8_u offset=687 + (get_local $1) ) + (get_local $0) ) - (br_if $while-in - (i32.ne - (tee_local $1 - (i32.add - (get_local $1) - (i32.const 1) + (block + (br_if $while-in + (i32.ne + (tee_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) ) + (i32.const 87) ) + ) + (set_local $1 (i32.const 87) ) + (br $__rjti$1) ) ) - (set_local $1 - (i32.const 87) - ) - (br $__rjti$1) ) (br_if $__rjti$1 (get_local $1) @@ -772,8 +772,8 @@ ) (block $__rjto$1 (block $__rjti$1 - (block $__rjti$0 - (loop $while-in + (loop $while-in + (block $__rjti$0 (if (i32.load (i32.const 16) diff --git a/test/passes/1.txt b/test/passes/1.txt index 72d0c87b8..22b7032fe 100644 --- a/test/passes/1.txt +++ b/test/passes/1.txt @@ -45,8 +45,8 @@ (get_local $0) ) ) - (block $block$11$break - (loop $shape$9$continue + (loop $shape$9$continue + (block $block$11$break (call $trivial) (br_if $block$11$break (i32.eqz diff --git a/test/passes/merge-blocks.txt b/test/passes/merge-blocks.txt index 8a74ed895..908339b37 100644 --- a/test/passes/merge-blocks.txt +++ b/test/passes/merge-blocks.txt @@ -90,8 +90,8 @@ (drop (block $label$0 (result i32) (drop - (block $label$1 - (loop $label$2 + (loop $label$2 + (block $label$1 (br $label$2) ) ) diff --git a/test/passes/merge-blocks_remove-unused-brs.txt b/test/passes/merge-blocks_remove-unused-brs.txt new file mode 100644 index 000000000..62be8f17c --- /dev/null +++ b/test/passes/merge-blocks_remove-unused-brs.txt @@ -0,0 +1,17 @@ +(module + (type $0 (func (param i32))) + (func $func (; 0 ;) (type $0) (param $x i32) + (loop $loop + (block $out + (if + (get_local $x) + (nop) + (block + (nop) + (br $loop) + ) + ) + ) + ) + ) +) diff --git a/test/passes/merge-blocks_remove-unused-brs.wast b/test/passes/merge-blocks_remove-unused-brs.wast new file mode 100644 index 000000000..5c9f59963 --- /dev/null +++ b/test/passes/merge-blocks_remove-unused-brs.wast @@ -0,0 +1,14 @@ +(module + (func $func (param $x i32) + (block $out + (loop $loop + (br_if $out + (get_local $x) + ) + (nop) + (br $loop) + ) + ) + ) +) + diff --git a/test/passes/remove-unused-names_merge-blocks.txt b/test/passes/remove-unused-names_merge-blocks.txt index 5cc6ca891..69a83d725 100644 --- a/test/passes/remove-unused-names_merge-blocks.txt +++ b/test/passes/remove-unused-names_merge-blocks.txt @@ -1095,30 +1095,30 @@ (drop (i32.const 3) ) - (block $b1 - (loop $l3 + (loop $l3 + (block $b1 (br_if $b1 (i32.const 4) ) (br_if $l3 (i32.const 5) ) - ) - (drop - (i32.const 6) + (drop + (i32.const 6) + ) ) ) - (block $b2 - (loop $l4 + (loop $l4 + (block $b2 (br_if $l4 (i32.const 7) ) - ) - (br_if $b2 - (i32.const 8) - ) - (drop - (i32.const 9) + (br_if $b2 + (i32.const 8) + ) + (drop + (i32.const 9) + ) ) ) (loop $l5 |