Skip to content

Commit 8cfde92

Browse files
committed
MergeSimilarFunctions: do a return_call when possible
This patch makes MergeSimilarFunctions do a return_call when the module has tail-call enabled. This is not merely an optimization, but is crucial for correctness when optimizing wasm modules produced by GHC that relies on tail-call to do control flow transfers. Previously, -Oz would break tail-call enabled modules by making the control stack grow where it shouldn't.
1 parent bc47696 commit 8cfde92

File tree

1 file changed

+6
-5
lines changed

1 file changed

+6
-5
lines changed

src/passes/MergeSimilarFunctions.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,8 @@ struct EquivalentClass {
165165
Function* target,
166166
Function* shared,
167167
const std::vector<ParamInfo>& params,
168-
const std::vector<Expression*>& extraArgs);
168+
const std::vector<Expression*>& extraArgs,
169+
bool isReturn);
169170

170171
bool deriveParams(Module* module,
171172
std::vector<ParamInfo>& params,
@@ -480,7 +481,7 @@ void EquivalentClass::merge(Module* module,
480481
for (auto& param : params) {
481482
extraArgs.push_back(param.lowerToExpression(builder, module, i));
482483
}
483-
replaceWithThunk(builder, func, sharedFn, params, extraArgs);
484+
replaceWithThunk(builder, func, sharedFn, params, extraArgs, module->features.hasTailCall());
484485
}
485486
return;
486487
}
@@ -617,7 +618,8 @@ EquivalentClass::replaceWithThunk(Builder& builder,
617618
Function* target,
618619
Function* shared,
619620
const std::vector<ParamInfo>& params,
620-
const std::vector<Expression*>& extraArgs) {
621+
const std::vector<Expression*>& extraArgs,
622+
bool isReturn) {
621623
std::vector<Expression*> callOperands;
622624
Type targetParams = target->getParams();
623625
for (Index i = 0; i < targetParams.size(); i++) {
@@ -628,8 +630,7 @@ EquivalentClass::replaceWithThunk(Builder& builder,
628630
callOperands.push_back(value);
629631
}
630632

631-
// TODO: make a return_call when possible?
632-
auto ret = builder.makeCall(shared->name, callOperands, target->getResults());
633+
auto ret = builder.makeCall(shared->name, callOperands, target->getResults(), isReturn);
633634
target->vars.clear();
634635
target->body = ret;
635636
return target;

0 commit comments

Comments
 (0)