summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/passes/SignatureRefining.cpp26
1 files changed, 26 insertions, 0 deletions
diff --git a/src/passes/SignatureRefining.cpp b/src/passes/SignatureRefining.cpp
index 24d120dda..ae124dc79 100644
--- a/src/passes/SignatureRefining.cpp
+++ b/src/passes/SignatureRefining.cpp
@@ -73,6 +73,15 @@ struct SignatureRefining : public Pass {
std::vector<Call*> calls;
std::vector<CallRef*> callRefs;
+ // Additional calls to take into account. We store intrinsic calls here,
+ // as they must appear twice: call.without.effects is both a normal call
+ // and also takes a final parameter that is a function reference that is
+ // called, and so two signatures are relevant for it. For the latter, we
+ // add the call as an "extra call" (which is an unusual call, as it has an
+ // extra parameter at the end, the function reference, compared to what we
+ // expect for the signature being called).
+ std::vector<Call*> extraCalls;
+
// A possibly improved LUB for the results.
LUBFinder resultsLUB;
@@ -107,6 +116,17 @@ struct SignatureRefining : public Pass {
// called.
for (auto* call : info.calls) {
allInfo[module->getFunction(call->target)->type].calls.push_back(call);
+
+ // For call.without.effects, we also add the effective function being
+ // called as well. The final operand is the function reference being
+ // called, which defines that type.
+ if (Intrinsics(*module).isCallWithoutEffects(call)) {
+ auto targetType = call->operands.back()->type;
+ if (!targetType.isRef()) {
+ continue;
+ }
+ allInfo[targetType.getHeapType()].extraCalls.push_back(call);
+ }
}
// For indirect calls, add each call_ref to the type the call_ref uses.
@@ -187,6 +207,12 @@ struct SignatureRefining : public Pass {
for (auto* callRef : info.callRefs) {
updateLUBs(callRef->operands);
}
+ for (auto* call : info.extraCalls) {
+ // Note that these intrinsic calls have an extra function reference
+ // param at the end, but updateLUBs looks at |numParams| only, so it
+ // considers just the relevant parameters.
+ updateLUBs(call->operands);
+ }
// Find the final LUBs, and see if we found an improvement.
std::vector<Type> newParamsTypes;