Skip to content

Commit ab6316e

Browse files
authored
[Coroutines] Work on intrinsic IDs instead of names (NFCI) (#145518)
For the checks whether certain intrinsics are used, work with intrinsic IDs instead of intrinsic names. This also exposes that some of the checks were incorrect, because the intrinsics were overloaded. There is no efficient way to determine whether these are used. This change explicitly documents which intrinsics are not checked for this reason.
1 parent 9beb467 commit ab6316e

File tree

5 files changed

+53
-68
lines changed

5 files changed

+53
-68
lines changed

llvm/lib/Transforms/Coroutines/CoroCleanup.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -110,11 +110,11 @@ bool Lowerer::lower(Function &F) {
110110

111111
static bool declaresCoroCleanupIntrinsics(const Module &M) {
112112
return coro::declaresIntrinsics(
113-
M, {"llvm.coro.alloc", "llvm.coro.begin", "llvm.coro.subfn.addr",
114-
"llvm.coro.free", "llvm.coro.id", "llvm.coro.id.retcon",
115-
"llvm.coro.id.async", "llvm.coro.id.retcon.once",
116-
"llvm.coro.async.size.replace", "llvm.coro.async.resume",
117-
"llvm.coro.begin.custom.abi"});
113+
M, {Intrinsic::coro_alloc, Intrinsic::coro_begin,
114+
Intrinsic::coro_subfn_addr, Intrinsic::coro_free, Intrinsic::coro_id,
115+
Intrinsic::coro_id_retcon, Intrinsic::coro_id_async,
116+
Intrinsic::coro_id_retcon_once, Intrinsic::coro_async_size_replace,
117+
Intrinsic::coro_async_resume, Intrinsic::coro_begin_custom_abi});
118118
}
119119

120120
PreservedAnalyses CoroCleanupPass::run(Module &M,

llvm/lib/Transforms/Coroutines/CoroEarly.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -279,12 +279,13 @@ void Lowerer::lowerEarlyIntrinsics(Function &F) {
279279
}
280280

281281
static bool declaresCoroEarlyIntrinsics(const Module &M) {
282+
// coro_suspend omitted as it is overloaded.
282283
return coro::declaresIntrinsics(
283-
M, {"llvm.coro.id", "llvm.coro.id.retcon", "llvm.coro.id.retcon.once",
284-
"llvm.coro.id.async", "llvm.coro.destroy", "llvm.coro.done",
285-
"llvm.coro.end", "llvm.coro.end.async", "llvm.coro.noop",
286-
"llvm.coro.free", "llvm.coro.promise", "llvm.coro.resume",
287-
"llvm.coro.suspend"});
284+
M, {Intrinsic::coro_id, Intrinsic::coro_id_retcon,
285+
Intrinsic::coro_id_retcon_once, Intrinsic::coro_id_async,
286+
Intrinsic::coro_destroy, Intrinsic::coro_done, Intrinsic::coro_end,
287+
Intrinsic::coro_end_async, Intrinsic::coro_noop, Intrinsic::coro_free,
288+
Intrinsic::coro_promise, Intrinsic::coro_resume});
288289
}
289290

290291
PreservedAnalyses CoroEarlyPass::run(Module &M, ModuleAnalysisManager &) {

llvm/lib/Transforms/Coroutines/CoroElide.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,7 @@ bool CoroIdElider::attemptElide() {
450450

451451
PreservedAnalyses CoroElidePass::run(Function &F, FunctionAnalysisManager &AM) {
452452
auto &M = *F.getParent();
453-
if (!coro::declaresIntrinsics(M, {"llvm.coro.id"}))
453+
if (!coro::declaresIntrinsics(M, Intrinsic::coro_id))
454454
return PreservedAnalyses::all();
455455

456456
FunctionElideInfo FEI{&F};

llvm/lib/Transforms/Coroutines/CoroInternal.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,7 @@ namespace coro {
2424

2525
bool isSuspendBlock(BasicBlock *BB);
2626
bool declaresAnyIntrinsic(const Module &M);
27-
bool declaresIntrinsics(const Module &M,
28-
const std::initializer_list<StringRef>);
27+
bool declaresIntrinsics(const Module &M, ArrayRef<Intrinsic::ID> List);
2928
void replaceCoroFree(CoroIdInst *CoroId, bool Elide);
3029

3130
/// Replaces all @llvm.coro.alloc intrinsics calls associated with a given

llvm/lib/Transforms/Coroutines/Coroutines.cpp

Lines changed: 40 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -61,71 +61,56 @@ CallInst *coro::LowererBase::makeSubFnCall(Value *Arg, int Index,
6161
return CallInst::Create(Fn, {Arg, IndexVal}, "", InsertPt->getIterator());
6262
}
6363

64-
// NOTE: Must be sorted!
65-
static const char *const CoroIntrinsics[] = {
66-
"llvm.coro.align",
67-
"llvm.coro.alloc",
68-
"llvm.coro.async.context.alloc",
69-
"llvm.coro.async.context.dealloc",
70-
"llvm.coro.async.resume",
71-
"llvm.coro.async.size.replace",
72-
"llvm.coro.await.suspend.bool",
73-
"llvm.coro.await.suspend.handle",
74-
"llvm.coro.await.suspend.void",
75-
"llvm.coro.begin",
76-
"llvm.coro.begin.custom.abi",
77-
"llvm.coro.destroy",
78-
"llvm.coro.done",
79-
"llvm.coro.end",
80-
"llvm.coro.end.async",
81-
"llvm.coro.frame",
82-
"llvm.coro.free",
83-
"llvm.coro.id",
84-
"llvm.coro.id.async",
85-
"llvm.coro.id.retcon",
86-
"llvm.coro.id.retcon.once",
87-
"llvm.coro.noop",
88-
"llvm.coro.prepare.async",
89-
"llvm.coro.prepare.retcon",
90-
"llvm.coro.promise",
91-
"llvm.coro.resume",
92-
"llvm.coro.save",
93-
"llvm.coro.size",
94-
"llvm.coro.subfn.addr",
95-
"llvm.coro.suspend",
96-
"llvm.coro.suspend.async",
97-
"llvm.coro.suspend.retcon",
64+
// We can only efficiently check for non-overloaded intrinsics.
65+
// The following intrinsics are absent for that reason:
66+
// coro_align, coro_size, coro_suspend_async, coro_suspend_retcon
67+
static Intrinsic::ID NonOverloadedCoroIntrinsics[] = {
68+
Intrinsic::coro_alloc,
69+
Intrinsic::coro_async_context_alloc,
70+
Intrinsic::coro_async_context_dealloc,
71+
Intrinsic::coro_async_resume,
72+
Intrinsic::coro_async_size_replace,
73+
Intrinsic::coro_await_suspend_bool,
74+
Intrinsic::coro_await_suspend_handle,
75+
Intrinsic::coro_await_suspend_void,
76+
Intrinsic::coro_begin,
77+
Intrinsic::coro_begin_custom_abi,
78+
Intrinsic::coro_destroy,
79+
Intrinsic::coro_done,
80+
Intrinsic::coro_end,
81+
Intrinsic::coro_end_async,
82+
Intrinsic::coro_frame,
83+
Intrinsic::coro_free,
84+
Intrinsic::coro_id,
85+
Intrinsic::coro_id_async,
86+
Intrinsic::coro_id_retcon,
87+
Intrinsic::coro_id_retcon_once,
88+
Intrinsic::coro_promise,
89+
Intrinsic::coro_resume,
90+
Intrinsic::coro_save,
91+
Intrinsic::coro_subfn_addr,
92+
Intrinsic::coro_suspend,
9893
};
9994

100-
#ifndef NDEBUG
101-
static bool isCoroutineIntrinsicName(StringRef Name) {
102-
return llvm::binary_search(CoroIntrinsics, Name);
103-
}
104-
#endif
105-
10695
bool coro::isSuspendBlock(BasicBlock *BB) {
10796
return isa<AnyCoroSuspendInst>(BB->front());
10897
}
10998

11099
bool coro::declaresAnyIntrinsic(const Module &M) {
111-
for (StringRef Name : CoroIntrinsics) {
112-
if (M.getNamedValue(Name))
113-
return true;
114-
}
115-
116-
return false;
100+
return declaresIntrinsics(M, NonOverloadedCoroIntrinsics);
117101
}
118102

119-
// Verifies if a module has named values listed. Also, in debug mode verifies
120-
// that names are intrinsic names.
121-
bool coro::declaresIntrinsics(const Module &M,
122-
const std::initializer_list<StringRef> List) {
123-
for (StringRef Name : List) {
124-
assert(isCoroutineIntrinsicName(Name) && "not a coroutine intrinsic");
125-
if (M.getNamedValue(Name))
126-
return true;
127-
}
103+
// Checks whether the module declares any of the listed intrinsics.
104+
bool coro::declaresIntrinsics(const Module &M, ArrayRef<Intrinsic::ID> List) {
105+
#ifndef NDEBUG
106+
for (Intrinsic::ID ID : List)
107+
assert(!Intrinsic::isOverloaded(ID) &&
108+
"Only non-overloaded intrinsics supported");
109+
#endif
128110

111+
for (Intrinsic::ID ID : List)
112+
if (Intrinsic::getDeclarationIfExists(&M, ID))
113+
return true;
129114
return false;
130115
}
131116

0 commit comments

Comments
 (0)