diff options
author | Alon Zakai <azakai@google.com> | 2021-03-01 19:33:10 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-01 11:33:10 -0800 |
commit | 575aec37f3fe4793b1d16275426c6369864e1540 (patch) | |
tree | b9d047a7d56fb89c8f63c9ebdef99cd4f5a7886f /src | |
parent | 27a841eec6ceb171caae2a2cbd7c92ecdf8d78eb (diff) | |
download | binaryen-575aec37f3fe4793b1d16275426c6369864e1540.tar.gz binaryen-575aec37f3fe4793b1d16275426c6369864e1540.tar.bz2 binaryen-575aec37f3fe4793b1d16275426c6369864e1540.zip |
[Wasm Exceptions] Fix/work around delegate issues in Inlining pass (#3633)
1. Ignore the fake delegate target in the unique name mapper. The mapper
is run after inlining, so this fixes inlining into a function that has a delegate
to the caller.
2. Do not inline a function with a delegate. We should support this eventually,
but for now I think this is good enough.
After this Inlining should be safe to run on exceptions code.
Diffstat (limited to 'src')
-rw-r--r-- | src/parsing.h | 5 | ||||
-rw-r--r-- | src/passes/Inlining.cpp | 12 |
2 files changed, 17 insertions, 0 deletions
diff --git a/src/parsing.h b/src/parsing.h index 9c3e0cd19..a8ed8b13f 100644 --- a/src/parsing.h +++ b/src/parsing.h @@ -321,6 +321,11 @@ struct UniqueNameMapper { } Name sourceToUnique(Name sName) { + // DELEGATE_CALLER_TARGET is a fake target used to denote delegating to the + // caller. We do not need to modify it, as it has no definitions, only uses. + if (sName == DELEGATE_CALLER_TARGET) { + return DELEGATE_CALLER_TARGET; + } if (labelMappings.find(sName) == labelMappings.end()) { throw ParseException("bad label in sourceToUnique"); } diff --git a/src/passes/Inlining.cpp b/src/passes/Inlining.cpp index 44ebbd54d..d0a69ea96 100644 --- a/src/passes/Inlining.cpp +++ b/src/passes/Inlining.cpp @@ -48,6 +48,7 @@ struct FunctionInfo { Index size; bool hasCalls; bool hasLoops; + bool hasTryDelegate; bool usedGlobally; // in a table or export FunctionInfo() { @@ -55,11 +56,16 @@ struct FunctionInfo { size = 0; hasCalls = false; hasLoops = false; + hasTryDelegate = false; usedGlobally = false; } // See pass.h for how defaults for these options were chosen. bool worthInlining(PassOptions& options) { + // Until we have proper support for try-delegate, ignore such functions. + if (hasTryDelegate) { + return false; + } // If it's small enough that we always want to inline such things, do so. if (size <= options.inlining.alwaysInlineMaxSize) { return true; @@ -113,6 +119,12 @@ struct FunctionInfoScanner (*infos)[getFunction()->name].hasCalls = true; } + void visitTry(Try* curr) { + if (curr->isDelegate()) { + (*infos)[getFunction()->name].hasTryDelegate = true; + } + } + void visitRefFunc(RefFunc* curr) { assert(infos->count(curr->func) > 0); (*infos)[curr->func].refs++; |