[llvm-dev] [RFC] Adding CPS call support

Gor Nishanov via llvm-dev llvm-dev at lists.llvm.org
Wed Apr 19 11:53:49 PDT 2017

Here is an example of emulating a CPS call using LLVM Coroutines:


It corresponds to:

void f(int val) {
  int result = cps_call_bar(41);

int cps_call_bar(int val) {
  return 42;

int main() {

Run: opt -enable-coroutines -O2 cps.ll -S

cps_call will look like:

define void @cps_call_bar(i8* %caller, i32* nocapture %retval.addr, i32 %n)
local_unnamed_addr {
  tail call void @partC(i32 %n)
  store i32 42, i32* %retval.addr, align 4
  %1 = bitcast i8* %caller to { i8*, i8* }*
  %2 = getelementptr inbounds { i8*, i8* }, { i8*, i8* }* %1, i32 0, i32 0
  %3 = load i8*, i8** %2
  %4 = bitcast i8* %3 to void (i8*)*
  tail call fastcc void %4(i8* %caller)
  ret void

main will get optimized to:

define i32 @main() local_unnamed_addr {
  %alloc.i = tail call i8* @malloc(i32 24)
  tail call void @partA(i32 40)
  tail call void @partC(i32 41)
  tail call void @partB(i32 42)
  tail call void @free(i8* nonnull %alloc.i)
  ret i32 0

and resume part of f will be:

define internal fastcc void @f.resume(%f.Frame* %FramePtr) {
  %vFrame = bitcast %f.Frame* %FramePtr to i8*
  tail call void @partB(i32 42)
  tail call void @free(i8* %vFrame)
  ret void

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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170419/122f0e31/attachment.html>

More information about the llvm-dev mailing list