diff --git a/llvm/docs/Coroutines.rst b/llvm/docs/Coroutines.rst index 92e138b6893b2..60e32dc467d27 100644 --- a/llvm/docs/Coroutines.rst +++ b/llvm/docs/Coroutines.rst @@ -810,6 +810,28 @@ The LLVM IR for a coroutine using a Coroutine with a custom ABI looks like: ret ptr %hdl } +Parameter Attributes +==================== +Some parameter attributes, used to communicate additional information about the result or parameters of a function, require special handling. + +ByVal +----- +A ByVal parameter on an argument indicates that the pointee should be treated as being passed by value to the function. +Prior to the coroutine transforms loads and stores to/from the pointer are generated where the value is needed. +Consequently, a ByVal argument is treated much like an alloca. +Space is allocated for it on the coroutine frame and the uses of the argument pointer are replaced with a pointer to the coroutine frame. + +Swift Error +----------- +Clang supports the swiftcall calling convention in many common targets, and a user could call a function that takes a swifterror argument from a C++ coroutine. +The swifterror parameter attribute exists to model and optimize Swift error handling. +A swifterror alloca or parameter can only be loaded, stored, or passed as a swifterror call argument, and a swifterror call argument can only be a direct reference to a swifterror alloca or parameter. +These rules, not coincidentally, mean that you can always perfectly model the data flow in the alloca, and LLVM CodeGen actually has to do that in order to emit code. + +For coroutine lowering the default treatment of allocas breaks those rules — splitting will try to replace the alloca with an entry in the coro frame, which can lead to trying to pass that as a swifterror argument. +To pass a swifterror argument in a split function, we need to still have the alloca around; but we also potentially need the coro frame slot, since useful data can (in theory) be stored in the swifterror alloca slot across suspensions in the presplit coroutine. +When split a coroutine it is consequently necessary to keep both the frame slot as well as the alloca itself and then keep them in sync. + Intrinsics ==========