<div dir="ltr">Here is an example of emulating a CPS call using LLVM Coroutines:<div><br></div><div><a href="https://gist.github.com/GorNishanov/d7caa7697681b96180e4648ed9408bc9">https://gist.github.com/GorNishanov/d7caa7697681b96180e4648ed9408bc9</a><br></div><div><br></div><div>It corresponds to:</div><div><br></div><div>void f(int val) {</div><div>  partA(val);</div><div>  int result = cps_call_bar(41);</div><div>  partB(result)</div><div>}</div><div><br></div><div>int cps_call_bar(int val) {</div><div>  partC(val)</div><div>  return 42;</div><div>}</div><div><br></div><div>int main() {</div><div>   f(40);<br>}</div><div><br></div><div>Run: opt -enable-coroutines -O2 cps.ll -S</div><div><br></div><div>cps_call will look like:</div><div><br></div><div>define void @cps_call_bar(i8* %caller, i32* nocapture %retval.addr, i32 %n) local_unnamed_addr {<br></div><div><div>  tail call void @partC(i32 %n)</div><div>  store i32 42, i32* %retval.addr, align 4</div><div>  %1 = bitcast i8* %caller to { i8*, i8* }*</div><div>  %2 = getelementptr inbounds { i8*, i8* }, { i8*, i8* }* %1, i32 0, i32 0</div><div>  %3 = load i8*, i8** %2</div><div>  %4 = bitcast i8* %3 to void (i8*)*</div><div>  tail call fastcc void %4(i8* %caller)</div><div>  ret void</div><div>}</div><div><br></div><div>main will get optimized to:</div><div><br></div><div>define i32 @main() local_unnamed_addr {</div><div>entry:</div><div>  %alloc.i = tail call i8* @malloc(i32 24)</div><div>  tail call void @partA(i32 40)</div><div>  tail call void @partC(i32 41)</div><div>  tail call void @partB(i32 42)</div><div>  tail call void @free(i8* nonnull %alloc.i)</div><div>  ret i32 0</div><div>}</div></div><div><br></div><div>and resume part of f will be:</div><div><br></div><div><div>define internal fastcc void @f.resume(%f.Frame* %FramePtr) {</div><div>entry.resume:</div><div>  %vFrame = bitcast %f.Frame* %FramePtr to i8*</div><div>  tail call void @partB(i32 42)</div><div>  tail call void @free(i8* %vFrame)</div><div>  ret void</div><div>}</div></div><div><br></div><div>Note that this is using LLVM coroutines as is. To support CPS we would need to add a couple of intrinsics along the lines I mentioned in my earlier post.</div></div>