diff options
author | Alon Zakai <azakai@google.com> | 2024-10-03 09:06:46 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-10-03 09:06:46 -0700 |
commit | 36181c881c67f2b11386fdf885dbe33567db0d67 (patch) | |
tree | d72adfff75bfcd4c74371eb54a488a5e22bcf9db /src/passes/MergeBlocks.cpp | |
parent | ce1a13c06aca0690b296f34401011b5a0bc07636 (diff) | |
download | binaryen-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.cpp | 76 |
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>())) { |