Skip to content

Commit 768de2c

Browse files
committed
[Coroutines] Part 15a: Lower coro.subfn.addr in CoroCleanup
Summary: Not all coro.subfn.addr intrinsics can be eliminated in CoroElide through devirtualization. Those that remain need to be lowered in CoroCleanup. Reviewers: majnemer Subscribers: llvm-commits, mehdi_amini Differential Revision: https://reviews.llvm.org/D24412 llvm-svn: 282897
1 parent b43712a commit 768de2c

File tree

3 files changed

+44
-3
lines changed

3 files changed

+44
-3
lines changed

llvm/lib/Transforms/Coroutines/CoroCleanup.cpp

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
//===----------------------------------------------------------------------===//
1111

1212
#include "CoroInternal.h"
13+
#include "llvm/IR/IRBuilder.h"
1314
#include "llvm/IR/InstIterator.h"
1415
#include "llvm/IR/LegacyPassManager.h"
1516
#include "llvm/Pass.h"
@@ -22,7 +23,8 @@ using namespace llvm;
2223
namespace {
2324
// Created on demand if CoroCleanup pass has work to do.
2425
struct Lowerer : coro::LowererBase {
25-
Lowerer(Module &M) : LowererBase(M) {}
26+
IRBuilder<> Builder;
27+
Lowerer(Module &M) : LowererBase(M), Builder(Context) {}
2628
bool lowerRemainingCoroIntrinsics(Function &F);
2729
};
2830
}
@@ -36,6 +38,23 @@ static void simplifyCFG(Function &F) {
3638
FPM.doFinalization();
3739
}
3840

41+
static void lowerSubFn(IRBuilder<> &Builder, CoroSubFnInst *SubFn) {
42+
Builder.SetInsertPoint(SubFn);
43+
Value *FrameRaw = SubFn->getFrame();
44+
int Index = SubFn->getIndex();
45+
46+
auto *FrameTy = StructType::get(
47+
SubFn->getContext(), {Builder.getInt8PtrTy(), Builder.getInt8PtrTy()});
48+
PointerType *FramePtrTy = FrameTy->getPointerTo();
49+
50+
Builder.SetInsertPoint(SubFn);
51+
auto *FramePtr = Builder.CreateBitCast(FrameRaw, FramePtrTy);
52+
auto *Gep = Builder.CreateConstInBoundsGEP2_32(FrameTy, FramePtr, 0, Index);
53+
auto *Load = Builder.CreateLoad(Gep);
54+
55+
SubFn->replaceAllUsesWith(Load);
56+
}
57+
3958
bool Lowerer::lowerRemainingCoroIntrinsics(Function &F) {
4059
bool Changed = false;
4160

@@ -57,6 +76,9 @@ bool Lowerer::lowerRemainingCoroIntrinsics(Function &F) {
5776
case Intrinsic::coro_id:
5877
II->replaceAllUsesWith(ConstantTokenNone::get(Context));
5978
break;
79+
case Intrinsic::coro_subfn_addr:
80+
lowerSubFn(Builder, cast<CoroSubFnInst>(II));
81+
break;
6082
}
6183
II->eraseFromParent();
6284
Changed = true;
@@ -87,7 +109,8 @@ struct CoroCleanup : FunctionPass {
87109
// in the module.
88110
bool doInitialization(Module &M) override {
89111
if (coro::declaresIntrinsics(M, {"llvm.coro.alloc", "llvm.coro.begin",
90-
"llvm.coro.free", "llvm.coro.id"}))
112+
"llvm.coro.subfn.addr", "llvm.coro.free",
113+
"llvm.coro.id"}))
91114
L = llvm::make_unique<Lowerer>(M);
92115
return false;
93116
}

llvm/lib/Transforms/Coroutines/Coroutines.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ static bool isCoroutineIntrinsicName(StringRef Name) {
107107
"llvm.coro.done", "llvm.coro.end", "llvm.coro.frame",
108108
"llvm.coro.free", "llvm.coro.id", "llvm.coro.param",
109109
"llvm.coro.promise", "llvm.coro.resume", "llvm.coro.save",
110-
"llvm.coro.size", "llvm.coro.suspend",
110+
"llvm.coro.size", "llvm.coro.subfn.addr", "llvm.coro.suspend",
111111
};
112112
return Intrinsic::lookupLLVMIntrinsicByName(CoroIntrinsics, Name) != -1;
113113
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
; Make sure that all library helper coro intrinsics are lowered.
2+
; RUN: opt < %s -O0 -enable-coroutines -S | FileCheck %s
3+
4+
; CHECK-LABEL: @uses_library_support_coro_intrinsics(
5+
; CHECK-NOT: @llvm.coro
6+
; CHECK: ret void
7+
define void @uses_library_support_coro_intrinsics(i8* %hdl) {
8+
entry:
9+
call void @llvm.coro.resume(i8* %hdl)
10+
call void @llvm.coro.destroy(i8* %hdl)
11+
call i1 @llvm.coro.done(i8* %hdl)
12+
ret void
13+
}
14+
15+
declare void @llvm.coro.resume(i8*)
16+
declare void @llvm.coro.destroy(i8*)
17+
declare i1 @llvm.coro.done(i8*)
18+

0 commit comments

Comments
 (0)