From 5faba87938779c595f2b4e40f933bae6571bc421 Mon Sep 17 00:00:00 2001 From: Xun Li Date: Sun, 18 Apr 2021 17:20:02 -0700 Subject: [PATCH] Revert "[Coroutines] Set presplit attribute in Clang instead of CoroEarly pass" This reverts commit fa6b54c44ab1d5f579304eadb7ac8bd7e72d0e77. The commited patch broke mlir tests. It seems that mlir tests depend on coroutine function properties set in CoroEarly pass. --- clang/lib/CodeGen/CGCoroutine.cpp | 2 - .../coro-always-inline-resume.cpp | 54 ---------- .../test/CodeGenCoroutines/coro-always-inline.cpp | 114 +++++++++------------ llvm/lib/Transforms/Coroutines/CoroEarly.cpp | 1 + llvm/test/Transforms/Coroutines/coro-debug-O2.ll | 2 +- .../Coroutines/coro-debug-frame-variable.ll | 2 +- llvm/test/Transforms/Coroutines/coro-split-01.ll | 2 +- .../Transforms/Coroutines/coro-split-recursive.ll | 2 +- llvm/test/Transforms/Coroutines/ex0.ll | 2 +- llvm/test/Transforms/Coroutines/ex1.ll | 2 +- llvm/test/Transforms/Coroutines/ex2.ll | 2 +- llvm/test/Transforms/Coroutines/ex3.ll | 2 +- llvm/test/Transforms/Coroutines/ex4.ll | 2 +- llvm/test/Transforms/Coroutines/ex5.ll | 2 +- llvm/test/Transforms/Coroutines/phi-coro-end.ll | 2 +- llvm/test/Transforms/Coroutines/restart-trigger.ll | 2 +- 16 files changed, 63 insertions(+), 132 deletions(-) delete mode 100644 clang/test/CodeGenCoroutines/coro-always-inline-resume.cpp diff --git a/clang/lib/CodeGen/CGCoroutine.cpp b/clang/lib/CodeGen/CGCoroutine.cpp index fcf8fe0..ca071d3 100644 --- a/clang/lib/CodeGen/CGCoroutine.cpp +++ b/clang/lib/CodeGen/CGCoroutine.cpp @@ -558,8 +558,6 @@ void CodeGenFunction::EmitCoroutineBody(const CoroutineBodyStmt &S) { CurCoro.Data->SuspendBB = RetBB; assert(ShouldEmitLifetimeMarkers && "Must emit lifetime intrinsics for coroutines"); - // CORO_PRESPLIT_ATTR = UNPREPARED_FOR_SPLIT - CurFn->addFnAttr("coroutine.presplit", "0"); // Backend is allowed to elide memory allocations, to help it, emit // auto mem = coro.alloc() ? 0 : ... allocation code ...; diff --git a/clang/test/CodeGenCoroutines/coro-always-inline-resume.cpp b/clang/test/CodeGenCoroutines/coro-always-inline-resume.cpp deleted file mode 100644 index e4aa14a..0000000 --- a/clang/test/CodeGenCoroutines/coro-always-inline-resume.cpp +++ /dev/null @@ -1,54 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fcoroutines-ts \ -// RUN: -fexperimental-new-pass-manager -O0 %s -o - | FileCheck %s -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fcoroutines-ts \ -// RUN: -fexperimental-new-pass-manager -fno-inline -O0 %s -o - | FileCheck %s - -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fcoroutines-ts \ -// RUN: -O0 %s -o - | FileCheck %s -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fcoroutines-ts \ -// RUN: -fno-inline -O0 %s -o - | FileCheck %s - -namespace std { -namespace experimental { - -struct handle {}; - -struct awaitable { - bool await_ready() noexcept { return true; } - // CHECK-NOT: await_suspend - inline void __attribute__((__always_inline__)) await_suspend(handle) noexcept {} - bool await_resume() noexcept { return true; } -}; - -template -struct coroutine_handle { - static handle from_address(void *address) noexcept { return {}; } -}; - -template -struct coroutine_traits { - struct promise_type { - awaitable initial_suspend() { return {}; } - awaitable final_suspend() noexcept { return {}; } - void return_void() {} - T get_return_object() { return T(); } - void unhandled_exception() {} - }; -}; -} // namespace experimental -} // namespace std - -// CHECK-LABEL: @_Z3foov -// CHECK-LABEL: entry: -// CHECK-NEXT: %this.addr.i{{[0-9]*}} = alloca %"struct.std::experimental::awaitable"*, align 8 -// CHECK-NEXT: %this.addr.i{{[0-9]*}} = alloca %"struct.std::experimental::awaitable"*, align 8 -// CHECK: [[CAST0:%[0-9]+]] = bitcast %"struct.std::experimental::awaitable"** %this.addr.i{{[0-9]*}} to i8* -// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[CAST0]]) -// CHECK: [[CAST1:%[0-9]+]] = bitcast %"struct.std::experimental::awaitable"** %this.addr.i{{[0-9]*}} to i8* -// CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[CAST1]]) - -// CHECK: [[CAST2:%[0-9]+]] = bitcast %"struct.std::experimental::awaitable"** %this.addr.i{{[0-9]*}} to i8* -// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[CAST2]]) -// CHECK: [[CAST3:%[0-9]+]] = bitcast %"struct.std::experimental::awaitable"** %this.addr.i{{[0-9]*}} to i8* -// CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[CAST3]]) -void foo() { co_return; } diff --git a/clang/test/CodeGenCoroutines/coro-always-inline.cpp b/clang/test/CodeGenCoroutines/coro-always-inline.cpp index 6ba5a6f..e4aa14a 100644 --- a/clang/test/CodeGenCoroutines/coro-always-inline.cpp +++ b/clang/test/CodeGenCoroutines/coro-always-inline.cpp @@ -1,68 +1,54 @@ -// RUN: %clang -cc1 -triple x86_64-unknown-linux-gnu -std=c++2a %s -emit-llvm -disable-llvm-passes -o - | FileCheck %s -// RUN: %clang -cc1 -triple x86_64-unknown-linux-gnu -std=c++2a %s -emit-llvm -disable-llvm-passes -o - | opt -always-inline -S | FileCheck --check-prefix=INLINE %s - -#include "Inputs/coroutine.h" - -namespace coro = std::experimental::coroutines_v1; - -class task { -public: - class promise_type { - public: - task get_return_object() noexcept; - coro::suspend_always initial_suspend() noexcept; - void return_void() noexcept; - void unhandled_exception() noexcept; - - struct final_awaiter { - bool await_ready() noexcept; - void await_suspend(coro::coroutine_handle h) noexcept; - void await_resume() noexcept; - }; - - final_awaiter final_suspend() noexcept; - - coro::coroutine_handle<> continuation; - }; - - task(task &&t) noexcept; - ~task(); +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fcoroutines-ts \ +// RUN: -fexperimental-new-pass-manager -O0 %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fcoroutines-ts \ +// RUN: -fexperimental-new-pass-manager -fno-inline -O0 %s -o - | FileCheck %s + +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fcoroutines-ts \ +// RUN: -O0 %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fcoroutines-ts \ +// RUN: -fno-inline -O0 %s -o - | FileCheck %s + +namespace std { +namespace experimental { + +struct handle {}; + +struct awaitable { + bool await_ready() noexcept { return true; } + // CHECK-NOT: await_suspend + inline void __attribute__((__always_inline__)) await_suspend(handle) noexcept {} + bool await_resume() noexcept { return true; } +}; - class awaiter { - public: - bool await_ready() noexcept; - void await_suspend(coro::coroutine_handle<> continuation) noexcept; - void await_resume() noexcept; +template +struct coroutine_handle { + static handle from_address(void *address) noexcept { return {}; } +}; - private: - friend task; - explicit awaiter(coro::coroutine_handle h) noexcept; - coro::coroutine_handle coro_; +template +struct coroutine_traits { + struct promise_type { + awaitable initial_suspend() { return {}; } + awaitable final_suspend() noexcept { return {}; } + void return_void() {} + T get_return_object() { return T(); } + void unhandled_exception() {} }; - - awaiter operator co_await() &&noexcept; - -private: - explicit task(coro::coroutine_handle h) noexcept; - coro::coroutine_handle coro_; }; - -task cee(); - -__attribute__((always_inline)) inline task bar() { - co_await cee(); - co_return; -} - -task foo() { - co_await bar(); - co_return; -} - -// check that Clang front-end will tag bar with both alwaysinline and coroutine presplit -// CHECK: define linkonce_odr void @_Z3barv({{.*}}) #[[ATTR:[0-9]+]] {{.*}} -// CHECK: attributes #[[ATTR]] = { alwaysinline {{.*}} "coroutine.presplit"="0" {{.*}}} - -// check that bar is not inlined even it's marked as always_inline -// INLINE-LABEL: define dso_local void @_Z3foov( -// INLINE: call void @_Z3barv( +} // namespace experimental +} // namespace std + +// CHECK-LABEL: @_Z3foov +// CHECK-LABEL: entry: +// CHECK-NEXT: %this.addr.i{{[0-9]*}} = alloca %"struct.std::experimental::awaitable"*, align 8 +// CHECK-NEXT: %this.addr.i{{[0-9]*}} = alloca %"struct.std::experimental::awaitable"*, align 8 +// CHECK: [[CAST0:%[0-9]+]] = bitcast %"struct.std::experimental::awaitable"** %this.addr.i{{[0-9]*}} to i8* +// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[CAST0]]) +// CHECK: [[CAST1:%[0-9]+]] = bitcast %"struct.std::experimental::awaitable"** %this.addr.i{{[0-9]*}} to i8* +// CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[CAST1]]) + +// CHECK: [[CAST2:%[0-9]+]] = bitcast %"struct.std::experimental::awaitable"** %this.addr.i{{[0-9]*}} to i8* +// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[CAST2]]) +// CHECK: [[CAST3:%[0-9]+]] = bitcast %"struct.std::experimental::awaitable"** %this.addr.i{{[0-9]*}} to i8* +// CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[CAST3]]) +void foo() { co_return; } diff --git a/llvm/lib/Transforms/Coroutines/CoroEarly.cpp b/llvm/lib/Transforms/Coroutines/CoroEarly.cpp index 0185f8d..1660e41 100644 --- a/llvm/lib/Transforms/Coroutines/CoroEarly.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroEarly.cpp @@ -179,6 +179,7 @@ bool Lowerer::lowerEarlyIntrinsics(Function &F) { // with a coroutine attribute. if (auto *CII = cast(&I)) { if (CII->getInfo().isPreSplit()) { + F.addFnAttr(CORO_PRESPLIT_ATTR, UNPREPARED_FOR_SPLIT); setCannotDuplicate(CII); CII->setCoroutineSelf(); CoroId = cast(&I); diff --git a/llvm/test/Transforms/Coroutines/coro-debug-O2.ll b/llvm/test/Transforms/Coroutines/coro-debug-O2.ll index 7777c94..0ab8cfe 100644 --- a/llvm/test/Transforms/Coroutines/coro-debug-O2.ll +++ b/llvm/test/Transforms/Coroutines/coro-debug-O2.ll @@ -9,7 +9,7 @@ ; CHECK: ![[PROMISEVAR_RESUME]] = !DILocalVariable(name: "__promise" %promise_type = type { i32, i32, double } -define void @f() "coroutine.presplit"="0" !dbg !8 { +define void @f() !dbg !8 { entry: %__promise = alloca %promise_type, align 8 %0 = bitcast %promise_type* %__promise to i8* diff --git a/llvm/test/Transforms/Coroutines/coro-debug-frame-variable.ll b/llvm/test/Transforms/Coroutines/coro-debug-frame-variable.ll index 9dbda92..433488b 100644 --- a/llvm/test/Transforms/Coroutines/coro-debug-frame-variable.ll +++ b/llvm/test/Transforms/Coroutines/coro-debug-frame-variable.ll @@ -63,7 +63,7 @@ ; CHECK: ![[IVAR_RESUME]] = !DILocalVariable(name: "i" ; CHECK: ![[JVAR_RESUME]] = !DILocalVariable(name: "j" ; CHECK: ![[JDBGLOC_RESUME]] = !DILocation(line: 32, column: 7, scope: ![[RESUME_SCOPE]]) -define void @f() "coroutine.presplit"="0" { +define void @f() { entry: %__promise = alloca i8, align 8 %i = alloca i32, align 4 diff --git a/llvm/test/Transforms/Coroutines/coro-split-01.ll b/llvm/test/Transforms/Coroutines/coro-split-01.ll index 04d8fbd..ca9faa5 100644 --- a/llvm/test/Transforms/Coroutines/coro-split-01.ll +++ b/llvm/test/Transforms/Coroutines/coro-split-01.ll @@ -2,7 +2,7 @@ ; RUN: opt < %s -S -enable-coroutines -O2 | FileCheck %s ; RUN: opt < %s -S -enable-coroutines -passes='default' | FileCheck %s -define i8* @f() "coroutine.presplit"="0" { +define i8* @f() { entry: %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null) %need.dyn.alloc = call i1 @llvm.coro.alloc(token %id) diff --git a/llvm/test/Transforms/Coroutines/coro-split-recursive.ll b/llvm/test/Transforms/Coroutines/coro-split-recursive.ll index 907ec1b..0b6909f 100644 --- a/llvm/test/Transforms/Coroutines/coro-split-recursive.ll +++ b/llvm/test/Transforms/Coroutines/coro-split-recursive.ll @@ -13,7 +13,7 @@ declare i8 @llvm.coro.suspend(token, i1) ; CHECK: call void @foo() ; CHECK-LABEL: define {{.*}}void @foo.destroy( -define void @foo() "coroutine.presplit"="0" { +define void @foo() { entry: %__promise = alloca i32, align 8 %0 = bitcast i32* %__promise to i8* diff --git a/llvm/test/Transforms/Coroutines/ex0.ll b/llvm/test/Transforms/Coroutines/ex0.ll index 9ca29fc..de57523 100644 --- a/llvm/test/Transforms/Coroutines/ex0.ll +++ b/llvm/test/Transforms/Coroutines/ex0.ll @@ -2,7 +2,7 @@ ; RUN: opt < %s -enable-coroutines -O2 -preserve-alignment-assumptions-during-inlining=false -S | FileCheck %s ; RUN: opt < %s -enable-coroutines -aa-pipeline=basic-aa -passes='default' -preserve-alignment-assumptions-during-inlining=false -S | FileCheck %s -define i8* @f(i32 %n) "coroutine.presplit"="0" { +define i8* @f(i32 %n) { entry: %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null) %size = call i32 @llvm.coro.size.i32() diff --git a/llvm/test/Transforms/Coroutines/ex1.ll b/llvm/test/Transforms/Coroutines/ex1.ll index 13276ef..42f6038 100644 --- a/llvm/test/Transforms/Coroutines/ex1.ll +++ b/llvm/test/Transforms/Coroutines/ex1.ll @@ -2,7 +2,7 @@ ; RUN: opt < %s -O2 -enable-coroutines -preserve-alignment-assumptions-during-inlining=false -S | FileCheck %s ; RUN: opt < %s -aa-pipeline=basic-aa -passes='default' -enable-coroutines -preserve-alignment-assumptions-during-inlining=false -S | FileCheck %s -define i8* @f(i32 %n) "coroutine.presplit"="0" { +define i8* @f(i32 %n) { entry: %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null) %size = call i32 @llvm.coro.size.i32() diff --git a/llvm/test/Transforms/Coroutines/ex2.ll b/llvm/test/Transforms/Coroutines/ex2.ll index 5f4431a..584bc90 100644 --- a/llvm/test/Transforms/Coroutines/ex2.ll +++ b/llvm/test/Transforms/Coroutines/ex2.ll @@ -2,7 +2,7 @@ ; RUN: opt < %s -O2 -enable-coroutines -S | FileCheck %s ; RUN: opt < %s -passes='default' -enable-coroutines -S | FileCheck %s -define i8* @f(i32 %n) "coroutine.presplit"="0" { +define i8* @f(i32 %n) { entry: %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null) %need.dyn.alloc = call i1 @llvm.coro.alloc(token %id) diff --git a/llvm/test/Transforms/Coroutines/ex3.ll b/llvm/test/Transforms/Coroutines/ex3.ll index a822a69..85cf53f 100644 --- a/llvm/test/Transforms/Coroutines/ex3.ll +++ b/llvm/test/Transforms/Coroutines/ex3.ll @@ -2,7 +2,7 @@ ; RUN: opt < %s -O2 -enable-coroutines -S | FileCheck %s ; RUN: opt < %s -aa-pipeline=basic-aa -passes='default' -enable-coroutines -S | FileCheck %s -define i8* @f(i32 %n) "coroutine.presplit"="0" { +define i8* @f(i32 %n) { entry: %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null) %size = call i32 @llvm.coro.size.i32() diff --git a/llvm/test/Transforms/Coroutines/ex4.ll b/llvm/test/Transforms/Coroutines/ex4.ll index a519f4e..e60bc2c 100644 --- a/llvm/test/Transforms/Coroutines/ex4.ll +++ b/llvm/test/Transforms/Coroutines/ex4.ll @@ -2,7 +2,7 @@ ; RUN: opt < %s -O2 -enable-coroutines -S | FileCheck %s ; RUN: opt < %s -passes='default' -enable-coroutines -S | FileCheck %s -define i8* @f(i32 %n) "coroutine.presplit"="0" { +define i8* @f(i32 %n) { entry: %promise = alloca i32 %pv = bitcast i32* %promise to i8* diff --git a/llvm/test/Transforms/Coroutines/ex5.ll b/llvm/test/Transforms/Coroutines/ex5.ll index 2cab0ac..dd56650 100644 --- a/llvm/test/Transforms/Coroutines/ex5.ll +++ b/llvm/test/Transforms/Coroutines/ex5.ll @@ -2,7 +2,7 @@ ; RUN: opt < %s -O2 -enable-coroutines -preserve-alignment-assumptions-during-inlining=false -S | FileCheck %s ; RUN: opt < %s -aa-pipeline=basic-aa -passes='default' -enable-coroutines -preserve-alignment-assumptions-during-inlining=false -S | FileCheck %s -define i8* @f(i32 %n) "coroutine.presplit"="0" { +define i8* @f(i32 %n) { entry: %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null) %size = call i32 @llvm.coro.size.i32() diff --git a/llvm/test/Transforms/Coroutines/phi-coro-end.ll b/llvm/test/Transforms/Coroutines/phi-coro-end.ll index 39a3410..d7ee2f5 100644 --- a/llvm/test/Transforms/Coroutines/phi-coro-end.ll +++ b/llvm/test/Transforms/Coroutines/phi-coro-end.ll @@ -2,7 +2,7 @@ ; RUN: opt < %s -O2 -enable-coroutines -S | FileCheck %s ; RUN: opt < %s -aa-pipeline=basic-aa -passes='default' -enable-coroutines -S | FileCheck %s -define i8* @f(i32 %n) "coroutine.presplit"="0" { +define i8* @f(i32 %n) { entry: %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null) %size = call i32 @llvm.coro.size.i32() diff --git a/llvm/test/Transforms/Coroutines/restart-trigger.ll b/llvm/test/Transforms/Coroutines/restart-trigger.ll index 8e51095..ca74f92 100644 --- a/llvm/test/Transforms/Coroutines/restart-trigger.ll +++ b/llvm/test/Transforms/Coroutines/restart-trigger.ll @@ -12,7 +12,7 @@ ; CHECK: CoroSplit: Processing coroutine 'f' state: 0 ; CHECK-NEXT: CoroSplit: Processing coroutine 'f' state: 1 -define void @f() "coroutine.presplit"="0" { +define void @f() { %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null) %size = call i32 @llvm.coro.size.i32() %alloc = call i8* @malloc(i32 %size) -- 2.7.4