summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2022-09-26 15:11:22 -0700
committerGitHub <noreply@github.com>2022-09-26 15:11:22 -0700
commiteb42407e6bc027a40cc569ad0c1b915c4f285b60 (patch)
tree03ba08b7a3142bbceea1d1e17445f66ebe27531e /src
parentb23b47d54a2fb02b048e7eb8de8043358599ec8b (diff)
downloadbinaryen-eb42407e6bc027a40cc569ad0c1b915c4f285b60.tar.gz
binaryen-eb42407e6bc027a40cc569ad0c1b915c4f285b60.tar.bz2
binaryen-eb42407e6bc027a40cc569ad0c1b915c4f285b60.zip
[GUFA] Optimize functions not taken by reference better (#5085)
This moves the logic to add connections from signatures to functions from the top level into the RefFunc logic. That way we only add those connections to functions that actually have a RefFunc, which avoids us thinking that a function without one can be reached by a call_ref of its type. Has a small but non-zero benefit on j2wasm.
Diffstat (limited to 'src')
-rw-r--r--src/ir/possible-contents.cpp35
1 files changed, 14 insertions, 21 deletions
diff --git a/src/ir/possible-contents.cpp b/src/ir/possible-contents.cpp
index 4755c9904..fd186a74f 100644
--- a/src/ir/possible-contents.cpp
+++ b/src/ir/possible-contents.cpp
@@ -418,6 +418,20 @@ struct InfoCollector
addRoot(
curr,
PossibleContents::literal(Literal(curr->func, curr->type.getHeapType())));
+
+ // The presence of a RefFunc indicates the function may be called
+ // indirectly, so add the relevant connections for this particular function.
+ // We do so here in the RefFunc so that we only do it for functions that
+ // actually have a RefFunc.
+ auto* func = getModule()->getFunction(curr->func);
+ for (Index i = 0; i < func->getParams().size(); i++) {
+ info.links.push_back(
+ {SignatureParamLocation{func->type, i}, LocalLocation{func, i, 0}});
+ }
+ for (Index i = 0; i < func->getResults().size(); i++) {
+ info.links.push_back(
+ {ResultLocation{func, i}, SignatureResultLocation{func->type, i}});
+ }
}
void visitRefEq(RefEq* curr) {
addRoot(curr);
@@ -616,9 +630,6 @@ struct InfoCollector
handleIndirectCall(curr, curr->heapType);
}
void visitCallRef(CallRef* curr) {
- // TODO: Optimize like RefCast etc.: the values reaching us depend on the
- // possible values of |target| (which might be nothing, or might be a
- // constant function).
handleIndirectCall(curr, curr->target->type);
}
@@ -1295,24 +1306,6 @@ Flower::Flower(Module& wasm) : wasm(wasm) {
}
#ifdef POSSIBLE_CONTENTS_DEBUG
- std::cout << "func phase\n";
-#endif
-
- // Connect function parameters to their signature, so that any indirect call
- // of that signature will reach them.
- // TODO: find which functions are even taken by reference
- for (auto& func : wasm.functions) {
- for (Index i = 0; i < func->getParams().size(); i++) {
- links.insert(getIndexes({SignatureParamLocation{func->type, i},
- LocalLocation{func.get(), i, 0}}));
- }
- for (Index i = 0; i < func->getResults().size(); i++) {
- links.insert(getIndexes({ResultLocation{func.get(), i},
- SignatureResultLocation{func->type, i}}));
- }
- }
-
-#ifdef POSSIBLE_CONTENTS_DEBUG
std::cout << "struct phase\n";
#endif