summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/passes/MergeBlocks.cpp20
-rw-r--r--test/emcc_hello_world.fromasm40
-rw-r--r--test/emcc_hello_world.fromasm.clamp40
-rw-r--r--test/emcc_hello_world.fromasm.imprecise40
-rw-r--r--test/passes/1.txt4
-rw-r--r--test/passes/merge-blocks.txt4
-rw-r--r--test/passes/merge-blocks_remove-unused-brs.txt17
-rw-r--r--test/passes/merge-blocks_remove-unused-brs.wast14
-rw-r--r--test/passes/remove-unused-names_merge-blocks.txt26
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