summaryrefslogtreecommitdiff
path: root/src/passes/MergeBlocks.cpp
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2024-10-03 09:06:46 -0700
committerGitHub <noreply@github.com>2024-10-03 09:06:46 -0700
commit36181c881c67f2b11386fdf885dbe33567db0d67 (patch)
treed72adfff75bfcd4c74371eb54a488a5e22bcf9db /src/passes/MergeBlocks.cpp
parentce1a13c06aca0690b296f34401011b5a0bc07636 (diff)
downloadbinaryen-36181c881c67f2b11386fdf885dbe33567db0d67.tar.gz
binaryen-36181c881c67f2b11386fdf885dbe33567db0d67.tar.bz2
binaryen-36181c881c67f2b11386fdf885dbe33567db0d67.zip
[NFC] Refactor out the dropped-block optimization code in MergeBlocks (#6982)
This just moves the code out into a function. A later PR will use it in another place. Add a test that shows the motivation for that later PR: we fail to optimize away a block return value at the top level of a function. Fixing that will involve calling the new function here from another place.
Diffstat (limited to 'src/passes/MergeBlocks.cpp')
-rw-r--r--src/passes/MergeBlocks.cpp76
1 files changed, 46 insertions, 30 deletions
diff --git a/src/passes/MergeBlocks.cpp b/src/passes/MergeBlocks.cpp
index 9a0b5d27b..401d2e629 100644
--- a/src/passes/MergeBlocks.cpp
+++ b/src/passes/MergeBlocks.cpp
@@ -197,7 +197,46 @@ static bool hasDeadCode(Block* block) {
return false;
}
-// core block optimizer routine
+// Given a dropped block, see if we can simplify it by optimizing the drop into
+// the block, removing the return value while doin so. Returns whether we
+// succeeded.
+static bool optimizeDroppedBlock(Drop* drop,
+ Block* block,
+ Module& wasm,
+ PassOptions& options,
+ BranchUtils::BranchSeekerCache& branchInfo) {
+ assert(drop->value == block);
+ if (block->name.is()) {
+ // There may be breaks: see if we can remove their values.
+ Expression* expression = block;
+ ProblemFinder finder(options);
+ finder.setModule(&wasm);
+ finder.origin = block->name;
+ finder.walk(expression);
+ if (finder.found()) {
+ // We found a problem that blocks us.
+ return false;
+ }
+
+ // Success. Fix up breaks before continuing to handle the drop itself.
+ BreakValueDropper fixer(options, branchInfo);
+ fixer.origin = block->name;
+ fixer.setModule(&wasm);
+ fixer.walk(expression);
+ }
+
+ // Optimize by removing the block. Reuse the drop, if we still need it.
+ auto* last = block->list.back();
+ if (last->type.isConcrete()) {
+ drop->value = last;
+ drop->finalize();
+ block->list.back() = drop;
+ }
+ block->finalize();
+ return true;
+}
+
+// Core block optimizer routine.
static void optimizeBlock(Block* curr,
Module* module,
PassOptions& passOptions,
@@ -218,8 +257,8 @@ static void optimizeBlock(Block* curr,
Loop* loop = nullptr;
// To to handle a non-block child.
if (!childBlock) {
- // if we have a child that is (drop (block ..)) then we can move the
- // drop into the block, and remove br values. this allows more merging,
+ // If we have a child that is (drop (block ..)) then we can move the
+ // drop into the block, and remove br values. This allows more merging.
if (auto* drop = list[i]->dynCast<Drop>()) {
childBlock = drop->value->dynCast<Block>();
if (childBlock) {
@@ -228,36 +267,13 @@ static void optimizeBlock(Block* curr,
// dce should have been run anyhow
continue;
}
- if (childBlock->name.is()) {
- Expression* expression = childBlock;
- // check if it's ok to remove the value from all breaks to us
- ProblemFinder finder(passOptions);
- finder.setModule(module);
- finder.origin = childBlock->name;
- finder.walk(expression);
- if (finder.found()) {
- childBlock = nullptr;
- } else {
- // fix up breaks
- BreakValueDropper fixer(passOptions, branchInfo);
- fixer.origin = childBlock->name;
- fixer.setModule(module);
- fixer.walk(expression);
- }
- }
- if (childBlock) {
- // we can do it!
- // reuse the drop, if we still need it
- auto* last = childBlock->list.back();
- if (last->type.isConcrete()) {
- drop->value = last;
- drop->finalize();
- childBlock->list.back() = drop;
- }
- childBlock->finalize();
+ if (optimizeDroppedBlock(
+ drop, childBlock, *module, passOptions, branchInfo)) {
child = list[i] = childBlock;
more = true;
changed = true;
+ } else {
+ childBlock = nullptr;
}
}
} else if ((loop = list[i]->dynCast<Loop>())) {