llvm.coro
LLVMのコルーチンサポート。
いくつかのモード(lowering方法)がある。
比較的機械語に近い他の命令群に比べると、だいぶ抽象度が高く複雑な印象。
LLVM coroutineは1つ以上のsuspend pointをもつLLVM関数である。
loweringの方法が2種類存在する
が、いずれにしろもとの関数が1つのramp functionといくつかのresume functionsに分割されるのは同じ?
分割をまたいで保持が必要な情報はcorouitne frameという領域に保存される
lowering方法その1:Switched-Resume Lowering
coroutine functionをramp function、resume function、destroy functionの3つに分割する
いくつめのsuspend pointまで進んだかを整数で管理する必要がある
lowering方法その2:Retuned-Continuation Lowering(retcon)
llvm.coro.id.retconとかを使うとこれになる
各suspend pointで、1つ以上のyielded valueと、continuation functionを返す
この関数ポインタを呼ぶことでコルーチンが再開される
lowering方法その3:Async Lowering
llvm.coro.id.asyncを使うとこれになる
例にswiftccって書いてるが #Swift で使われているのかな コルーチンは「async context」を第一引数で受け取り、voidを返す
Coroutines by Example
いずれもswitched-resumeの例
llvm.coro.sizeが返しただけのメモリを確保し、llvm.coro.beginを呼ぶ
Coroutine Transformation
上記の例がどう機械語に落ちるか。
%incはスタックに乗せておけないので、ヒープに置くような変換(LLVM IRからLLVM IRへの変換)が行われる