Skip to content

Commit 85c437a

Browse files
committed
[llvm][Coro] Lower coro.frame in CoroEarly instead of CoroSplit
1 parent 9f77c26 commit 85c437a

File tree

3 files changed

+25
-35
lines changed

3 files changed

+25
-35
lines changed

llvm/include/llvm/Transforms/Coroutines/CoroShape.h

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -78,17 +78,14 @@ struct Shape {
7878
}
7979

8080
// Scan the function and collect the above intrinsics for later processing
81-
void analyze(Function &F, SmallVectorImpl<CoroFrameInst *> &CoroFrames,
82-
SmallVectorImpl<CoroSaveInst *> &UnusedCoroSaves,
81+
void analyze(Function &F, SmallVectorImpl<CoroSaveInst *> &UnusedCoroSaves,
8382
CoroPromiseInst *&CoroPromise);
8483
// If for some reason, we were not able to find coro.begin, bailout.
85-
void invalidateCoroutine(Function &F,
86-
SmallVectorImpl<CoroFrameInst *> &CoroFrames);
84+
void invalidateCoroutine(Function &F);
8785
// Perform ABI related initial transformation
8886
void initABI();
8987
// Remove orphaned and unnecessary intrinsics
90-
void cleanCoroutine(SmallVectorImpl<CoroFrameInst *> &CoroFrames,
91-
SmallVectorImpl<CoroSaveInst *> &UnusedCoroSaves,
88+
void cleanCoroutine(SmallVectorImpl<CoroSaveInst *> &UnusedCoroSaves,
9289
CoroPromiseInst *CoroPromise);
9390

9491
// Field indexes for special fields in the switch lowering.
@@ -265,16 +262,15 @@ struct Shape {
265262

266263
Shape() = default;
267264
explicit Shape(Function &F) {
268-
SmallVector<CoroFrameInst *, 8> CoroFrames;
269265
SmallVector<CoroSaveInst *, 2> UnusedCoroSaves;
270266
CoroPromiseInst *CoroPromise = nullptr;
271267

272-
analyze(F, CoroFrames, UnusedCoroSaves, CoroPromise);
268+
analyze(F, UnusedCoroSaves, CoroPromise);
273269
if (!CoroBegin) {
274-
invalidateCoroutine(F, CoroFrames);
270+
invalidateCoroutine(F);
275271
return;
276272
}
277-
cleanCoroutine(CoroFrames, UnusedCoroSaves, CoroPromise);
273+
cleanCoroutine(UnusedCoroSaves, CoroPromise);
278274
}
279275
};
280276

llvm/lib/Transforms/Coroutines/CoroEarly.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,10 @@ class Lowerer : public coro::LowererBase {
2525
IRBuilder<> Builder;
2626
PointerType *const AnyResumeFnPtrTy;
2727
Constant *NoopCoro = nullptr;
28+
SmallVector<CoroFrameInst *, 8> CoroFrames;
2829

2930
void lowerResumeOrDestroy(CallBase &CB, CoroSubFnInst::ResumeKind);
31+
void lowerCoroFrames(Function &F, Value *CoroBegin);
3032
void lowerCoroPromise(CoroPromiseInst *Intrin);
3133
void lowerCoroDone(IntrinsicInst *II);
3234
void lowerCoroNoop(IntrinsicInst *II);
@@ -51,6 +53,18 @@ void Lowerer::lowerResumeOrDestroy(CallBase &CB,
5153
CB.setCallingConv(CallingConv::Fast);
5254
}
5355

56+
void Lowerer::lowerCoroFrames(Function &F, Value *CoroBegin) {
57+
// Lower with poison if we cannot find coro.begin
58+
if (CoroBegin == nullptr)
59+
CoroBegin = PoisonValue::get(PointerType::get(F.getContext(), 0));
60+
61+
for (CoroFrameInst *CF : CoroFrames) {
62+
CF->replaceAllUsesWith(CoroBegin);
63+
CF->eraseFromParent();
64+
}
65+
CoroFrames.clear();
66+
}
67+
5468
// Coroutine promise field is always at the fixed offset from the beginning of
5569
// the coroutine frame. i8* coro.promise(i8*, i1 from) intrinsic adds an offset
5670
// to a passed pointer to move from coroutine frame to coroutine promise and
@@ -257,6 +271,8 @@ void Lowerer::lowerEarlyIntrinsics(Function &F) {
257271
break;
258272
}
259273
}
274+
// The coro.frame intrinsic is always lowered to the result of coro.begin.
275+
lowerCoroFrames(F, CoroBegin);
260276

261277
if (CoroId) {
262278
// Make sure that all CoroFree reference the coro.id intrinsic.
@@ -282,8 +298,8 @@ static bool declaresCoroEarlyIntrinsics(const Module &M) {
282298
M, {"llvm.coro.id", "llvm.coro.id.retcon", "llvm.coro.id.retcon.once",
283299
"llvm.coro.id.async", "llvm.coro.destroy", "llvm.coro.done",
284300
"llvm.coro.end", "llvm.coro.end.async", "llvm.coro.noop",
285-
"llvm.coro.free", "llvm.coro.promise", "llvm.coro.resume",
286-
"llvm.coro.suspend"});
301+
"llvm.coro.frame", "llvm.coro.free", "llvm.coro.promise",
302+
"llvm.coro.resume", "llvm.coro.suspend"});
287303
}
288304

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

