@@ -312,6 +312,7 @@ lowered to a constant representing the size required for the coroutine frame.
312312The `coro.begin `_ intrinsic initializes the coroutine frame and returns the
313313coroutine handle. The second parameter of `coro.begin ` is given a block of memory
314314to be used if the coroutine frame needs to be allocated dynamically.
315+
315316The `coro.id `_ intrinsic serves as coroutine identity useful in cases when the
316317`coro.begin `_ intrinsic get duplicated by optimization passes such as
317318jump-threading.
@@ -749,6 +750,65 @@ and python iterator `__next__` would look like:
749750 return *(int *)coro.promise(hdl, 4, false);
750751 }
751752
753+ Custom ABIs and Plugin Libraries
754+ --------------------------------
755+
756+ Plugin libraries can extend coroutine lowering enabling a wide variety of users
757+ to utilize the coroutine transformation passes. An existing coroutine lowering
758+ is extended by: 1. defining custom ABIs that inherit from the existing ABIs,
759+ 2. give a list of generators for the custom ABIs when constructing the
760+ `CoroSplit `_ pass, and 3. use `coro.begin.custom.abi ` in place of `coro.begin `
761+ with an additional parameter for the index of the generator/ABI to be used for
762+ the coroutine.
763+
764+ A custom ABI overriding the SwitchABI's materialization looks like:
765+
766+ .. code-block :: c++
767+
768+ class CustomSwitchABI : public coro::SwitchABI {
769+ public:
770+ CustomSwitchABI(Function &F, coro::Shape &S)
771+ : coro::SwitchABI(F, S, ExtraMaterializable) {}
772+ };
773+
774+ Giving a list of custom ABI generators while constructing the `CoroSplit `
775+ pass looks like:
776+
777+ .. code-block :: c++
778+
779+ CoroSplitPass::BaseABITy GenCustomABI = [](Function &F, coro::Shape &S) {
780+ return new CustomSwitchABI(F, S);
781+ };
782+
783+ CGSCCPassManager CGPM;
784+ CGPM.addPass(CoroSplitPass({GenCustomABI}));
785+
786+ The LLVM IR for a coroutine using a Coroutine with a custom ABI looks like:
787+
788+ .. code-block :: llvm
789+
790+ define ptr @f(i32 %n) presplitcoroutine_custom_abi {
791+ entry:
792+ %id = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr null)
793+ %size = call i32 @llvm.coro.size.i32()
794+ %alloc = call ptr @malloc(i32 %size)
795+ %hdl = call noalias ptr @llvm.coro.begin.custom.abi(token %id, ptr %alloc, i32 0)
796+ br label %loop
797+ loop:
798+ %n.val = phi i32 [ %n, %entry ], [ %inc, %loop ]
799+ %inc = add nsw i32 %n.val, 1
800+ call void @print(i32 %n.val)
801+ %0 = call i8 @llvm.coro.suspend(token none, i1 false)
802+ switch i8 %0, label %suspend [i8 0, label %loop
803+ i8 1, label %cleanup]
804+ cleanup:
805+ %mem = call ptr @llvm.coro.free(token %id, ptr %hdl)
806+ call void @free(ptr %mem)
807+ br label %suspend
808+ suspend:
809+ %unused = call i1 @llvm.coro.end(ptr %hdl, i1 false, token none)
810+ ret ptr %hdl
811+ }
752812
753813 Intrinsics
754814==========
@@ -1007,6 +1067,36 @@ with small positive and negative offsets).
10071067
10081068A frontend should emit exactly one `coro.begin ` intrinsic per coroutine.
10091069
1070+ .. _coro.begin.custom.abi :
1071+
1072+ 'llvm.coro.begin.custom.abi' Intrinsic
1073+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1074+ ::
1075+
1076+ declare ptr @llvm.coro.begin.custom.abi(token <id>, ptr <mem>, i32)
1077+
1078+ Overview:
1079+ """""""""
1080+
1081+ The '``llvm.coro.begin.custom.abi ``' intrinsic is used in place of the
1082+ `coro.begin ` intrinsic with an additional parameter to specify the custom ABI
1083+ for the coroutine. The return is identical to that of the `coro.begin `
1084+ intrinsic.
1085+
1086+ Arguments:
1087+ """"""""""
1088+
1089+ The first and second arguments are identical to those of the `coro.begin `
1090+ intrinsic.
1091+
1092+ The third argument is an i32 index of the generator list given to the
1093+ `CoroSplit ` pass specifying the custom ABI generator lor this coroutine.
1094+
1095+ Semantics:
1096+ """"""""""
1097+
1098+ The semantics are identical to those of the `coro.begin ` intrinsic.
1099+
10101100.. _coro.free :
10111101
10121102'llvm.coro.free' Intrinsic
0 commit comments