diff options
author | Alon Zakai <azakai@google.com> | 2024-03-22 11:12:49 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-22 11:12:49 -0700 |
commit | 57dc0c975dbb82c96826f29559136c703afce3e2 (patch) | |
tree | d81f52d34b2e090b6185bcb3ca7b62540a2d51f4 /src | |
parent | f5147a14e7a7c447bfbc38d05dff19a5231697c0 (diff) | |
download | binaryen-57dc0c975dbb82c96826f29559136c703afce3e2.tar.gz binaryen-57dc0c975dbb82c96826f29559136c703afce3e2.tar.bz2 binaryen-57dc0c975dbb82c96826f29559136c703afce3e2.zip |
CodeFolding: Fix up old EH when we fold away an If (#6420)
The pass does (among other things) this:
(if
condition
X
X
)
=>
(block
(drop
condition
)
X ;; deduplicated
)
After that the condition is now nested in a block, so we may need EH fixups
if it contains a pop.
Diffstat (limited to 'src')
-rw-r--r-- | src/passes/CodeFolding.cpp | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/src/passes/CodeFolding.cpp b/src/passes/CodeFolding.cpp index 0e57a79a2..5a18937bb 100644 --- a/src/passes/CodeFolding.cpp +++ b/src/passes/CodeFolding.cpp @@ -59,6 +59,7 @@ #include "ir/branch-utils.h" #include "ir/effects.h" +#include "ir/eh-utils.h" #include "ir/find_all.h" #include "ir/label-utils.h" #include "ir/utils.h" @@ -119,7 +120,11 @@ struct CodeFolding : public WalkerPass<ControlFlowWalker<CodeFolding>> { // state + // Set when we optimized and believe another pass is warranted. bool anotherPass; + // Set when we optimized in a manner that requires EH fixups specifically, + // which is generally the case when we wrap things in a block. + bool needEHFixups; // pass state @@ -229,6 +234,7 @@ struct CodeFolding : public WalkerPass<ControlFlowWalker<CodeFolding>> { // we must ensure we present the same type as the if had ret->finalize(curr->type); replaceCurrent(ret); + needEHFixups = true; } else { // if both are blocks, look for a tail we can merge auto* left = curr->ifTrue->dynCast<Block>(); @@ -266,6 +272,7 @@ struct CodeFolding : public WalkerPass<ControlFlowWalker<CodeFolding>> { anotherPass = true; while (anotherPass) { anotherPass = false; + needEHFixups = false; super::doWalkFunction(func); optimizeTerminatingTails(unreachableTails); // optimize returns at the end, so we can benefit from a fallthrough if @@ -279,6 +286,9 @@ struct CodeFolding : public WalkerPass<ControlFlowWalker<CodeFolding>> { returnTails.clear(); unoptimizables.clear(); modifieds.clear(); + if (needEHFixups) { + EHUtils::handleBlockNestedPops(func, *getModule()); + } // if we did any work, types may need to be propagated if (anotherPass) { ReFinalize().walkFunctionInModule(func, getModule()); @@ -488,6 +498,7 @@ private: // ensure the replacement has the same type, so the outside is not surprised block->finalize(oldType); replaceCurrent(block); + needEHFixups = true; } // optimize tails that terminate control flow in this function, so we @@ -745,6 +756,7 @@ private: // ensure the replacement has the same type, so the outside is not surprised outer->finalize(getFunction()->getResults()); getFunction()->body = outer; + needEHFixups = true; return true; } |