[Coroutines] Convert coroutine.presplit to enum attr

This is required by @nikic in https://reviews.llvm.org/D127383 to
decrease the cost to check whether a function is a coroutine and this
fixes a FIXME too.

Reviewed By: rjmccall, ezhulenev

Differential Revision: https://reviews.llvm.org/D127471
This commit is contained in:
Chuanqi Xu 2022-06-10 11:37:09 +08:00
parent a2232da2a5
commit 735e6c40b5
100 changed files with 132 additions and 138 deletions

View File

@ -654,9 +654,8 @@ void CodeGenFunction::EmitCoroutineBody(const CoroutineBodyStmt &S) {
EmitStmt(Ret);
}
// LLVM require the frontend to add the function attribute. See
// Coroutines.rst.
CurFn->addFnAttr("coroutine.presplit", "0");
// LLVM require the frontend to mark the coroutine.
CurFn->setPresplitCoroutine();
}
// Emit coroutine intrinsic and patch up arguments of the token type.

View File

@ -14,7 +14,7 @@ struct coro {
};
// CHECK: void @_Z3foov() #[[FOO_ATTR_NUM:[0-9]+]]
// CHECK: attributes #[[FOO_ATTR_NUM]] = { {{.*}} "coroutine.presplit"="0"
// CHECK: attributes #[[FOO_ATTR_NUM]] = { {{.*}} presplitcoroutine
coro foo() {
co_await suspend_always{};
}

View File

@ -1201,7 +1201,7 @@ duplicated.
A frontend should emit exactly one `coro.id` intrinsic per coroutine.
A frontend should emit function attribute `"coroutine.presplit"` for the coroutine.
A frontend should emit function attribute `presplitcoroutine` for the coroutine.
.. _coro.id.async:
@ -1242,7 +1242,7 @@ Semantics:
A frontend should emit exactly one `coro.id.async` intrinsic per coroutine.
A frontend should emit function attribute `"coroutine.presplit"` for the coroutine.
A frontend should emit function attribute `presplitcoroutine` for the coroutine.
.. _coro.id.retcon:
@ -1299,7 +1299,7 @@ be used to deallocate memory. It must take a pointer and return ``void``.
Semantics:
""""""""""
A frontend should emit function attribute `"coroutine.presplit"` for the coroutine.
A frontend should emit function attribute `presplitcoroutine` for the coroutine.
'llvm.coro.id.retcon.once' Intrinsic
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -1325,7 +1325,7 @@ coroutine's return type.
Semantics:
""""""""""
A frontend should emit function attribute `"coroutine.presplit"` for the coroutine.
A frontend should emit function attribute `presplitcoroutine` for the coroutine.
.. _coro.end:

View File

@ -685,6 +685,7 @@ enum AttributeKindCodes {
ATTR_KIND_ALLOC_ALIGN = 80,
ATTR_KIND_ALLOCATED_POINTER = 81,
ATTR_KIND_ALLOC_KIND = 82,
ATTR_KIND_PRESPLIT_COROUTINE = 83,
};
enum ComdatSelectionKindCodes {

View File

@ -303,6 +303,9 @@ def ZExt : EnumAttr<"zeroext", [ParamAttr, RetAttr]>;
/// Function is required to make Forward Progress.
def MustProgress : EnumAttr<"mustprogress", [FnAttr]>;
/// Function is a presplit coroutine.
def PresplitCoroutine : EnumAttr<"presplitcoroutine", [FnAttr]>;
/// Target-independent string attributes.
def LessPreciseFPMAD : StrBoolAttr<"less-precise-fpmad">;
def NoInfsFPMath : StrBoolAttr<"no-infs-fp-math">;

View File

@ -484,11 +484,12 @@ public:
return AttributeSets.getParamDereferenceableOrNullBytes(ArgNo);
}
/// A function will have the "coroutine.presplit" attribute if it's
/// a coroutine and has not gone through full CoroSplit pass.
/// Determine if the function is presplit coroutine.
bool isPresplitCoroutine() const {
return hasFnAttribute("coroutine.presplit");
return hasFnAttribute(Attribute::PresplitCoroutine);
}
void setPresplitCoroutine() { addFnAttr(Attribute::PresplitCoroutine); }
void setSplittedCoroutine() { removeFnAttr(Attribute::PresplitCoroutine); }
/// Determine if the function does not access memory.
bool doesNotAccessMemory() const {

View File

@ -1634,6 +1634,8 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) {
return Attribute::MustProgress;
case bitc::ATTR_KIND_HOT:
return Attribute::Hot;
case bitc::ATTR_KIND_PRESPLIT_COROUTINE:
return Attribute::PresplitCoroutine;
}
}

View File