llvm/lib/Transforms/Coroutines/Coroutines.cpp

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,6 @@ static CoroSaveInst *createCoroSave(CoroBeginInst *CoroBegin,
191191

192192
// Collect "interesting" coroutine intrinsics.
193193
void coro::Shape::analyze(Function &F,
194-
SmallVectorImpl<CoroFrameInst *> &CoroFrames,
195194
SmallVectorImpl<CoroSaveInst *> &UnusedCoroSaves,
196195
CoroPromiseInst *&CoroPromise) {
197196
clear();
@@ -215,9 +214,6 @@ void coro::Shape::analyze(Function &F,
215214
case Intrinsic::coro_align:
216215
CoroAligns.push_back(cast<CoroAlignInst>(II));
217216
break;
218-
case Intrinsic::coro_frame:
219-
CoroFrames.push_back(cast<CoroFrameInst>(II));
220-
break;
221217
case Intrinsic::coro_save:
222218
// After optimizations, coro_suspends using this coro_save might have
223219
// been removed, remember orphaned coro_saves to remove them later.
@@ -351,19 +347,9 @@ void coro::Shape::analyze(Function &F,
351347
}
352348

353349
// If for some reason, we were not able to find coro.begin, bailout.
354-
void coro::Shape::invalidateCoroutine(
355-
Function &F, SmallVectorImpl<CoroFrameInst *> &CoroFrames) {
350+
void coro::Shape::invalidateCoroutine(Function &F) {
356351
assert(!CoroBegin);
357352
{
358-
// Replace coro.frame which are supposed to be lowered to the result of
359-
// coro.begin with poison.
360-
auto *Poison = PoisonValue::get(PointerType::get(F.getContext(), 0));
361-
for (CoroFrameInst *CF : CoroFrames) {
362-
CF->replaceAllUsesWith(Poison);
363-
CF->eraseFromParent();
364-
}
365-
CoroFrames.clear();
366-
367353
// Replace all coro.suspend with poison and remove related coro.saves if
368354
// present.
369355
for (AnyCoroSuspendInst *CS : CoroSuspends) {
@@ -482,15 +468,7 @@ void coro::AnyRetconABI::init() {
482468
}
483469

484470
void coro::Shape::cleanCoroutine(
485-
SmallVectorImpl<CoroFrameInst *> &CoroFrames,
486471
SmallVectorImpl<CoroSaveInst *> &UnusedCoroSaves, CoroPromiseInst *PI) {
487-
// The coro.frame intrinsic is always lowered to the result of coro.begin.
488-
for (CoroFrameInst *CF : CoroFrames) {
489-
CF->replaceAllUsesWith(CoroBegin);
490-
CF->eraseFromParent();
491-
}
492-
CoroFrames.clear();
493-
494472
// Remove orphaned coro.saves.
495473
for (CoroSaveInst *CoroSave : UnusedCoroSaves)
496474
CoroSave->eraseFromParent();

0 commit comments

Comments
 (0)