[PATCH] D23245: Part 5: Elide dynamic allocation of coroutine frame when possible

Gor Nishanov via llvm-commits llvm-commits at lists.llvm.org
Sat Aug 6 23:05:23 PDT 2016


GorNishanov created this revision.
GorNishanov added reviewers: majnemer, mehdi_amini.
GorNishanov added a subscriber: llvm-commits.

A particular coroutine usage pattern, where a coroutine is created, manipulated and 
destroyed by the same calling function, is common for coroutines implementing
RAII idiom and is suitable for allocation elision optimization which avoid 
dynamic allocation by storing the coroutine frame as a static `alloca` in its 
caller.

coro.free and coro.alloc intrinsics are used to indicate which code needs to be suppressed 
when dynamic allocation elision happens:
```
entry:
  %elide = call i8* @llvm.coro.alloc()
  %need.dyn.alloc = icmp ne i8* %elide, null
  br i1 %need.dyn.alloc, label %coro.begin, label %dyn.alloc
dyn.alloc:
  %alloc = call i8* @CustomAlloc(i32 4)
  br label %coro.begin
coro.begin:
  %phi = phi i8* [ %elide, %entry ], [ %alloc, %dyn.alloc ]
  %hdl = call i8* @llvm.coro.begin(i8* %phi, i32 0, i8* null,
                          i8* bitcast ([2 x void (%f.frame*)*]* @f.resumers to i8*))
```
and
```
  %mem = call i8* @llvm.coro.free(i8* %hdl)
  %need.dyn.free = icmp ne i8* %mem, null
  br i1 %need.dyn.free, label %dyn.free, label %if.end
dyn.free:
  call void @CustomFree(i8* %mem)
  br label %if.end
if.end:
  ...
```

If heap allocation elision is performed, we replace coro.alloc with a static alloca on the caller frame and coro.free with null constant.

Also, we need to make sure that if there are any tail calls referencing the coroutine frame, we need to remote tail call attribute, since now coroutine frame lives on the stack.

Documentation and overview is here: http://llvm.org/docs/Coroutines.html.

Upstreaming sequence (rough plan)
1.Add documentation. (https://reviews.llvm.org/D22603)
2.Add coroutine intrinsics. (https://reviews.llvm.org/D22659)
3.Add empty coroutine passes. (https://reviews.llvm.org/D22847)
4.Add coroutine devirtualization + tests.
ab) Lower coro.resume and coro.destroy (https://reviews.llvm.org/D22998)
c) Do devirtualization (https://reviews.llvm.org/D23229)
5.Add CGSCC restart trigger + tests. (https://reviews.llvm.org/D23234)
6.Add coroutine heap elision + tests.  <= we are here
7.Add the rest of the logic (split into more patches)

https://reviews.llvm.org/D23245

Files:
  lib/Transforms/Coroutines/CoroElide.cpp
  lib/Transforms/Coroutines/CoroInstr.h
  lib/Transforms/Coroutines/CoroInternal.h
  lib/Transforms/Coroutines/Coroutines.cpp
  test/Transforms/Coroutines/coro-heap-elide.ll
  test/Transforms/Coroutines/restart-trigger.ll

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D23245.67093.patch
Type: text/x-patch
Size: 13256 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160807/4976cf18/attachment.bin>


More information about the llvm-commits mailing list