@ -774,6 +774,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {
return bitc::ATTR_KIND_BYREF;
case Attribute::MustProgress:
return bitc::ATTR_KIND_MUSTPROGRESS;
case Attribute::PresplitCoroutine:
return bitc::ATTR_KIND_PRESPLIT_COROUTINE;
case Attribute::EndAttrKinds:
llvm_unreachable("Can not encode end-attribute kinds marker.");
case Attribute::None:

View File

@ -45,8 +45,7 @@ static void lowerSubFn(IRBuilder<> &Builder, CoroSubFnInst *SubFn) {
}
bool Lowerer::lower(Function &F) {
bool IsPrivateAndUnprocessed =
F.hasFnAttribute(CORO_PRESPLIT_ATTR) && F.hasLocalLinkage();
bool IsPrivateAndUnprocessed = F.isPresplitCoroutine() && F.hasLocalLinkage();
bool Changed = false;
for (Instruction &I : llvm::make_early_inc_range(instructions(F))) {

View File

@ -180,7 +180,7 @@ void Lowerer::lowerEarlyIntrinsics(Function &F) {
case Intrinsic::coro_id:
if (auto *CII = cast<CoroIdInst>(&I)) {
if (CII->getInfo().isPreSplit()) {
assert(F.hasFnAttribute(CORO_PRESPLIT_ATTR) &&
assert(F.isPresplitCoroutine() &&
"The frontend uses Swtich-Resumed ABI should emit "
"\"coroutine.presplit\" attribute for the coroutine.");
setCannotDuplicate(CII);
@ -192,9 +192,7 @@ void Lowerer::lowerEarlyIntrinsics(Function &F) {
case Intrinsic::coro_id_retcon:
case Intrinsic::coro_id_retcon_once:
case Intrinsic::coro_id_async:
// TODO: Remove the line once we support it in the corresponding
// frontend.
F.addFnAttr(CORO_PRESPLIT_ATTR);
F.setPresplitCoroutine();
break;
case Intrinsic::coro_resume:
lowerResumeOrDestroy(*CB, CoroSubFnInst::ResumeIndex);

View File

@ -20,15 +20,6 @@ class CallGraph;
class CallGraphSCC;
class PassRegistry;
// CoroEarly pass marks every function that has coro.begin with a string
// attribute "coroutine.presplit". CoroSplit pass would processes the
// function marked as "coroutine.presplit" only.
//
// FIXME: Refactor these attributes as LLVM attributes instead of string
// attributes since these attributes are already used outside LLVM's
// coroutine module.
#define CORO_PRESPLIT_ATTR "coroutine.presplit"
namespace coro {
bool declaresAnyIntrinsic(const Module &M);

View File

@ -2064,7 +2064,7 @@ PreservedAnalyses CoroSplitPass::run(LazyCallGraph::SCC &C,
// Find coroutines for processing.
SmallVector<LazyCallGraph::Node *> Coroutines;
for (LazyCallGraph::Node &N : C)
if (N.getFunction().hasFnAttribute(CORO_PRESPLIT_ATTR))
if (N.getFunction().isPresplitCoroutine())
Coroutines.push_back(&N);
if (Coroutines.empty() && PrepareFns.empty())
@ -2081,7 +2081,7 @@ PreservedAnalyses CoroSplitPass::run(LazyCallGraph::SCC &C,
Function &F = N->getFunction();
LLVM_DEBUG(dbgs() << "CoroSplit: Processing coroutine '" << F.getName()
<< "\n");
F.removeFnAttr(CORO_PRESPLIT_ATTR);
F.setSplittedCoroutine();
SmallVector<Function *, 4> Clones;
const coro::Shape Shape = splitCoroutine(F, Clones, OptimizeFrame);

View File

@ -2,7 +2,7 @@
; coro.begin.
; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
define nonnull i8* @f(i32 %n) "coroutine.presplit"="1" {
define nonnull i8* @f(i32 %n) presplitcoroutine {
; CHECK-LABEL: @f(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[ID:%.*]] = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* bitcast ([3 x void (%f.Frame*)*]* @f.resumers to i8*))

View File

@ -1,7 +1,7 @@
; Tests that the coro.align intrinsic could be lowered to correct alignment
; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
define i8* @f() "coroutine.presplit"="1" {
define i8* @f() presplitcoroutine {
entry:
%x = alloca i64, align 16
%y = alloca i64

View File

@ -1,7 +1,7 @@
; Tests that the coro.align intrinsic could be lowered to correct alignment
; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
define i8* @f() "coroutine.presplit"="1" {
define i8* @f() presplitcoroutine {
entry:
%x = alloca i64, align 16
%y = alloca i32, align 32

View File

@ -1,7 +1,7 @@
; Tests that the coro.align intrinsic could be lowered to correct alignment
; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
define i8* @f() "coroutine.presplit"="1" {
define i8* @f() presplitcoroutine {
entry:
%x = alloca i1, align 64
%y = alloca i64, align 32

View File

@ -1,7 +1,7 @@
; Tests that the coro.align intrinsic could be lowered to correct alignment
; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
define i8* @f() "coroutine.presplit"="1" {
define i8* @f() presplitcoroutine {
entry:
%x = alloca i1, align 64
%y = alloca i64

View File

@ -1,7 +1,7 @@
; Tests that the coro.align intrinsic could be lowered to correct alignment
; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
define i8* @f() "coroutine.presplit"="1" {
define i8* @f() presplitcoroutine {
entry:
%id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
%size = call i32 @llvm.coro.size.i32()

View File

@ -1,7 +1,7 @@
; Tests that the coro.align intrinsic could be lowered to correct alignment
; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
define i8* @f() "coroutine.presplit"="1" {
define i8* @f() presplitcoroutine {
entry:
%x = alloca i64
%y = alloca i64

View File

@ -3,7 +3,7 @@
; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
; using copy of this (as it would happen under -O0)
define i8* @f_copy(i64 %this_arg) "coroutine.presplit"="1" {
define i8* @f_copy(i64 %this_arg) presplitcoroutine {
entry:
%this.addr = alloca i64
store i64 %this_arg, i64* %this.addr

View File

@ -3,7 +3,7 @@
; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
; using this directly (as it would happen under -O2)
define i8* @f_direct(i64 %this) "coroutine.presplit"="1" {
define i8* @f_direct(i64 %this) presplitcoroutine {
entry:
%id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
%size = call i32 @llvm.coro.size.i32()

View File

@ -2,7 +2,7 @@
; if their aliases are used across suspension points through PHINode.
; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
define i8* @f(i1 %n) "coroutine.presplit"="1" {
define i8* @f(i1 %n) presplitcoroutine {
entry:
%x = alloca i64
%y = alloca i64

View File

@ -2,7 +2,7 @@
; the alloac will be put on the frame.
; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
define i8* @f() "coroutine.presplit"="1" {
define i8* @f() presplitcoroutine {
entry:
%x = alloca i64
%y = alloca i32*

View File

@ -1,7 +1,7 @@
; Tests that allocas escaped through function calls will live on the frame.
; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
define i8* @f() "coroutine.presplit"="1" {
define i8* @f() presplitcoroutine {
entry:
%x = alloca i64
%y = alloca i64

View File

@ -2,7 +2,7 @@
; if their aliases are used across suspension points through PHINode.
; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
define i8* @f(i1 %n) "coroutine.presplit"="1" {
define i8* @f(i1 %n) presplitcoroutine {
entry:
%x = alloca i64
br i1 %n, label %flag_true, label %flag_false

View File

@ -2,7 +2,7 @@
; live on the frame are properly moved to the .resume function.
; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
define i8* @f() "coroutine.presplit"="1" {
define i8* @f() presplitcoroutine {
entry:
%id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
%size = call i32 @llvm.coro.size.i32()

View File

@ -4,7 +4,7 @@
%handle = type { i8* }
define i8* @f() "coroutine.presplit"="1" {
define i8* @f() presplitcoroutine {
entry:
%0 = alloca %"handle", align 8
%1 = alloca %"handle"*, align 8

View File

@ -2,7 +2,7 @@
; if their aliases are used across suspension points through PHINode.
; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
define i8* @f(i1 %n) "coroutine.presplit"="1" {
define i8* @f(i1 %n) presplitcoroutine {
entry:
%x = alloca i64
%y = alloca i64

View File

@ -11,7 +11,7 @@ declare void @consume.i8.array(%i8.array*)
; The lifetime of testval starts and ends before coro.suspend. Even though consume.i8.array
; might capture it, we can safely say it won't live across suspension.
define void @foo() "coroutine.presplit"="1" {
define void @foo() presplitcoroutine {
entry:
%testval = alloca %i8.array
%cast = getelementptr inbounds %i8.array, %i8.array* %testval, i64 0, i32 0, i64 0
@ -39,7 +39,7 @@ exit:
; The lifetime of testval starts after coro.suspend. So it will never live across suspension
; points.
define void @bar() "coroutine.presplit"="1" {
define void @bar() presplitcoroutine {
entry:
%testval = alloca %i8.array
%cast = getelementptr inbounds %i8.array, %i8.array* %testval, i64 0, i32 0, i64 0

View File

@ -14,7 +14,7 @@ declare void @consume.i8(i8*)
; wouldn't live across suspend point.
; This test whether or not %testval would be put on the frame by ignoring the
; partial lifetime markers.
define void @foo(%i8.array** %to_store) "coroutine.presplit"="1" {
define void @foo(%i8.array** %to_store) presplitcoroutine {
entry:
%testval = alloca %i8.array
%subrange = getelementptr inbounds %i8.array, %i8.array* %testval, i64 0, i32 0, i64 50

View File

@ -62,7 +62,7 @@ entry:
; CHECK: store i64 2, i64* [[T4]]
; CHECK: store i64 3, i64* [[T9]]
define swiftcc void @my_async_function(i8* swiftasync %async.ctxt) "coroutine.presplit"="1" {
define swiftcc void @my_async_function(i8* swiftasync %async.ctxt) presplitcoroutine {
entry:
%tmp = alloca i64, align 8
%tmp2 = alloca i64, align 16

View File

@ -61,7 +61,7 @@ entry:
}
define swiftcc void @my_async_function(i8* swiftasync %async.ctxt, %async.task* %task, %async.actor* %actor) "coroutine.presplit"="1" !dbg !1 {
define swiftcc void @my_async_function(i8* swiftasync %async.ctxt, %async.task* %task, %async.actor* %actor) presplitcoroutine !dbg !1 {
entry:
%tmp = alloca { i64, i64 }, align 8
%vector = alloca <4 x double>, align 16
@ -203,7 +203,7 @@ define void @my_async_function_pa(i8* %ctxt, %async.task* %task, %async.actor* %
i32 128 ; Initial async context size without space for frame
}>
define swiftcc void @my_async_function2(%async.task* %task, %async.actor* %actor, i8* %async.ctxt) "coroutine.presplit"="1" "frame-pointer"="all" !dbg !6 {
define swiftcc void @my_async_function2(%async.task* %task, %async.actor* %actor, i8* %async.ctxt) presplitcoroutine "frame-pointer"="all" !dbg !6 {
entry:
%id = call token @llvm.coro.id.async(i32 128, i32 16, i32 2, i8* bitcast (<{i32, i32}>* @my_async_function2_fp to i8*))
@ -325,7 +325,7 @@ is_not_null:
ret void
}
define swiftcc void @dont_crash_on_cf(i8* %async.ctxt, %async.task* %task, %async.actor* %actor) "coroutine.presplit"="1" {
define swiftcc void @dont_crash_on_cf(i8* %async.ctxt, %async.task* %task, %async.actor* %actor) presplitcoroutine {
entry:
%id = call token @llvm.coro.id.async(i32 128, i32 16, i32 0,
i8* bitcast (<{i32, i32}>* @dont_crash_on_cf_fp to i8*))
@ -371,7 +371,7 @@ define swiftcc void @must_tail_call_return(i8* %async.ctxt, %async.task* %task,
ret void
}
define swiftcc void @multiple_coro_end_async(i8* %async.ctxt, %async.task* %task, %async.actor* %actor) "coroutine.presplit"="1" {
define swiftcc void @multiple_coro_end_async(i8* %async.ctxt, %async.task* %task, %async.actor* %actor) presplitcoroutine {
entry:
%id = call token @llvm.coro.id.async(i32 128, i32 16, i32 0,
i8* bitcast (<{i32, i32}>* @dont_crash_on_cf_fp to i8*))
@ -427,7 +427,7 @@ is_not_equal:
i32 64 ; Initial async context size without space for frame
}>
define swiftcc void @polymorphic_suspend_return(i8* swiftasync %async.ctxt, %async.task* %task, %async.actor* %actor) "coroutine.presplit"="1" {
define swiftcc void @polymorphic_suspend_return(i8* swiftasync %async.ctxt, %async.task* %task, %async.actor* %actor) presplitcoroutine {
entry:
%tmp = alloca { i64, i64 }, align 8
%proj.1 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %tmp, i64 0, i32 0
@ -496,7 +496,7 @@ entry:
i32 128 ; Initial async context size without space for frame
}>
define swiftcc void @no_coro_suspend(i8* %async.ctx) "coroutine.presplit"="1" {
define swiftcc void @no_coro_suspend(i8* %async.ctx) presplitcoroutine {
entry:
%some_alloca = alloca i64
%id = call token @llvm.coro.id.async(i32 128, i32 16, i32 0,
@ -523,7 +523,7 @@ entry:
declare void @do_with_swifterror(i64** swifterror)
define swiftcc void @no_coro_suspend_swifterror(i8* %async.ctx) "coroutine.presplit"="1" {
define swiftcc void @no_coro_suspend_swifterror(i8* %async.ctx) presplitcoroutine {
entry:
%some_alloca = alloca swifterror i64*
%id = call token @llvm.coro.id.async(i32 128, i32 16, i32 0,
@ -553,7 +553,7 @@ entry:
declare void @crash()
declare void @use(i8*)
define swiftcc void @undefined_coro_async_resume(i8 *%async.ctx) "coroutine.presplit"="1" {
define swiftcc void @undefined_coro_async_resume(i8 *%async.ctx) presplitcoroutine {
entry:
%id = call token @llvm.coro.id.async(i32 24, i32 16, i32 0, i8* bitcast (<{i32, i32}>* @undefined_coro_async_resume_fp to i8*))
%hdl = call i8* @llvm.coro.begin(token %id, i8* null)

View File

@ -113,7 +113,7 @@ declare void @_ZdlPv(i8*) local_unnamed_addr #8
; Function Attrs: argmemonly nounwind readonly
declare i8* @llvm.coro.free(token, i8* nocapture readonly) #1
attributes #0 = { noinline ssp uwtable mustprogress "coroutine.presplit"="1" "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="penryn" "target-features"="+cx16,+cx8,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "tune-cpu"="generic" }
attributes #0 = { noinline ssp uwtable mustprogress presplitcoroutine "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="penryn" "target-features"="+cx16,+cx8,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "tune-cpu"="generic" }
attributes #1 = { argmemonly nounwind readonly }
attributes #2 = { nounwind }
attributes #3 = { nobuiltin nofree allocsize(0) "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="penryn" "target-features"="+cx16,+cx8,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "tune-cpu"="generic" }

View File

@ -3,7 +3,7 @@
; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg<switch-range-to-icmp>,early-cse' -S | FileCheck %s
declare i32 @__CxxFrameHandler3(...)
define i8* @f2(i1 %val) "coroutine.presplit"="1" personality i32 (...)* @__CxxFrameHandler3 {
define i8* @f2(i1 %val) presplitcoroutine personality i32 (...)* @__CxxFrameHandler3 {
entry:
%id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
%valueA = call i32 @f();

View File

@ -5,7 +5,7 @@ target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
target triple = "i686-pc-windows-msvc"
; CHECK-LABEL: define void @f(
define void @f(i1 %cond) "coroutine.presplit"="1" personality i32 0 {
define void @f(i1 %cond) presplitcoroutine personality i32 0 {
entry:
%id = call token @llvm.coro.id(i32 8, i8* null, i8* null, i8* null)
%size = call i32 @llvm.coro.size.i32()

View File

@ -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() presplitcoroutine !dbg !8 {
entry:
%__promise = alloca %promise_type, align 8
%0 = bitcast %promise_type* %__promise to i8*

View File

@ -57,7 +57,7 @@ declare void @pi32(i32*)
declare void @pi64(i64*)
declare void @pdouble(double*)
define void @f(i32 %a, i32 %b, i64 %c, double %d) "coroutine.presplit"="0" !dbg !8 {
define void @f(i32 %a, i32 %b, i64 %c, double %d) presplitcoroutine !dbg !8 {
entry:
%__promise = alloca %promise_type, align 8
%0 = bitcast %promise_type* %__promise to i8*
@ -183,7 +183,7 @@ unreachable: ; preds = %after.coro.free
}
define void @bar(i32 %a, i64 %c, double %d) "coroutine.presplit"="0" !dbg !19 {
define void @bar(i32 %a, i64 %c, double %d) presplitcoroutine !dbg !19 {
entry:
%__promise = alloca %promise_type, align 8
%0 = bitcast %promise_type* %__promise to i8*

View File

@ -43,7 +43,7 @@
source_filename = "../llvm/test/Transforms/Coroutines/coro-debug-dbg.values-O2.ll"
declare void @consume(i32)
define void @f(i32 %i, i32 %j, i8* %ptr) "coroutine.presplit"="0" !dbg !8 {
define void @f(i32 %i, i32 %j, i8* %ptr) presplitcoroutine !dbg !8 {
entry:
%__promise = alloca i8, align 8
%x = alloca [10 x i32], align 16

View File

@ -13,7 +13,7 @@
source_filename = "../llvm/test/Transforms/Coroutines/coro-debug-dbg.values-O2.ll"
define void @f(i32 %i, i32 %j) "coroutine.presplit"="0" !dbg !8 {
define void @f(i32 %i, i32 %j) presplitcoroutine !dbg !8 {
entry:
%__promise = alloca i8, align 8
%x = alloca [10 x i32], align 16

View File

@ -19,7 +19,7 @@
source_filename = "../llvm/test/Transforms/Coroutines/coro-debug-dbg.values-O2.ll"
declare void @consume(i32)
define void @f(i32 %i, i32 %j) "coroutine.presplit"="0" !dbg !8 {
define void @f(i32 %i, i32 %j) presplitcoroutine !dbg !8 {
entry:
%__promise = alloca i8, align 8
%x = alloca [10 x i32], align 16

View File

@ -60,7 +60,7 @@
; CHECK-DAG: ![[IVAR_RESUME]] = !DILocalVariable(name: "i"
; CHECK-DAG: ![[JVAR_RESUME]] = !DILocalVariable(name: "j"
; CHECK-DAG: ![[JDBGLOC_RESUME]] = !DILocation(line: 32, column: 7, scope: ![[RESUME_SCOPE]])
define void @f() "coroutine.presplit"="0" {
define void @f() presplitcoroutine {
entry:
%__promise = alloca i8, align 8
%i = alloca i32, align 4

View File

@ -123,7 +123,7 @@ entry:
; Function Attrs: argmemonly nounwind readonly
declare i8* @llvm.coro.subfn.addr(i8* nocapture readonly, i8) #2
attributes #0 = { noinline nounwind "coroutine.presplit"="1" "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="none" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-features"="+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #0 = { noinline nounwind presplitcoroutine "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="none" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-features"="+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { nounwind readnone speculatable }
attributes #2 = { argmemonly nounwind readonly }
attributes #3 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="none" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-features"="+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }

View File

@ -5,7 +5,7 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
; CHECK-LABEL: define internal fastcc void @f.resume(
define void @f(i1 %cond) "coroutine.presplit"="1" personality i32 0 {
define void @f(i1 %cond) presplitcoroutine personality i32 0 {
entry:
%id = call token @llvm.coro.id(i32 16, i8* null, i8* null, i8* null)
%size = tail call i64 @llvm.coro.size.i64()

View File

@ -5,7 +5,7 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
; CHECK-LABEL: define internal fastcc void @g.resume(
define void @g(i1 %cond, i32 %x, i32 %y) "coroutine.presplit"="1" personality i32 0 {
define void @g(i1 %cond, i32 %x, i32 %y) presplitcoroutine personality i32 0 {
entry:
%id = call token @llvm.coro.id(i32 16, i8* null, i8* null, i8* null)
%size = tail call i64 @llvm.coro.size.i64()

View File

@ -5,7 +5,7 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
; CHECK-LABEL: define internal fastcc void @h.resume(
define void @h(i1 %cond, i32 %x, i32 %y) "coroutine.presplit"="1" personality i32 0 {
define void @h(i1 %cond, i32 %x, i32 %y) presplitcoroutine personality i32 0 {
entry:
%id = call token @llvm.coro.id(i32 16, i8* null, i8* null, i8* null)
%size = tail call i64 @llvm.coro.size.i64()

View File

@ -4,7 +4,7 @@
declare void @consume.double.ptr(double*)
declare void @consume.i32.ptr(i32*)
define i8* @f() "coroutine.presplit"="1" {
define i8* @f() presplitcoroutine {
entry:
%prefix = alloca double
%data = alloca i32, i32 4

View File

@ -5,7 +5,7 @@
declare void @consume(%struct.big_structure*)
; Function Attrs: noinline optnone uwtable
define i8* @f(i1 %cond) "coroutine.presplit"="1" {
define i8* @f(i1 %cond) presplitcoroutine {
entry:
%data = alloca %struct.big_structure, align 1
%data2 = alloca %struct.big_structure, align 1

View File

@ -6,7 +6,7 @@
%struct.big_structure = type { [500 x i8] }
declare i8* @malloc(i64)
declare void @consume(%struct.big_structure*)
define void @a(i1 zeroext %cond) "coroutine.presplit"="1" {
define void @a(i1 zeroext %cond) presplitcoroutine {
entry:
%__promise = alloca %"struct.task::promise_type", align 1
%a = alloca %struct.big_structure, align 1

View File

@ -8,7 +8,7 @@
declare i8* @malloc(i64)
declare void @consume(%struct.big_structure*)
declare void @consume.2(%struct.big_structure.2*)
define void @a(i1 zeroext %cond) "coroutine.presplit"="1" {
define void @a(i1 zeroext %cond) presplitcoroutine {
entry:
%__promise = alloca %"struct.task::promise_type", align 1
%a = alloca %struct.big_structure, align 1

View File

@ -5,7 +5,7 @@
declare void @consume(%struct.big_structure*)
; Function Attrs: noinline optnone uwtable
define i8* @f(i1 %cond) "coroutine.presplit"="1" {
define i8* @f(i1 %cond) presplitcoroutine {
entry:
%data = alloca %struct.big_structure, align 1
%data2 = alloca %struct.big_structure, align 1

View File

@ -8,7 +8,7 @@
declare i8* @malloc(i64)
declare void @consume(%struct.big_structure*)
declare void @consume.2(%struct.big_structure.2*)
define void @a(i1 zeroext %cond) "coroutine.presplit"="1" {
define void @a(i1 zeroext %cond) presplitcoroutine {
entry:
%__promise = alloca %"struct.task::promise_type", align 1
%a = alloca %struct.big_structure, align 1

View File

@ -8,7 +8,7 @@
declare i8* @malloc(i64)
declare void @consume(%struct.big_structure*)
declare void @consume.2(%struct.big_structure.2*)
define void @a(i1 zeroext %cond) "coroutine.presplit"="1" {
define void @a(i1 zeroext %cond) presplitcoroutine {
entry:
%__promise = alloca %"struct.task::promise_type", align 1
%a = alloca %struct.big_structure, align 32

View File

@ -1,7 +1,7 @@
; Check that coro-split doesn't choke on intrinsics in unreachable blocks
; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S
define i8* @f(i1 %arg) "coroutine.presplit"="1" personality i32 0 {
define i8* @f(i1 %arg) presplitcoroutine personality i32 0 {
entry:
%arg.addr = alloca i1
store i1 %arg, i1* %arg.addr

View File

@ -1,7 +1,7 @@
; Check that we can handle spills of the result of the invoke instruction
; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
define i8* @f(i64 %this) "coroutine.presplit"="1" personality i32 0 {
define i8* @f(i64 %this) presplitcoroutine personality i32 0 {
entry:
%this.addr = alloca i64
store i64 %this, i64* %this.addr

View File

@ -24,7 +24,7 @@ entry:
declare token @llvm.coro.id(i32, i8* readnone, i8* nocapture readonly, i8*)
declare i8* @llvm.coro.begin(token, i8* writeonly)
attributes #0 = { alwaysinline ssp uwtable "coroutine.presplit"="1" "use-sample-profile" }
attributes #0 = { alwaysinline ssp uwtable presplitcoroutine "use-sample-profile" }
!llvm.dbg.cu = !{}
!llvm.module.flags = !{!1, !2, !3, !4}

View File

@ -1,7 +1,7 @@
; Verifies that we materialize instruction across suspend points
; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
define i8* @f(i32 %n) "coroutine.presplit"="1" {
define i8* @f(i32 %n) presplitcoroutine {
entry:
%id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
%size = call i32 @llvm.coro.size.i32()

View File

@ -1,7 +1,7 @@
; RUN: opt < %s -S -passes=coro-early | FileCheck %s
%struct.A = type <{ i64, i64, i32, [4 x i8] }>
define void @f(%struct.A* nocapture readonly noalias align 8 %a) "coroutine.presplit"="0" {
define void @f(%struct.A* nocapture readonly noalias align 8 %a) presplitcoroutine {
%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)

View File

@ -6,7 +6,7 @@
declare void @consume(%PackedStruct*)
define i8* @f() "coroutine.presplit"="1" {
define i8* @f() presplitcoroutine {
entry:
%data = alloca %PackedStruct, align 32
%id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)

View File

@ -2,7 +2,7 @@
; frame slot if it was written to.
; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
define i8* @f() "coroutine.presplit"="1" {
define i8* @f() presplitcoroutine {
entry:
%a.addr = alloca i64 ; read-only before coro.begin
%a = load i64, i64* %a.addr ; cannot modify the value, don't need to copy

View File

@ -10,7 +10,7 @@ declare void @init(i64 *%ptr)
declare void @use(i8* %ptr)
declare void @use_addr_val(i64 %val, {i64, i64}*%addr)
define { i8*, {i64, i64}* } @f(i8* %buffer) "coroutine.presplit"="1" {
define { i8*, {i64, i64}* } @f(i8* %buffer) presplitcoroutine {
entry:
%tmp = alloca { i64, i64 }, align 8
%proj.1 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %tmp, i64 0, i32 0

View File

@ -3,7 +3,7 @@
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.12.0"
define {i8*, i32*} @f(i8* %buffer, i32* %ptr) "coroutine.presplit"="1" {
define {i8*, i32*} @f(i8* %buffer, i32* %ptr) presplitcoroutine {
entry:
%temp = alloca i32, align 4
%id = call token @llvm.coro.id.retcon.once(i32 8, i32 8, i8* %buffer, i8* bitcast (void (i8*, i1)* @prototype to i8*), i8* bitcast (i8* (i32)* @allocate to i8*), i8* bitcast (void (i8*)* @deallocate to i8*))

View File

@ -1,7 +1,7 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse,simplifycfg,coro-cleanup' -S | FileCheck %s
define i8* @f(i8* %buffer, i32 %n) "coroutine.presplit"="1" {
define i8* @f(i8* %buffer, i32 %n) presplitcoroutine {
entry:
%id = call token @llvm.coro.id.retcon(i32 8, i32 4, i8* %buffer, i8* bitcast (i8* (i8*, i32)* @prototype to i8*), i8* bitcast (i8* (i32)* @allocate to i8*), i8* bitcast (void (i8*)* @deallocate to i8*))
%hdl = call i8* @llvm.coro.begin(token %id, i8* null)

View File

@ -5,7 +5,7 @@
; Verifies that the both phis are stored correctly in the coroutine frame
; CHECK: %f.Frame = type { void (%f.Frame*)*, void (%f.Frame*)*, i32, i32, i1 }
define i8* @f(i1 %n) "coroutine.presplit"="1" {
define i8* @f(i1 %n) presplitcoroutine {
; CHECK-LABEL: @f(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[ID:%.*]] = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* bitcast ([3 x void (%f.Frame*)*]* @f.resumers to i8*))

View File

@ -9,7 +9,7 @@ declare void @g.dummy(%g.Frame*)
declare i8* @g()
define i8* @f() "coroutine.presplit"="1" {
define i8* @f() presplitcoroutine {
entry:
%id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
%size = call i32 @llvm.coro.size.i32()

View File

@ -1,7 +1,7 @@
; Verifies that phi and invoke definitions before CoroBegin are spilled properly.
; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse,simplifycfg' -S | FileCheck %s
define i8* @f(i1 %n) "coroutine.presplit"="1" personality i32 0 {
define i8* @f(i1 %n) presplitcoroutine personality i32 0 {
entry:
%id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
%size = call i32 @llvm.coro.size.i32()

View File

@ -6,7 +6,7 @@
declare void @consume(i32*)
declare void @consume2(%"class.task::promise_type"*)
define i8* @f() "coroutine.presplit"="1" {
define i8* @f() presplitcoroutine {
entry:
%data = alloca i32, align 4
%__promise = alloca %"class.task::promise_type", align 64

View File

@ -1,7 +1,7 @@
; Tests that coro-split pass splits the coroutine into f, f.resume and f.destroy
; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
define i8* @f() "coroutine.presplit"="1" {
define i8* @f() presplitcoroutine {
entry:
%id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
%need.alloc = call i1 @llvm.coro.alloc(token %id)

View File

@ -1,7 +1,7 @@
; Tests that a coroutine is split, inlined into the caller and devirtualized.
; RUN: opt < %s -S -passes='default<O2>' | FileCheck %s
define i8* @f() "coroutine.presplit"="0" {
define i8* @f() presplitcoroutine {
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)

View File

@ -10,7 +10,7 @@
declare i8* @malloc(i64)
declare void @print(i32)
define void @a() "coroutine.presplit"="1" {
define void @a() presplitcoroutine {
entry:
%ref.tmp7 = alloca %"struct.lean_future<int>::Awaiter", align 8
%testval = alloca i32

View File

@ -1,7 +1,7 @@
; Tests that coro-split passes initialized values to coroutine frame allocator.
; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
define i8* @f(i32 %argument) "coroutine.presplit"="1" {
define i8* @f(i32 %argument) presplitcoroutine {
entry:
%argument.addr = alloca i32, align 4
%incremented = add i32 %argument, 1

View File

@ -65,7 +65,7 @@ declare void @llvm.dbg.value(metadata, metadata, metadata) #1
attributes #0 = { nounwind uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="none" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { nounwind readnone }
attributes #2 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="none" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #3 = { nounwind uwtable "coroutine.presplit"="1" "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="none" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #3 = { nounwind uwtable presplitcoroutine "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="none" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #4 = { argmemonly nounwind }
attributes #5 = { argmemonly nounwind readonly }
attributes #6 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="none" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }

View File

@ -2,7 +2,7 @@
; and retains it in the start function.
; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
define i8* @f(i1 %val) "coroutine.presplit"="1" personality i32 3 {
define i8* @f(i1 %val) presplitcoroutine personality i32 3 {
entry:
%id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
%hdl = call i8* @llvm.coro.begin(token %id, i8* null)

View File

@ -2,7 +2,7 @@
; and retains it in the start function.
; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
define i8* @f2(i1 %val) "coroutine.presplit"="1" personality i32 4 {
define i8* @f2(i1 %val) presplitcoroutine personality i32 4 {
entry:
%id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
%hdl = call i8* @llvm.coro.begin(token %id, i8* null)

View File

@ -3,7 +3,7 @@
; '-fvisibility-inlines-hidden'.
; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
define hidden i8* @f() "coroutine.presplit"="1" {
define hidden i8* @f() presplitcoroutine {
entry:
%id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
%need.alloc = call i1 @llvm.coro.alloc(token %id)

View File

@ -59,7 +59,7 @@ declare i1 @llvm.coro.end(i8*, i1) #2
declare i8* @llvm.coro.subfn.addr(i8* nocapture readonly, i8) #1
declare i8* @malloc(i64)
attributes #0 = { "coroutine.presplit"="1" }
attributes #0 = { presplitcoroutine }
attributes #1 = { argmemonly nounwind readonly }
attributes #2 = { nounwind }
attributes #3 = { nounwind readnone }

View File

@ -98,7 +98,7 @@ declare i8 @switch_result()
declare i8* @g()
declare i8* @h()
attributes #0 = { "coroutine.presplit"="1" }
attributes #0 = { presplitcoroutine }
attributes #1 = { argmemonly nounwind readonly }
attributes #2 = { nounwind }
attributes #3 = { nounwind readnone }

View File

@ -61,7 +61,7 @@ declare i1 @llvm.coro.end(i8*, i1) #2
declare i8* @llvm.coro.subfn.addr(i8* nocapture readonly, i8) #1
declare i8* @malloc(i64)
attributes #0 = { "coroutine.presplit"="1" }
attributes #0 = { presplitcoroutine }
attributes #1 = { argmemonly nounwind readonly }
attributes #2 = { nounwind }
attributes #3 = { nounwind readnone }

View File

@ -94,7 +94,7 @@ declare i8 @switch_result()
declare i8* @g()
declare i8* @h()
attributes #0 = { "coroutine.presplit"="1" }
attributes #0 = { presplitcoroutine }
attributes #1 = { argmemonly nounwind readonly }
attributes #2 = { nounwind }
attributes #3 = { nounwind readnone }

View File

@ -59,7 +59,7 @@ declare i8* @llvm.coro.subfn.addr(i8* nocapture readonly, i8) #1
declare i8* @malloc(i64)
declare void @delete(i8* nonnull) #2
attributes #0 = { "coroutine.presplit"="1" }
attributes #0 = { presplitcoroutine }
attributes #1 = { argmemonly nounwind readonly }
attributes #2 = { nounwind }
attributes #3 = { nounwind readnone }

View File

@ -56,7 +56,7 @@ declare void @consume(i8*)
declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture)
declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture)
attributes #0 = { "coroutine.presplit"="1" }
attributes #0 = { presplitcoroutine }
attributes #1 = { argmemonly nounwind readonly }
attributes #2 = { nounwind }
attributes #3 = { nounwind readnone }

View File

@ -111,7 +111,7 @@ declare void @consume(i64*)
declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture)
declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture)
attributes #0 = { "coroutine.presplit"="1" }
attributes #0 = { presplitcoroutine }
attributes #1 = { argmemonly nounwind readonly }
attributes #2 = { nounwind }
attributes #3 = { nounwind readnone }

View File

@ -113,7 +113,7 @@ declare void @consume(i64*)
declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture)
declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture)
attributes #0 = { "coroutine.presplit"="1" }
attributes #0 = { presplitcoroutine }
attributes #1 = { argmemonly nounwind readonly }
attributes #2 = { nounwind }
attributes #3 = { nounwind readnone }

View File

@ -14,7 +14,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() presplitcoroutine {
entry:
%__promise = alloca i32, align 8
%0 = bitcast i32* %__promise to i8*

View File

@ -9,7 +9,7 @@
declare i8* @malloc(i64)
declare void @print(i32)
define void @a() "coroutine.presplit"="1" {
define void @a() presplitcoroutine {
entry:
%ref.tmp7 = alloca %"struct.lean_future<int>::Awaiter", align 8
%testval = alloca i32

View File

@ -10,7 +10,7 @@ declare i1 @getcond()
declare i8* @malloc(i64)
declare void @print(i32)
define void @a() "coroutine.presplit"="1" {
define void @a() presplitcoroutine {
entry:
%ref.tmp7 = alloca %"struct.lean_future<int>::Awaiter", align 8
%testval = alloca i32

View File

@ -12,7 +12,7 @@ declare void @print(i32)
%i8.array = type { [100 x i8] }
declare void @consume.i8.array(%i8.array*)
define void @a.gep() "coroutine.presplit"="1" {
define void @a.gep() presplitcoroutine {
entry:
%ref.tmp7 = alloca %"struct.lean_future<int>::Awaiter", align 8
%testval = alloca %i8.array

View File

@ -10,7 +10,7 @@ declare i8* @malloc(i64)
declare void @print(i32)
declare void @consume.i8(i8)
define void @a() "coroutine.presplit"="1" {
define void @a() presplitcoroutine {
entry:
%ref.tmp7 = alloca %"struct.lean_future<int>::Awaiter", align 8
%testval = alloca i8

View File

@ -13,7 +13,7 @@ declare i1 @llvm.coro.end(i8*, i1)
declare i8* @llvm.coro.free(token, i8* nocapture readonly)
declare token @llvm.coro.save(i8*)
define void @foo() "coroutine.presplit"="1" {
define void @foo() presplitcoroutine {
entry:
%a0 = alloca [0 x i8]
%a1 = alloca i32

View File

@ -1,7 +1,7 @@
; First example from Doc/Coroutines.rst (two block loop)
; RUN: opt < %s -aa-pipeline=basic-aa -passes='default<O2>' -preserve-alignment-assumptions-during-inlining=false -S | FileCheck %s
define i8* @f(i32 %n) "coroutine.presplit"="0" {
define i8* @f(i32 %n) presplitcoroutine {
entry:
%id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
%size = call i32 @llvm.coro.size.i32()

View File

@ -1,7 +1,7 @@
; First example from Doc/Coroutines.rst (one block loop)
; RUN: opt < %s -aa-pipeline=basic-aa -passes='default<O2>' -preserve-alignment-assumptions-during-inlining=false -S | FileCheck %s
define i8* @f(i32 %n) "coroutine.presplit"="0" {
define i8* @f(i32 %n) presplitcoroutine {
entry:
%id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
%size = call i32 @llvm.coro.size.i32()

View File

@ -1,7 +1,7 @@
; Second example from Doc/Coroutines.rst (custom alloc and free functions)
; RUN: opt < %s -passes='default<O2>' -S | FileCheck %s
define i8* @f(i32 %n) "coroutine.presplit"="0" {
define i8* @f(i32 %n) presplitcoroutine {
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)

View File

@ -1,7 +1,7 @@
; Third example from Doc/Coroutines.rst (two suspend points)
; RUN: opt < %s -aa-pipeline=basic-aa -passes='default<O2>' -S | FileCheck %s
define i8* @f(i32 %n) "coroutine.presplit"="0" {
define i8* @f(i32 %n) presplitcoroutine {
entry:
%id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
%size = call i32 @llvm.coro.size.i32()

View File

@ -1,7 +1,7 @@
; Fourth example from Doc/Coroutines.rst (coroutine promise)
; RUN: opt < %s -passes='default<O2>' -S | FileCheck %s
define i8* @f(i32 %n) "coroutine.presplit"="0" {
define i8* @f(i32 %n) presplitcoroutine {
entry:
%promise = alloca i32
%pv = bitcast i32* %promise to i8*

View File

@ -1,7 +1,7 @@
; Fifth example from Doc/Coroutines.rst (final suspend)
; RUN: opt < %s -aa-pipeline=basic-aa -passes='default<O2>' -preserve-alignment-assumptions-during-inlining=false -S | FileCheck %s
define i8* @f(i32 %n) "coroutine.presplit"="0" {
define i8* @f(i32 %n) presplitcoroutine {
entry:
%id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
%size = call i32 @llvm.coro.size.i32()

View File

@ -10,7 +10,7 @@
; CHECK-NEXT: call void @print(i32 %n)
; CHECK-NEXT: ret void
;
define void @no_suspends(i32 %n) "coroutine.presplit"="1" {
define void @no_suspends(i32 %n) presplitcoroutine {
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)
@ -50,7 +50,7 @@ suspend:
; CHECK-NEXT: call void @print(i32 0)
; CHECK-NEXT: ret void
;
define void @simplify_resume(i8* %src, i8* %dst) "coroutine.presplit"="1" {
define void @simplify_resume(i8* %src, i8* %dst) presplitcoroutine {
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)
@ -101,7 +101,7 @@ suspend:
; CHECK-NEXT: call void @print(i32 1)
; CHECK-NEXT: ret void
;
define void @simplify_destroy() "coroutine.presplit"="1" personality i32 0 {
define void @simplify_destroy() presplitcoroutine personality i32 0 {
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)
@ -159,7 +159,7 @@ lpad:
; CHECK: call void @print(i32 0)
; CHECK-NEXT: ret void
;
define void @simplify_resume_with_inlined_if(i8* %src, i8* %dst, i1 %cond) "coroutine.presplit"="1" {
define void @simplify_resume_with_inlined_if(i8* %src, i8* %dst, i1 %cond) presplitcoroutine {
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)
@ -215,7 +215,7 @@ suspend:
; CHECK-NEXT: entry:
; CHECK-NEXT: llvm.coro.id
define void @cannot_simplify_other_calls() "coroutine.presplit"="1" {
define void @cannot_simplify_other_calls() presplitcoroutine {
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)
@ -268,7 +268,7 @@ suspend:
; CHECK-NEXT: entry:
; CHECK-NEXT: llvm.coro.id
define void @cannot_simplify_calls_in_terminator() "coroutine.presplit"="1" personality i32 0 {
define void @cannot_simplify_calls_in_terminator() presplitcoroutine personality i32 0 {
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)
@ -321,7 +321,7 @@ lpad:
; CHECK-NEXT: entry:
; CHECK-NEXT: llvm.coro.id
define void @cannot_simplify_not_last_instr(i8* %dst, i8* %src) "coroutine.presplit"="1" {
define void @cannot_simplify_not_last_instr(i8* %dst, i8* %src) presplitcoroutine {
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)
@ -367,7 +367,7 @@ suspend:
; CHECK-NEXT: entry:
; CHECK-NEXT: llvm.coro.id
;
define void @cannot_simplify_final_suspend() "coroutine.presplit"="1" personality i32 0 {
define void @cannot_simplify_final_suspend() presplitcoroutine personality i32 0 {
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)

View File

@ -1,7 +1,7 @@
; Verify that we correctly handle suspend when the coro.end block contains phi
; RUN: opt < %s -aa-pipeline=basic-aa -passes='default<O2>' -S | FileCheck %s
define i8* @f(i32 %n) "coroutine.presplit"="0" {
define i8* @f(i32 %n) presplitcoroutine {
entry:
%id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
%size = call i32 @llvm.coro.size.i32()

View File

@ -79,7 +79,7 @@ define void @unreachable() {
; CHECK-NOT: Function Attrs: {{.*}}noreturn
; CHECK: @coro
define void @coro() "coroutine.presplit"="1" {
define void @coro() presplitcoroutine {
call token @llvm.coro.id.retcon.once(i32 0, i32 0, i8* null, i8* bitcast(void() *@coro to i8*), i8* null, i8* null)
call i1 @llvm.coro.end(i8* null, i1 false)
unreachable

View File

@ -13,7 +13,7 @@
declare i8* @malloc(i64)
declare void @print(i32)
define void @a() "coroutine.presplit"="0" {
define void @a() presplitcoroutine {
entry:
%ref.tmp7 = alloca %"struct.lean_future<int>::Awaiter", align 8
%testval = alloca i32

View File

@ -192,11 +192,9 @@ static CoroMachinery setupCoroMachinery(func::FuncOp func) {
}
// The switch-resumed API based coroutine should be marked with
// "coroutine.presplit" attribute with value "0" to mark the function as a
// coroutine.
func->setAttr("passthrough", builder.getArrayAttr(builder.getArrayAttr(
{builder.getStringAttr("coroutine.presplit"),
builder.getStringAttr("0")})));
// coroutine.presplit attribute to mark the function as a coroutine.
func->setAttr("passthrough", builder.getArrayAttr(
StringAttr::get(ctx, "presplitcoroutine")));
CoroMachinery machinery;
machinery.func = func;

View File

@ -3,9 +3,9 @@
// RUN: mlir-opt %s -pass-pipeline="async-to-async-runtime,func.func(async-runtime-ref-counting,async-runtime-ref-counting-opt),convert-async-to-llvm,func.func(convert-linalg-to-loops,convert-scf-to-cf),convert-linalg-to-llvm,convert-memref-to-llvm,func.func(convert-arith-to-llvm),convert-func-to-llvm,reconcile-unrealized-casts" \
// RUN: | FileCheck %s
// CHECK: llvm.func @async_execute_fn{{.*}}attributes{{.*}}"coroutine.presplit", "0"
// CHECK: llvm.func @async_execute_fn_0{{.*}}attributes{{.*}}"coroutine.presplit", "0"
// CHECK: llvm.func @async_execute_fn_1{{.*}}attributes{{.*}}"coroutine.presplit", "0"
// CHECK: llvm.func @async_execute_fn{{.*}}attributes{{.*}}presplitcoroutine
// CHECK: llvm.func @async_execute_fn_0{{.*}}attributes{{.*}}presplitcoroutine
// CHECK: llvm.func @async_execute_fn_1{{.*}}attributes{{.*}}presplitcoroutine
func.func @main() {
%i0 = arith.constant 0 : index