summaryrefslogtreecommitdiff
path: root/src/passes/MergeBlocks.cpp
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2017-08-03 14:15:48 -0700
committerAlon Zakai (kripken) <alonzakai@gmail.com>2017-08-05 13:39:58 -0700
commitb9ce58696487fb4961070e322879b3d3e0cfc9d3 (patch)
tree61374d95b9f3c5c37446b9b186f4d4cacc201dac /src/passes/MergeBlocks.cpp
parentffd9a72d28d36915fb173a6d52fbb6e43f7c15db (diff)
downloadbinaryen-b9ce58696487fb4961070e322879b3d3e0cfc9d3.tar.gz
binaryen-b9ce58696487fb4961070e322879b3d3e0cfc9d3.tar.bz2
binaryen-b9ce58696487fb4961070e322879b3d3e0cfc9d3.zip
don't move code around a drop-block when the block contains unreachables, which can cause type changes in the outside. dce should be run on that anyhow
Diffstat (limited to 'src/passes/MergeBlocks.cpp')
-rw-r--r--src/passes/MergeBlocks.cpp54
1 files changed, 32 insertions, 22 deletions
diff --git a/src/passes/MergeBlocks.cpp b/src/passes/MergeBlocks.cpp
index 7c086a920..7591aa50a 100644
--- a/src/passes/MergeBlocks.cpp
+++ b/src/passes/MergeBlocks.cpp
@@ -168,32 +168,42 @@ static void optimizeBlock(Block* curr, Module* module, PassOptions& passOptions)
if (drop) {
child = drop->value->dynCast<Block>();
if (child) {
- if (child->name.is()) {
- Expression* expression = child;
- // check if it's ok to remove the value from all breaks to us
- ProblemFinder finder(passOptions);
- finder.origin = child->name;
- finder.walk(expression);
- if (finder.found()) {
+ // if we move around unreachable code, type changes could occur. avoid that, as
+ // anyhow it means we should have run dce before getting here
+ for (auto* test : child->list) {
+ if (test->type == unreachable) {
child = nullptr;
- } else {
- // fix up breaks
- BreakValueDropper fixer(passOptions);
- fixer.origin = child->name;
- fixer.setModule(module);
- fixer.walk(expression);
+ break;
}
}
if (child) {
- // we can do it!
- // reuse the drop
- drop->value = child->list.back();
- drop->finalize();
- child->list.back() = drop;
- child->finalize();
- curr->list[i] = child;
- more = true;
- changed = true;
+ if (child->name.is()) {
+ Expression* expression = child;
+ // check if it's ok to remove the value from all breaks to us
+ ProblemFinder finder(passOptions);
+ finder.origin = child->name;
+ finder.walk(expression);
+ if (finder.found()) {
+ child = nullptr;
+ } else {
+ // fix up breaks
+ BreakValueDropper fixer(passOptions);
+ fixer.origin = child->name;
+ fixer.setModule(module);
+ fixer.walk(expression);
+ }
+ }
+ if (child) {
+ // we can do it!
+ // reuse the drop
+ drop->value = child->list.back();
+ drop->finalize();
+ child->list.back() = drop;
+ child->finalize();
+ curr->list[i] = child;
+ more = true;
+ changed = true;
+ }
}
}
}