Go to file
Gor Nishanov b2a9c02521 [Coroutines] Part 6: Elide dynamic allocation of a coroutine frame when possible
Summary:
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)

Reviewers: mehdi_amini, majnemer

Subscribers: mehdi_amini, llvm-commits

Differential Revision: https://reviews.llvm.org/D23245

llvm-svn: 278242
2016-08-10 16:40:39 +00:00
clang [analyzer] Fix a crash in CloneDetector when calling functions by pointers. 2016-08-10 16:25:16 +00:00
clang-tools-extra [clang-rename] fix test introduced in r278221 2016-08-10 13:46:36 +00:00
compiler-rt test commit. 2016-08-10 10:48:02 +00:00
debuginfo-tests New round of fixes for "Always compile debuginfo-tests for the host triple" 2014-10-18 23:47:59 +00:00
libclc Make min follow the OCL 1.0 specs 2016-07-25 22:36:22 +00:00
libcxx test/hard_link_count(): Fix test on darwin 2016-08-10 01:02:28 +00:00
libcxxabi Depend directly on unwind when not building standalone 2016-08-09 21:28:52 +00:00
libunwind Allow building both shared and static library 2016-08-08 22:55:48 +00:00
lld [ELF][MIPS] Take into account combination of EF_MIPS_ARCH and EF_MIPS_MACH flags while checking ISA compatibility 2016-08-10 15:06:45 +00:00
lldb Make sure files include what they use (part 1/N) 2016-08-10 13:30:20 +00:00
llgo [llgo] add llgo source path to LLVM_GO_PACKAGES 2016-07-27 03:01:00 +00:00
llvm [Coroutines] Part 6: Elide dynamic allocation of a coroutine frame when possible 2016-08-10 16:40:39 +00:00
openmp Fix linking of omp_foreign_thread_team_reuse test on FreeBSD 2016-08-08 18:34:05 +00:00
parallel-libs [StreamExecutor] Add DeviceMemory and kernel arg packing 2016-08-08 16:45:19 +00:00
polly [GPGPU] Ensure arrays where only parts are modified are copied to GPU 2016-08-10 10:58:19 +00:00