[Coroutine] Collect CoroBegin if all of terminators are dominated by one coro.destroy

Summary: The original logic seems to be we could collecting a CoroBegin
if one of the terminators could be dominated by one of coro.destroy,
which doesn't make sense.
This patch rewrites the logics to collect CoroBegin if all of
terminators are dominated by one coro.destroy. If there is no such
coro.destroy, we would call hasEscapePath to evaluate if we should
collect it.

Test Plan: check-llvm

Reviewed by: lxfind

Differential Revision: https://reviews.llvm.org/D100614
This commit is contained in:
Chuanqi Xu 2021-04-22 11:20:20 +08:00
parent b9e9e2eef1
commit 77ca2a6893
2 changed files with 67 additions and 9 deletions

View File

@ -232,17 +232,22 @@ bool Lowerer::shouldElide(Function *F, DominatorTree &DT) const {
// Filter out the coro.destroy that lie along exceptional paths.
SmallPtrSet<CoroBeginInst *, 8> ReferencedCoroBegins;
for (auto &It : DestroyAddr) {
// If there is any coro.destroy dominates all of the terminators for the
// coro.begin, we could know the corresponding coro.begin wouldn't escape.
for (Instruction *DA : It.second) {
for (BasicBlock *TI : Terminators) {
if (DT.dominates(DA, TI->getTerminator())) {
if (llvm::all_of(Terminators, [&](auto *TI) {
return DT.dominates(DA, TI->getTerminator());
})) {
ReferencedCoroBegins.insert(It.first);
break;
}
}
}
// Whether there is any paths from coro.begin to Terminators which not pass
// through any of the coro.destroys.
//
// hasEscapePath is relatively slow, so we avoid to run it as much as
// possible.
if (!ReferencedCoroBegins.count(It.first) &&
!hasEscapePath(It.first, Terminators))
ReferencedCoroBegins.insert(It.first);

View File

@ -19,15 +19,23 @@ define fastcc void @f.destroy(i8*) {
ret void
}
@f.resumers = internal constant [2 x void (i8*)*] [void (i8*)* @f.resume,
void (i8*)* @f.destroy]
; cleanup part of the coroutine
define fastcc void @f.cleanup(i8*) {
tail call void @print(i32 2)
ret void
}
@f.resumers = internal constant [3 x void (i8*)*] [void (i8*)* @f.resume,
void (i8*)* @f.destroy,
void (i8*)* @f.cleanup]
; a coroutine start function
define i8* @f() {
entry:
%id = call token @llvm.coro.id(i32 0, i8* null,
i8* bitcast (i8*()* @f to i8*),
i8* bitcast ([2 x void (i8*)*]* @f.resumers to i8*))
i8* bitcast ([3 x void (i8*)*]* @f.resumers to i8*))
%alloc = call i1 @llvm.coro.alloc(token %id)
%hdl = call i8* @llvm.coro.begin(token %id, i8* null)
ret i8* %hdl
}
@ -42,7 +50,7 @@ entry:
%1 = bitcast i8* %0 to void (i8*)*
call fastcc void %1(i8* %hdl)
; CHECK-NEXT: call void @print(i32 1)
; CHECK-NEXT: call void @print(i32 2)
%2 = call i8* @llvm.coro.subfn.addr(i8* %hdl, i8 1)
%3 = bitcast i8* %2 to void (i8*)*
call fastcc void %3(i8* %hdl)
@ -51,6 +59,50 @@ entry:
ret void
}
; CHECK-LABEL: @callResumeMultiRet(
define void @callResumeMultiRet(i1 %b) {
entry:
%hdl = call i8* @f()
; CHECK: %alloc.i = call i1 @llvm.coro.alloc
; CHECK: call void @print(i32 0)
%0 = call i8* @llvm.coro.subfn.addr(i8* %hdl, i8 0)
%1 = bitcast i8* %0 to void (i8*)*
call fastcc void %1(i8* %hdl)
br i1 %b, label %destroy, label %ret
destroy:
; CHECK: call void @print(i32 1)
%2 = call i8* @llvm.coro.subfn.addr(i8* %hdl, i8 1)
%3 = bitcast i8* %2 to void (i8*)*
call fastcc void %3(i8* %hdl)
ret void
ret:
ret void
}
; CHECK-LABEL: @callResumeMultiRetDommmed(
define void @callResumeMultiRetDommmed(i1 %b) {
entry:
%hdl = call i8* @f()
; CHECK-NOT: %alloc.i = call i1 @llvm.coro.alloc
; CHECK: call void @print(i32 0)
%0 = call i8* @llvm.coro.subfn.addr(i8* %hdl, i8 0)
%1 = bitcast i8* %0 to void (i8*)*
call fastcc void %1(i8* %hdl)
; CHECK: call void @print(i32 2)
%2 = call i8* @llvm.coro.subfn.addr(i8* %hdl, i8 1)
%3 = bitcast i8* %2 to void (i8*)*
call fastcc void %3(i8* %hdl)
br i1 %b, label %destroy, label %ret
destroy:
ret void
ret:
ret void
}
; CHECK-LABEL: @eh(
define void @eh() personality i8* null {
entry:
@ -113,3 +165,4 @@ declare token @llvm.coro.id(i32, i8*, i8*, i8*)
declare i8* @llvm.coro.begin(token, i8*)
declare i8* @llvm.coro.frame()
declare i8* @llvm.coro.subfn.addr(i8*, i8)
declare i1 @llvm.coro.alloc(token)