summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2017-07-17 10:23:06 -0700
committerAlon Zakai <alonzakai@gmail.com>2017-07-17 10:23:06 -0700
commita2e170294c03d5fe0d91e2797d96acdb95b1d37c (patch)
treec225944366315da75b4864ec7ab1ac218cb8a760 /src
parent7bc2ed70de137aa6615fcd5d0e1f3e88f008a738 (diff)
downloadbinaryen-a2e170294c03d5fe0d91e2797d96acdb95b1d37c.tar.gz
binaryen-a2e170294c03d5fe0d91e2797d96acdb95b1d37c.tar.bz2
binaryen-a2e170294c03d5fe0d91e2797d96acdb95b1d37c.zip
fix blockifyMerge logic - it needs to not skip code in the block we merge to. since that's a fairly specific functionality needed in removeUnusedBrs, move it to there
Diffstat (limited to 'src')
-rw-r--r--src/passes/RemoveUnusedBrs.cpp32
-rw-r--r--src/wasm-builder.h22
2 files changed, 30 insertions, 24 deletions
diff --git a/src/passes/RemoveUnusedBrs.cpp b/src/passes/RemoveUnusedBrs.cpp
index b725de901..3ab0371ed 100644
--- a/src/passes/RemoveUnusedBrs.cpp
+++ b/src/passes/RemoveUnusedBrs.cpp
@@ -232,11 +232,39 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
// this is already an if-else. if one side is a dead end, we can append to the other, if
// there is no returned value to concern us
assert(!isConcreteWasmType(iff->type)); // can't be, since in the middle of a block
+
+ // ensures the first node is a block, if it isn't already, and merges in the second,
+ // either as a single element or, if a block, by appending to the first block. this
+ // keeps the order of operations in place, that is, the appended element will be
+ // executed after the first node's elements
+ auto blockifyMerge = [&](Expression* any, Expression* append) -> Block* {
+ Block* block = nullptr;
+ if (any) block = any->dynCast<Block>();
+ // if the first isn't a block, or it's a block with a name (so we might
+ // branch to the end, and so can't append to it, we might skip that code!)
+ // then make a new block
+ if (!block || block->name.is()) {
+ block = builder.makeBlock(any);
+ } else {
+ assert(!isConcreteWasmType(block->type));
+ }
+ auto* other = append->dynCast<Block>();
+ if (!other) {
+ block->list.push_back(append);
+ } else {
+ for (auto* item : other->list) {
+ block->list.push_back(item);
+ }
+ }
+ block->finalize();
+ return block;
+ };
+
if (ExpressionAnalyzer::obviouslyDoesNotFlowOut(iff->ifTrue)) {
- iff->ifFalse = builder.blockifyMerge(iff->ifFalse, builder.stealSlice(block, i + 1, list.size()));
+ iff->ifFalse = blockifyMerge(iff->ifFalse, builder.stealSlice(block, i + 1, list.size()));
return true;
} else if (ExpressionAnalyzer::obviouslyDoesNotFlowOut(iff->ifFalse)) {
- iff->ifTrue = builder.blockifyMerge(iff->ifTrue, builder.stealSlice(block, i + 1, list.size()));
+ iff->ifTrue = blockifyMerge(iff->ifTrue, builder.stealSlice(block, i + 1, list.size()));
return true;
}
}
diff --git a/src/wasm-builder.h b/src/wasm-builder.h
index 41aaf6766..f702342d2 100644
--- a/src/wasm-builder.h
+++ b/src/wasm-builder.h
@@ -315,28 +315,6 @@ public:
return block;
}
- // ensures the first node is a block, if it isn't already, and merges in the second,
- // either as a single element or, if a block, by appending to the first block
- Block* blockifyMerge(Expression* any, Expression* append) {
- Block* block = nullptr;
- if (any) block = any->dynCast<Block>();
- if (!block) {
- block = makeBlock(any);
- } else {
- assert(!isConcreteWasmType(block->type));
- }
- auto* other = append->dynCast<Block>();
- if (!other) {
- block->list.push_back(append);
- } else {
- for (auto* item : other->list) {
- block->list.push_back(item);
- }
- }
- block->finalize();
- return block;
- }
-
// a helper for the common pattern of a sequence of two expressions. Similar to
// blockify, but does *not* reuse a block if the first is one.
Block* makeSequence(Expression* left, Expression* right) {