AnyResumeFnPtrTy(FunctionType::get(Type::getVoidTy(Context), Int8Ptr,
/*isVarArg=*/false)
->getPointerTo()) {}
- bool lowerEarlyIntrinsics(Function &F);
+ void lowerEarlyIntrinsics(Function &F);
};
}
CB->setCannotDuplicate();
}
-bool Lowerer::lowerEarlyIntrinsics(Function &F) {
- bool Changed = false;
+void Lowerer::lowerEarlyIntrinsics(Function &F) {
CoroIdInst *CoroId = nullptr;
SmallVector<CoroFreeInst *, 4> CoroFrees;
bool HasCoroSuspend = false;
if (auto *CII = cast<CoroIdInst>(&I)) {
if (CII->getInfo().isPreSplit()) {
assert(F.hasFnAttribute(CORO_PRESPLIT_ATTR) &&
- F.getFnAttribute(CORO_PRESPLIT_ATTR).getValueAsString() ==
- UNPREPARED_FOR_SPLIT &&
"The frontend uses Swtich-Resumed ABI should emit "
- "\"coroutine.presplit\" attribute with value \"0\" for the "
- "coroutine.");
+ "\"coroutine.presplit\" attribute for the coroutine.");
setCannotDuplicate(CII);
CII->setCoroutineSelf();
CoroId = cast<CoroIdInst>(&I);
case Intrinsic::coro_id_async:
// TODO: Remove the line once we support it in the corresponding
// frontend.
- F.addFnAttr(CORO_PRESPLIT_ATTR, PREPARED_FOR_SPLIT);
+ F.addFnAttr(CORO_PRESPLIT_ATTR);
break;
case Intrinsic::coro_resume:
lowerResumeOrDestroy(*CB, CoroSubFnInst::ResumeIndex);
lowerCoroDone(cast<IntrinsicInst>(&I));
break;
}
-
- Changed = true;
}
// Make sure that all CoroFree reference the coro.id intrinsic.
for (Argument &A : F.args())
if (A.hasNoAliasAttr())
A.removeAttr(Attribute::NoAlias);
-
- return Changed;
}
static bool declaresCoroEarlyIntrinsics(const Module &M) {
class PassRegistry;
// CoroEarly pass marks every function that has coro.begin with a string
-// attribute "coroutine.presplit"="0". CoroSplit pass processes the coroutine
-// twice. First, it lets it go through complete IPO optimization pipeline as a
-// single function. It forces restart of the pipeline by inserting an indirect
-// call to an empty function "coro.devirt.trigger" which is devirtualized by
-// CoroElide pass that triggers a restart of the pipeline by CGPassManager.
-// When CoroSplit pass sees the same coroutine the second time, it splits it up,
-// adds coroutine subfunctions to the SCC to be processed by IPO pipeline.
-// Async lowering similarily triggers a restart of the pipeline after it has
-// split the coroutine.
+// 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.
-// FIXME: Remove these values once we remove the Legacy PM.
#define CORO_PRESPLIT_ATTR "coroutine.presplit"
-#define UNPREPARED_FOR_SPLIT "0"
-#define PREPARED_FOR_SPLIT "1"
-#define ASYNC_RESTART_AFTER_SPLIT "2"
-
-#define CORO_DEVIRT_TRIGGER_FN "coro.devirt.trigger"
namespace coro {
for (LazyCallGraph::Node *N : Coroutines) {
Function &F = N->getFunction();
LLVM_DEBUG(dbgs() << "CoroSplit: Processing coroutine '" << F.getName()
- << "' state: "
- << F.getFnAttribute(CORO_PRESPLIT_ATTR).getValueAsString()
<< "\n");
F.removeFnAttr(CORO_PRESPLIT_ATTR);
+++ /dev/null
-; REQUIRES: asserts
-; The following tests use the new pass manager, and verify that the coroutine
-; passes re-run the CGSCC pipeline.
-; RUN: opt < %s -S -passes='default<O0>' -debug-only=coro-split 2>&1 | FileCheck --check-prefix=CHECK-NEWPM %s
-; RUN: opt < %s -S -passes='default<O1>' -debug-only=coro-split 2>&1 | FileCheck --check-prefix=CHECK-NEWPM %s
-
-; CHECK: CoroSplit: Processing coroutine 'f' state: 0
-; CHECK-NEXT: CoroSplit: Processing coroutine 'f' state: 1
-; CHECK-NEWPM: CoroSplit: Processing coroutine 'f' state: 0
-; CHECK-NEWPM-NOT: CoroSplit: Processing coroutine 'f' state: 1
-
-
-define void @f() "coroutine.presplit"="0" {
- %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)
- %hdl = call i8* @llvm.coro.begin(token %id, i8* %alloc)
- call void @print(i32 0)
- %s1 = call i8 @llvm.coro.suspend(token none, i1 false)
- switch i8 %s1, label %suspend [i8 0, label %resume
- i8 1, label %cleanup]
-resume:
- call void @print(i32 1)
- br label %cleanup
-
-cleanup:
- %mem = call i8* @llvm.coro.free(token %id, i8* %hdl)
- call void @free(i8* %mem)
- br label %suspend
-suspend:
- call i1 @llvm.coro.end(i8* %hdl, i1 0)
- ret void
-}
-
-declare token @llvm.coro.id(i32, i8*, i8*, i8*)
-declare i8* @llvm.coro.begin(token, i8*)
-declare i8* @llvm.coro.free(token, i8*)
-declare i32 @llvm.coro.size.i32()
-declare i8 @llvm.coro.suspend(token, i1)
-declare void @llvm.coro.resume(i8*)
-declare void @llvm.coro.destroy(i8*)
-declare i1 @llvm.coro.end(i8*, i1)
-
-declare noalias i8* @malloc(i32)
-declare void @print(i32)
-declare void @free(i8*)