From 5bf352ac773bd121d3571efd8cf4c2746517d126 Mon Sep 17 00:00:00 2001 From: tnowicki Date: Thu, 21 Nov 2024 11:21:19 -0500 Subject: [PATCH 1/3] [Coroutines][Docs] Add a discussion on the handling of certain parameter attribs ByVal arguments and Swifterror require special handling in the coroutine passes. The goal of this section is to provide a description of how these parameter attributes are handled. --- llvm/docs/Coroutines.rst | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/llvm/docs/Coroutines.rst b/llvm/docs/Coroutines.rst index 92e138b6893b2..dfbd855099834 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 +-----dd +A ByVal parameter on an argument indicates that the pointer parameter should really be 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 ========== From 21fc5607ae4d0521bcd53d27d5af1b2ecc2d3b47 Mon Sep 17 00:00:00 2001 From: Tyler Nowicki Date: Mon, 25 Nov 2024 10:34:41 -0500 Subject: [PATCH 2/3] Update Coroutines.rst --- llvm/docs/Coroutines.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/docs/Coroutines.rst b/llvm/docs/Coroutines.rst index dfbd855099834..c9913490789ad 100644 --- a/llvm/docs/Coroutines.rst +++ b/llvm/docs/Coroutines.rst @@ -815,7 +815,7 @@ Parameter Attributes Some parameter attributes, used to communicate additional information about the result or parameters of a function, require special handling. ByVal ------dd +----- A ByVal parameter on an argument indicates that the pointer parameter should really be 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. From 4b190da228e99d25a68d9b2ae9d0f4eea83deceb Mon Sep 17 00:00:00 2001 From: Tyler Nowicki Date: Mon, 9 Dec 2024 15:56:51 -0500 Subject: [PATCH 3/3] Update llvm/docs/Coroutines.rst --- llvm/docs/Coroutines.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/docs/Coroutines.rst b/llvm/docs/Coroutines.rst index c9913490789ad..60e32dc467d27 100644 --- a/llvm/docs/Coroutines.rst +++ b/llvm/docs/Coroutines.rst @@ -816,7 +816,7 @@ Some parameter attributes, used to communicate additional information about the ByVal ----- -A ByVal parameter on an argument indicates that the pointer parameter should really be passed by value to the function. +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.