[llvm] [Coroutines] Documentation for custom ABIs (PR #111781)

Tyler Nowicki via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 10 10:00:08 PDT 2024


https://github.com/TylerNowicki updated https://github.com/llvm/llvm-project/pull/111781

>From e0ef787ad06911b4c8a4ff59235d9299b43ef6e4 Mon Sep 17 00:00:00 2001
From: tnowicki <tnowicki.nowicki at amd.com>
Date: Mon, 9 Sep 2024 15:15:02 -0400
Subject: [PATCH 1/3] [Coroutines] Documentation for plugin libraries and
 custom ABIs

---
 llvm/docs/Coroutines.rst | 90 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 90 insertions(+)

diff --git a/llvm/docs/Coroutines.rst b/llvm/docs/Coroutines.rst
index 5679aefcb421d8..d53f4ed2a4e707 100644
--- a/llvm/docs/Coroutines.rst
+++ b/llvm/docs/Coroutines.rst
@@ -312,6 +312,7 @@ lowered to a constant representing the size required for the coroutine frame.
 The `coro.begin`_ intrinsic initializes the coroutine frame and returns the
 coroutine handle. The second parameter of `coro.begin` is given a block of memory
 to be used if the coroutine frame needs to be allocated dynamically.
+
 The `coro.id`_ intrinsic serves as coroutine identity useful in cases when the
 `coro.begin`_ intrinsic get duplicated by optimization passes such as
 jump-threading.
@@ -749,6 +750,65 @@ and python iterator `__next__` would look like:
     return *(int*)coro.promise(hdl, 4, false);
   }
 
+Custom ABIs and Plugin Libraries
+--------------------------------
+
+Plugin libraries can extend coroutine lowering enabling a wide variety of users
+to utilize the coroutine transformation passes. An existing coroutine lowering
+is extended by: 1. defining custom ABIs that inherit from the existing ABIs,
+2. give a list of generators for the custom ABIs when constructing the
+`CoroSplit`_ pass, and 3. use `coro.begin.custom.abi` in place of `coro.begin`
+with an additional parameter for the index of the generator/ABI to be used for
+the coroutine.
+
+A custom ABI overriding the SwitchABI's materialization looks like:
+
+.. code-block:: c++
+
+  class CustomSwitchABI : public coro::SwitchABI {
+  public:
+    CustomSwitchABI(Function &F, coro::Shape &S)
+      : coro::SwitchABI(F, S, ExtraMaterializable) {}
+  };
+
+Giving a list of custom ABI generators while constructing the `CoroSplit`
+pass looks like:
+
+.. code-block:: c++
+
+  CoroSplitPass::BaseABITy GenCustomABI = [](Function &F, coro::Shape &S) {
+    return new CustomSwitchABI(F, S);
+  };
+
+  CGSCCPassManager CGPM;
+  CGPM.addPass(CoroSplitPass({GenCustomABI}));
+
+The LLVM IR for a coroutine using a Coroutine with a custom ABI looks like:
+
+.. code-block:: llvm
+
+  define ptr @f(i32 %n) presplitcoroutine_custom_abi {
+  entry:
+    %id = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr null)
+    %size = call i32 @llvm.coro.size.i32()
+    %alloc = call ptr @malloc(i32 %size)
+    %hdl = call noalias ptr @llvm.coro.begin.custom.abi(token %id, ptr %alloc, i32 0)
+    br label %loop
+  loop:
+    %n.val = phi i32 [ %n, %entry ], [ %inc, %loop ]
+    %inc = add nsw i32 %n.val, 1
+    call void @print(i32 %n.val)
+    %0 = call i8 @llvm.coro.suspend(token none, i1 false)
+    switch i8 %0, label %suspend [i8 0, label %loop
+                                  i8 1, label %cleanup]
+  cleanup:
+    %mem = call ptr @llvm.coro.free(token %id, ptr %hdl)
+    call void @free(ptr %mem)
+    br label %suspend
+  suspend:
+    %unused = call i1 @llvm.coro.end(ptr %hdl, i1 false, token none)
+    ret ptr %hdl
+  }
 
 Intrinsics
 ==========
