Need help about LLVM build coroutine

Ferhat Kurtulmuş aferust at gmail.com
Tue Mar 5 17:59:04 UTC 2024


On Saturday, 2 March 2024 at 12:56:27 UTC, Dakota wrote:
> On Saturday, 2 March 2024 at 12:32:32 UTC, Richard (Rikki) 
> Andrew Cattermole wrote:
>> From what I'm reading of the documentation, it looks like you 
>> have to work at the IR level to declare a coroutine.
>>
>> This isn't something you can do with only intrinsics in 
>> library code.
>>
>> https://llvm.org/docs/Coroutines.html#introduction
>>
>> Take note of the function attribute ``presplitcoroutine`` 
>> under coroutine representation.
>>
>> https://llvm.org/docs/Coroutines.html#coroutine-representation
>
> Thanks for the tips. I dont understand LLVM IR.  I want to 
> create a LLIR function which accept 2 parameters,  first one is 
> a pointer of coroutine function entry, the other is a pointer 
> to a struct look like this:
>
> ```d
> struct coroutine_object {
>     void* coro_handler;
>     void* core_argv;
>     size_t core_argc;
> }
> ```
>
>
> this llvm IR should create one new coroutine, and save the 
> handler into arg2.coro_handler, then start enter the coroutine 
> to execute.
>
>
> I use chatGPT get this code.  any one can help me fix it and 
> export to `extern(C)`
>
> ```ir
>
> define void @start_coroutine(i8* %func_ptr, i8** 
> %coro_handle_ptr) {
> entry:
>   %func = bitcast i8* %func_ptr to void (i8*)*
>
>   %coro_begin = call i8* @llvm.coro.begin(token none, i8* null, 
> i8* null)
>
>   store i8* %coro_begin, i8** %coro_handle_ptr
>
>   call void @llvm.coro.alloc(i8* %coro_begin, i8* bitcast (void 
> (i8*)* @coro_func to i8*))
>
>   call void @llvm.coro.init(token none, i8* %coro_begin, i8* 
> %coro_begin)
>
>   call void @llvm.coro.save(i8* %coro_begin, i8** null)
>
>   call void @llvm.coro.resume(i8* %coro_begin)
>
>   ret void
> }
>
> declare token @llvm.coro.begin(token, i8*, i8*)
> declare void @llvm.coro.alloc(i8*, i8*)
> declare void @llvm.coro.init(token, i8*, i8*)
> declare void @llvm.coro.save(i8*, i8**)
> declare void @llvm.coro.resume(i8*)
> ```
>
> to build it use :
>
> ```sh
> llvm-as -o coro.bc coro.ll
> llvm-ar rcs libcoro.a coro.bc
> ```
I cannot help at any level close to or further than Rikki, but I 
want to state that in d with LDC you can embed ir code directly 
into the code like the below code (it just prints a value using a 
print function of Gou intrinsic. Not sure it's been long time).
void printInt(uint val){
     __irEx!(`
         @str = private addrspace(4) constant [4 x i8] c"%d\0A\00"
         declare i8* @llvm.nvvm.ptr.constant.to.gen.p0i8.p4i8(i8 
addrspace(4)*) nounwind readnone
         declare i32 @vprintf(i8* nocapture, i8*) nounwind
         declare i32 addrspace(5)* 
@llvm.nvvm.ptr.gen.to.local.p5i32.p0i32(i32*) nounwind readnone
             `, `
         %tmp = alloca [12 x i32], align 8
         %tmp2 = getelementptr inbounds [12 x i32], [12 x i32]* 
%tmp, i64 0, i64 0
         %gen2local = call i32 addrspace(5)* 
@llvm.nvvm.ptr.gen.to.local.p5i32.p0i32(i32* %tmp2)

         %getElem12 = getelementptr i32, i32 addrspace(5)* 
%gen2local, i64 0
         store i32 %0, i32 addrspace(5)* %getElem12, align 8

         %fmt = call i8* 
@llvm.nvvm.ptr.constant.to.gen.p0i8.p4i8(i8 addrspace(4)* 
getelementptr inbounds ([4 x i8], [4 x i8] addrspace(4)* @str, 
i64 0, i64 0))

         %val = bitcast [12 x i32]* %tmp to i8*

         %call = call i32 @vprintf(i8* %fmt, i8* %val)
         ret void
             `, ``, void, uint)(val);
}




More information about the digitalmars-d-ldc mailing list