summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2017-08-06 11:19:03 -0700
committerAlon Zakai <alonzakai@gmail.com>2017-08-06 11:24:52 -0700
commit323e0b489a2b26d144da440d8043189ebbf49db2 (patch)
tree033b9ed11eaa48e614badfbc452ca2626cd8a613
parent7231e619004414c33b30f4a3dd55ff85c69e1406 (diff)
downloadbinaryen-323e0b489a2b26d144da440d8043189ebbf49db2.tar.gz
binaryen-323e0b489a2b26d144da440d8043189ebbf49db2.tar.bz2
binaryen-323e0b489a2b26d144da440d8043189ebbf49db2.zip
handle merging blocks with items after an unreachable, that if merged would be invalid. stop on the unreachable, it is easier and better
-rw-r--r--src/passes/MergeBlocks.cpp15
-rw-r--r--test/passes/remove-unused-names_merge-blocks.txt5
-rw-r--r--test/passes/remove-unused-names_merge-blocks.wast14
3 files changed, 25 insertions, 9 deletions
diff --git a/src/passes/MergeBlocks.cpp b/src/passes/MergeBlocks.cpp
index 3627a5b0e..1ef34117e 100644
--- a/src/passes/MergeBlocks.cpp
+++ b/src/passes/MergeBlocks.cpp
@@ -214,21 +214,18 @@ static void optimizeBlock(Block* curr, Module* module, PassOptions& passOptions)
}
if (!child) continue;
if (child->name.is()) continue; // named blocks can have breaks to them (and certainly do, if we ran RemoveUnusedNames and RemoveUnusedBrs)
- if (child->type == unreachable) {
- // an unreachable block can have a concrete final element (which is never reached)
- if (!child->list.empty()) {
- if (isConcreteWasmType(child->list.back()->type)) {
- // just remove it
- child->list.pop_back();
- }
- }
- }
ExpressionList merged(module->allocator);
for (size_t j = 0; j < i; j++) {
merged.push_back(curr->list[j]);
}
for (auto item : child->list) {
merged.push_back(item);
+ if (item->type == unreachable) {
+ // we don't need anything else from the child,
+ // and it is always valid to end on an unreachable,
+ // so stop there (otherwise, we need to be careful)
+ break;
+ }
}
for (size_t j = i + 1; j < curr->list.size(); j++) {
merged.push_back(curr->list[j]);
diff --git a/test/passes/remove-unused-names_merge-blocks.txt b/test/passes/remove-unused-names_merge-blocks.txt
index ff0d8b912..81386b10a 100644
--- a/test/passes/remove-unused-names_merge-blocks.txt
+++ b/test/passes/remove-unused-names_merge-blocks.txt
@@ -906,4 +906,9 @@
)
)
)
+ (func $merging-with-unreachable-in-middle (type $4) (result i32)
+ (return
+ (i32.const 21536)
+ )
+ )
)
diff --git a/test/passes/remove-unused-names_merge-blocks.wast b/test/passes/remove-unused-names_merge-blocks.wast
index 2911203d1..bf1dc1fda 100644
--- a/test/passes/remove-unused-names_merge-blocks.wast
+++ b/test/passes/remove-unused-names_merge-blocks.wast
@@ -1068,4 +1068,18 @@
)
)
)
+ (func $merging-with-unreachable-in-middle (result i32)
+ (block $label$1 (result i32)
+ (block
+ (return
+ (i32.const 21536)
+ )
+ (block $label$15
+ (br $label$15)
+ )
+ (i32.const 19299)
+ )
+ )
+ )
)
+