diff options
author | Alon Zakai <alonzakai@gmail.com> | 2017-08-03 14:15:48 -0700 |
---|---|---|
committer | Alon Zakai (kripken) <alonzakai@gmail.com> | 2017-08-05 13:39:58 -0700 |
commit | b9ce58696487fb4961070e322879b3d3e0cfc9d3 (patch) | |
tree | 61374d95b9f3c5c37446b9b186f4d4cacc201dac /src/passes/MergeBlocks.cpp | |
parent | ffd9a72d28d36915fb173a6d52fbb6e43f7c15db (diff) | |
download | binaryen-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.cpp | 54 |
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; + } } } } |