@@ -1007,6 +1067,36 @@ with small positive and negative offsets).
 
 A frontend should emit exactly one `coro.begin` intrinsic per coroutine.
 
+.. _coro.begin.custom.abi:
+
+'llvm.coro.begin.custom.abi' Intrinsic
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+::
+
+  declare ptr @llvm.coro.begin.custom.abi(token <id>, ptr <mem>, i32)
+
+Overview:
+"""""""""
+
+The '``llvm.coro.begin.custom.abi``' intrinsic is used in place of the
+`coro.begin` intrinsic with an additional parameter to specify the custom ABI
+for the coroutine. The return is identical to that of the `coro.begin`
+intrinsic.
+
+Arguments:
+""""""""""
+
+The first and second arguments are identical to those of the `coro.begin`
+intrinsic.
+
+The third argument is an i32 index of the generator list given to the
+`CoroSplit` pass specifying the custom ABI generator lor this coroutine.
+
+Semantics:
+""""""""""
+
+The semantics are identical to those of the `coro.begin` intrinsic.
+
 .. _coro.free:
 
 'llvm.coro.free' Intrinsic

>From 2ec85daff02beb501860b74be6f9c15d588ef146 Mon Sep 17 00:00:00 2001
From: Tyler Nowicki <tyler.nowicki at gmail.com>
Date: Thu, 10 Oct 2024 12:58:50 -0400
Subject: [PATCH 2/3] Update Coroutines.rst

---
 llvm/docs/Coroutines.rst | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/llvm/docs/Coroutines.rst b/llvm/docs/Coroutines.rst
index d53f4ed2a4e707..80b1d6bf9a15da 100644
--- a/llvm/docs/Coroutines.rst
+++ b/llvm/docs/Coroutines.rst
@@ -755,11 +755,11 @@ Custom ABIs and Plugin Libraries
 
 Plugin libraries can extend coroutine lowering enabling a wide variety of users
 to utilize the coroutine transformation passes. An existing coroutine lowering
-is extended by: 1. defining custom ABIs that inherit from the existing ABIs,
-2. give a list of generators for the custom ABIs when constructing the
-`CoroSplit`_ pass, and 3. use `coro.begin.custom.abi` in place of `coro.begin`
-with an additional parameter for the index of the generator/ABI to be used for
-the coroutine.
+is extended by:
+
+#. defining custom ABIs that inherit from the existing ABIs,
+#. give a list of generators for the custom ABIs when constructing the `CoroSplit`_ pass, and
+#. use `coro.begin.custom.abi` in place of `coro.begin` that has an additional parameter for the index of the generator/ABI to be used for the coroutine.
 
 A custom ABI overriding the SwitchABI's materialization looks like:
 
@@ -777,7 +777,7 @@ pass looks like:
 .. code-block:: c++
 
   CoroSplitPass::BaseABITy GenCustomABI = [](Function &F, coro::Shape &S) {
-    return new CustomSwitchABI(F, S);
+    return std::make_unique<CustomSwitchABI>(F, S);
   };
 
   CGSCCPassManager CGPM;

>From ae7df95bfccf649ab7af7fa1e19c27bd704c7a8a Mon Sep 17 00:00:00 2001
From: Tyler Nowicki <tyler.nowicki at gmail.com>
Date: Thu, 10 Oct 2024 12:59:57 -0400
Subject: [PATCH 3/3] Update Coroutines.rst

---
 llvm/docs/Coroutines.rst | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/docs/Coroutines.rst b/llvm/docs/Coroutines.rst
index 80b1d6bf9a15da..393c8820a1aff0 100644
--- a/llvm/docs/Coroutines.rst
+++ b/llvm/docs/Coroutines.rst
@@ -1079,8 +1079,8 @@ Overview:
 """""""""
 
 The '``llvm.coro.begin.custom.abi``' intrinsic is used in place of the
-`coro.begin` intrinsic with an additional parameter to specify the custom ABI
-for the coroutine. The return is identical to that of the `coro.begin`
+`coro.begin` intrinsic that has an additional parameter to specify the custom
+ABI for the coroutine. The return is identical to that of the `coro.begin`
 intrinsic.
 
 Arguments:



More information about the llvm-commits mailing list