Supporting coroutines without tail calls

Since coroutines depend on musttail calls, they can’t compile to WebAssembly without enabling the WebAssembly tail-call target feature. Unfortunately Wasm tail calls are not yet standard and have not shipped on any major WebAssembly engines, so enabling tail-call is not a realistic option for production code yet. Would it be possible to support coroutines without musttail for targets where it is not available? Is there already a workaround that I haven’t found?

Since coroutines depend on musttail calls

The semantics of standard C++ Coroutine shouldn’t depend on musttail calls. Although there are some papers about symmetric transfer, symmetric transfer are not part of standard today. So semantically, coroutines shouldn’t depend on musttail calls. The symmetric transfer nowadays is an optimization in the middle end.

So I guess you meet the implementation problem. Could you elaborate more where you meet the problem? Since I am not familiar with WebAssembly.

(Since the tag is ‘Clang Frontend’, I assume you’re refering to C++ coroutines)

Yes, definitely referring to C++ coroutines!

In particular the musttail calls are introduced by llvm/lib/Transforms/Coroutines/CoroSplit.cpp. I hadn’t registered until now that this is in the middle end rather than the frontend since I had assumed the coroutine handling was C+±specific, but that was wrong. These musttail calls get to the WebAssembly backend, which reports an error because it cannot lower musttail calls to WebAssembly without the nonstandard tail-call target feature enabled.

It’s good to know that C++ itself doesn’t depend on musttail calls. It sounds like fixing this would be a matter of changing how LLVM lowers the coroutine intrinsics to not use musttail when the target does not support tail calls.

Yeah, the C++ coroutines in Clang is implemented in 2 parts. It is helpful for the performance.

Would you like to give a reproducer for WebAssembly? So that I could work on that. Or if you want to contribute it, I think it should be good to accept it.

I sent ⚙ D128163 [Coroutines] Don't add musttail call if WebAssembly are enabled. I feel like it might be able to fix the problem. But I haven’t verified it since I didn’t touch WebAssembly before.