[NFC] Code cleanups for coroutine after we remvoed legacy passes

This commit is contained in:
Chuanqi Xu 2022-04-21 15:32:39 +08:00
parent 00c511b351
commit 7eaa84eac3
4 changed files with 6 additions and 75 deletions
llvm
lib/Transforms/Coroutines
test/Transforms/Coroutines

View File

@ -35,7 +35,7 @@ public:
AnyResumeFnPtrTy(FunctionType::get(Type::getVoidTy(Context), Int8Ptr,
/*isVarArg=*/false)
->getPointerTo()) {}
bool lowerEarlyIntrinsics(Function &F);
void lowerEarlyIntrinsics(Function &F);
};
}
@ -145,8 +145,7 @@ static void setCannotDuplicate(CoroIdInst *CoroId) {
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;
@ -182,11 +181,8 @@ bool Lowerer::lowerEarlyIntrinsics(Function &F) {
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);
@ -198,7 +194,7 @@ bool Lowerer::lowerEarlyIntrinsics(Function &F) {
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);
@ -213,8 +209,6 @@ bool Lowerer::lowerEarlyIntrinsics(Function &F) {
lowerCoroDone(cast<IntrinsicInst>(&I));
break;
}
Changed = true;
}
// Make sure that all CoroFree reference the coro.id intrinsic.
@ -231,8 +225,6 @@ bool Lowerer::lowerEarlyIntrinsics(Function &F) {
for (Argument &A : F.args())
if (A.hasNoAliasAttr())
A.removeAttr(Attribute::NoAlias);
return Changed;
}
static bool declaresCoroEarlyIntrinsics(const Module &M) {

View File

@ -21,26 +21,13 @@ class CallGraphSCC;
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 {

View File

@ -2084,8 +2084,6 @@ PreservedAnalyses CoroSplitPass::run(LazyCallGraph::SCC &C,
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);

View File

@ -1,46 +0,0 @@
; 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*)