GorNishanov created this revision.
SemaCoroutine forms expressions referring to the coroutine frame of the
enclosing coroutine using coro.frame builtin.
During codegen, we emit llvm.coro.begin intrinsic that returns the address of
the coroutine frame.
When coro.frame is emitted, we replace it with SSA value of coro.begin.
https://reviews.llvm.org/D31586
Files:
lib/CodeGen/CGCoroutine.cpp
test/CodeGenCoroutines/coro-alloc.cpp
test/CodeGenCoroutines/coro-await.cpp
test/CodeGenCoroutines/coro-builtins.c
Index: test/CodeGenCoroutines/coro-builtins.c
===
--- test/CodeGenCoroutines/coro-builtins.c
+++ test/CodeGenCoroutines/coro-builtins.c
@@ -2,7 +2,7 @@
void *myAlloc(long long);
-// CHECK-LABEL: f(
+// CHECK-LABEL: f(
void f(int n) {
// CHECK: %n.addr = alloca i32
// CHECK: %n_copy = alloca i32
@@ -19,31 +19,25 @@
// CHECK-NEXT: %[[SIZE:.+]] = call i64 @llvm.coro.size.i64()
// CHECK-NEXT: %[[MEM:.+]] = call i8* @myAlloc(i64 %[[SIZE]])
- // CHECK-NEXT: %[[BEG:.+]] = call i8* @llvm.coro.begin(token %[[COROID]], i8* %[[MEM]])
+ // CHECK-NEXT: %[[FRAME:.+]] = call i8* @llvm.coro.begin(token %[[COROID]], i8* %[[MEM]])
__builtin_coro_begin(myAlloc(__builtin_coro_size()));
- // CHECK-NEXT: %[[FRAME1:.+]] = call i8* @llvm.coro.frame()
- // CHECK-NEXT: call void @llvm.coro.resume(i8* %[[FRAME1]])
+ // CHECK-NEXT: call void @llvm.coro.resume(i8* %[[FRAME]])
__builtin_coro_resume(__builtin_coro_frame());
- // CHECK-NEXT: %[[FRAME2:.+]] = call i8* @llvm.coro.frame()
- // CHECK-NEXT: call void @llvm.coro.destroy(i8* %[[FRAME2]])
+ // CHECK-NEXT: call void @llvm.coro.destroy(i8* %[[FRAME]])
__builtin_coro_destroy(__builtin_coro_frame());
- // CHECK-NEXT: %[[FRAME3:.+]] = call i8* @llvm.coro.frame()
- // CHECK-NEXT: call i1 @llvm.coro.done(i8* %[[FRAME3]])
+ // CHECK-NEXT: call i1 @llvm.coro.done(i8* %[[FRAME]])
__builtin_coro_done(__builtin_coro_frame());
- // CHECK-NEXT: %[[FRAME4:.+]] = call i8* @llvm.coro.frame()
- // CHECK-NEXT: call i8* @llvm.coro.promise(i8* %[[FRAME4]], i32 48, i1 false)
+ // CHECK-NEXT: call i8* @llvm.coro.promise(i8* %[[FRAME]], i32 48, i1 false)
__builtin_coro_promise(__builtin_coro_frame(), 48, 0);
- // CHECK-NEXT: %[[FRAME5:.+]] = call i8* @llvm.coro.frame()
- // CHECK-NEXT: call i8* @llvm.coro.free(token %[[COROID]], i8* %[[FRAME5]])
+ // CHECK-NEXT: call i8* @llvm.coro.free(token %[[COROID]], i8* %[[FRAME]])
__builtin_coro_free(__builtin_coro_frame());
- // CHECK-NEXT: %[[FRAME6:.+]] = call i8* @llvm.coro.frame()
- // CHECK-NEXT: call i1 @llvm.coro.end(i8* %[[FRAME6]], i1 false)
+ // CHECK-NEXT: call i1 @llvm.coro.end(i8* %[[FRAME]], i1 false)
__builtin_coro_end(__builtin_coro_frame(), 0);
// CHECK-NEXT: call i8 @llvm.coro.suspend(token none, i1 true)
Index: test/CodeGenCoroutines/coro-await.cpp
===
--- test/CodeGenCoroutines/coro-await.cpp
+++ test/CodeGenCoroutines/coro-await.cpp
@@ -40,6 +40,7 @@
// CHECK-LABEL: f0(
extern "C" void f0() {
+ // CHECK: %[[FRAME:.+]] = call i8* @llvm.coro.begin(
co_await suspend_always{};
// See if we need to suspend:
@@ -54,7 +55,6 @@
// ---
// Build the coroutine handle and pass it to await_suspend
// ---
- // CHECK: %[[FRAME:.+]] = call i8* @llvm.coro.frame()
// CHECK: call i8* @_ZNSt12experimental16coroutine_handleINS_16coroutine_traitsIJvEE12promise_typeEE12from_addressEPv(i8* %[[FRAME]])
// ... many lines of code to coerce coroutine_handle into an i8* scalar
// CHECK: %[[CH:.+]] = load i8*, i8** %{{.+}}
@@ -100,8 +100,9 @@
// CHECK-LABEL: f1(
extern "C" void f1(int) {
- co_yield 42;
// CHECK: %[[PROMISE:.+]] = alloca %"struct.std::experimental::coroutine_traits::promise_type"
+ // CHECK: %[[FRAME:.+]] = call i8* @llvm.coro.begin(
+ co_yield 42;
// CHECK: call void @_ZNSt12experimental16coroutine_traitsIJviEE12promise_type11yield_valueEi(%struct.suspend_maybe* sret %[[AWAITER:.+]], %"struct.std::experimental::coroutine_traits::promise_type"* %[[PROMISE]], i32 42)
// See if we need to suspend:
@@ -116,7 +117,6 @@
// ---
// Build the coroutine handle and pass it to await_suspend
// ---
- // CHECK: %[[FRAME:.+]] = call i8* @llvm.coro.frame()
// CHECK: call i8* @_ZNSt12experimental16coroutine_handleINS_16coroutine_traitsIJviEE12promise_typeEE12from_addressEPv(i8* %[[FRAME]])
// ... many lines of code to coerce coroutine_handle into an i8* scalar
// CHECK: %[[CH:.+]] = load i8*, i8** %{{.+}}
Index: test/CodeGenCoroutines/coro-alloc.cpp
===
--- test/CodeGenCoroutines/coro-alloc.cpp
+++ test/CodeGenCoroutines/coro-alloc.cpp
@@ -53,9 +53,8 @@
// CHECK: [[InitBB]]:
// CHECK: