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 | |
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.
-rw-r--r-- | src/parsing.h | 5 | ||||
-rw-r--r-- | src/passes/Inlining.cpp | 12 | ||||
-rw-r--r-- | test/passes/inlining_all-features.txt | 30 | ||||
-rw-r--r-- | test/passes/inlining_all-features.wast | 27 |
4 files changed, 74 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++; diff --git a/test/passes/inlining_all-features.txt b/test/passes/inlining_all-features.txt index e0ecf57b5..f255ed8ff 100644 --- a/test/passes/inlining_all-features.txt +++ b/test/passes/inlining_all-features.txt @@ -79,3 +79,33 @@ ) ) ) +(module + (type $none_=>_none (func)) + (func $0 + (try $label$3 + (do + (nop) + ) + (delegate 0) + ) + ) + (func $1 + (call $0) + ) +) +(module + (type $none_=>_i32 (func (result i32))) + (func $1 (result i32) + (try $label$3 + (do + (nop) + ) + (delegate 0) + ) + (block (result i32) + (block $__inlined_func$0 (result i32) + (i32.const 42) + ) + ) + ) +) diff --git a/test/passes/inlining_all-features.wast b/test/passes/inlining_all-features.wast index 3890d63a1..4b20d4240 100644 --- a/test/passes/inlining_all-features.wast +++ b/test/passes/inlining_all-features.wast @@ -64,3 +64,30 @@ ) ) ) +;; for now, do not inline a try-delegate +(module + (type $none_=>_none (func)) + (func $0 + (try $label$3 + (do) + (delegate 0) + ) + ) + (func $1 + (call $0) + ) +) +;; properly support inlining into a function with a try-delegate +(module + (type $none_=>_none (func)) + (func $0 (result i32) + (i32.const 42) + ) + (func $1 (result i32) + (try $label$3 + (do) + (delegate 0) + ) + (call $0) + ) +) |