[llvm] [llvm][Coro] Lower coro.frame in CoroEarly instead of CoroSplit (PR #137976)
Weibo He via llvm-commits
llvm-commits at lists.llvm.org
Fri May 16 05:38:50 PDT 2025
https://github.com/NewSigma updated https://github.com/llvm/llvm-project/pull/137976
>From 85c437a132098d4a157a5822fe621d0337a4210e Mon Sep 17 00:00:00 2001
From: NewSigma <NewSigma at 163.com>
Date: Fri, 16 May 2025 17:34:34 +0800
Subject: [PATCH] [llvm][Coro] Lower coro.frame in CoroEarly instead of
CoroSplit
---
.../llvm/Transforms/Coroutines/CoroShape.h | 16 +++++--------
llvm/lib/Transforms/Coroutines/CoroEarly.cpp | 20 ++++++++++++++--
llvm/lib/Transforms/Coroutines/Coroutines.cpp | 24 +------------------
3 files changed, 25 insertions(+), 35 deletions(-)
diff --git a/llvm/include/llvm/Transforms/Coroutines/CoroShape.h b/llvm/include/llvm/Transforms/Coroutines/CoroShape.h
index 891774b446571..038fc28903981 100644
--- a/llvm/include/llvm/Transforms/Coroutines/CoroShape.h
+++ b/llvm/include/llvm/Transforms/Coroutines/CoroShape.h
@@ -78,17 +78,14 @@ struct Shape {
}
// Scan the function and collect the above intrinsics for later processing
- void analyze(Function &F, SmallVectorImpl<CoroFrameInst *> &CoroFrames,
- SmallVectorImpl<CoroSaveInst *> &UnusedCoroSaves,
+ void analyze(Function &F, SmallVectorImpl<CoroSaveInst *> &UnusedCoroSaves,
CoroPromiseInst *&CoroPromise);
// If for some reason, we were not able to find coro.begin, bailout.
- void invalidateCoroutine(Function &F,
- SmallVectorImpl<CoroFrameInst *> &CoroFrames);
+ void invalidateCoroutine(Function &F);
// Perform ABI related initial transformation
void initABI();
// Remove orphaned and unnecessary intrinsics
- void cleanCoroutine(SmallVectorImpl<CoroFrameInst *> &CoroFrames,
- SmallVectorImpl<CoroSaveInst *> &UnusedCoroSaves,
+ void cleanCoroutine(SmallVectorImpl<CoroSaveInst *> &UnusedCoroSaves,
CoroPromiseInst *CoroPromise);
// Field indexes for special fields in the switch lowering.
@@ -265,16 +262,15 @@ struct Shape {
Shape() = default;
explicit Shape(Function &F) {
- SmallVector<CoroFrameInst *, 8> CoroFrames;
SmallVector<CoroSaveInst *, 2> UnusedCoroSaves;
CoroPromiseInst *CoroPromise = nullptr;
- analyze(F, CoroFrames, UnusedCoroSaves, CoroPromise);
+ analyze(F, UnusedCoroSaves, CoroPromise);
if (!CoroBegin) {
- invalidateCoroutine(F, CoroFrames);
+ invalidateCoroutine(F);
return;
}
- cleanCoroutine(CoroFrames, UnusedCoroSaves, CoroPromise);
+ cleanCoroutine(UnusedCoroSaves, CoroPromise);
}
};
diff --git a/llvm/lib/Transforms/Coroutines/CoroEarly.cpp b/llvm/lib/Transforms/Coroutines/CoroEarly.cpp
index eea6dfba14e37..717e1bfc1a074 100644
--- a/llvm/lib/Transforms/Coroutines/CoroEarly.cpp
+++ b/llvm/lib/Transforms/Coroutines/CoroEarly.cpp
@@ -25,8 +25,10 @@ class Lowerer : public coro::LowererBase {
IRBuilder<> Builder;
PointerType *const AnyResumeFnPtrTy;
Constant *NoopCoro = nullptr;
+ SmallVector<CoroFrameInst *, 8> CoroFrames;
void lowerResumeOrDestroy(CallBase &CB, CoroSubFnInst::ResumeKind);
+ void lowerCoroFrames(Function &F, Value *CoroBegin);
void lowerCoroPromise(CoroPromiseInst *Intrin);
void lowerCoroDone(IntrinsicInst *II);
void lowerCoroNoop(IntrinsicInst *II);
@@ -51,6 +53,18 @@ void Lowerer::lowerResumeOrDestroy(CallBase &CB,
CB.setCallingConv(CallingConv::Fast);
}
+void Lowerer::lowerCoroFrames(Function &F, Value *CoroBegin) {
+ // Lower with poison if we cannot find coro.begin
+ if (CoroBegin == nullptr)
+ CoroBegin = PoisonValue::get(PointerType::get(F.getContext(), 0));
+
+ for (CoroFrameInst *CF : CoroFrames) {
+ CF->replaceAllUsesWith(CoroBegin);
+ CF->eraseFromParent();
+ }
+ CoroFrames.clear();
+}
+
// Coroutine promise field is always at the fixed offset from the beginning of
// the coroutine frame. i8* coro.promise(i8*, i1 from) intrinsic adds an offset
// to a passed pointer to move from coroutine frame to coroutine promise and
@@ -257,6 +271,8 @@ void Lowerer::lowerEarlyIntrinsics(Function &F) {
break;
}
}
+ // The coro.frame intrinsic is always lowered to the result of coro.begin.
+ lowerCoroFrames(F, CoroBegin);
if (CoroId) {
// Make sure that all CoroFree reference the coro.id intrinsic.
@@ -282,8 +298,8 @@ static bool declaresCoroEarlyIntrinsics(const Module &M) {
M, {"llvm.coro.id", "llvm.coro.id.retcon", "llvm.coro.id.retcon.once",
"llvm.coro.id.async", "llvm.coro.destroy", "llvm.coro.done",
"llvm.coro.end", "llvm.coro.end.async", "llvm.coro.noop",
- "llvm.coro.free", "llvm.coro.promise", "llvm.coro.resume",
- "llvm.coro.suspend"});
+ "llvm.coro.frame", "llvm.coro.free", "llvm.coro.promise",
+ "llvm.coro.resume", "llvm.coro.suspend"});
}
PreservedAnalyses CoroEarlyPass::run(Module &M, ModuleAnalysisManager &) {
diff --git a/llvm/lib/Transforms/Coroutines/Coroutines.cpp b/llvm/lib/Transforms/Coroutines/Coroutines.cpp
index 02500ff778b80..b9b0d135e37b3 100644
--- a/llvm/lib/Transforms/Coroutines/Coroutines.cpp
+++ b/llvm/lib/Transforms/Coroutines/Coroutines.cpp
@@ -191,7 +191,6 @@ static CoroSaveInst *createCoroSave(CoroBeginInst *CoroBegin,
// Collect "interesting" coroutine intrinsics.
void coro::Shape::analyze(Function &F,
- SmallVectorImpl<CoroFrameInst *> &CoroFrames,
SmallVectorImpl<CoroSaveInst *> &UnusedCoroSaves,
CoroPromiseInst *&CoroPromise) {
clear();
@@ -215,9 +214,6 @@ void coro::Shape::analyze(Function &F,
case Intrinsic::coro_align:
CoroAligns.push_back(cast<CoroAlignInst>(II));
break;
- case Intrinsic::coro_frame:
- CoroFrames.push_back(cast<CoroFrameInst>(II));
- break;
case Intrinsic::coro_save:
// After optimizations, coro_suspends using this coro_save might have
// been removed, remember orphaned coro_saves to remove them later.
@@ -351,19 +347,9 @@ void coro::Shape::analyze(Function &F,
}
// If for some reason, we were not able to find coro.begin, bailout.
-void coro::Shape::invalidateCoroutine(
- Function &F, SmallVectorImpl<CoroFrameInst *> &CoroFrames) {
+void coro::Shape::invalidateCoroutine(Function &F) {
assert(!CoroBegin);
{
- // Replace coro.frame which are supposed to be lowered to the result of
- // coro.begin with poison.
- auto *Poison = PoisonValue::get(PointerType::get(F.getContext(), 0));
- for (CoroFrameInst *CF : CoroFrames) {
- CF->replaceAllUsesWith(Poison);
- CF->eraseFromParent();
- }
- CoroFrames.clear();
-
// Replace all coro.suspend with poison and remove related coro.saves if
// present.
for (AnyCoroSuspendInst *CS : CoroSuspends) {
@@ -482,15 +468,7 @@ void coro::AnyRetconABI::init() {
}
void coro::Shape::cleanCoroutine(
- SmallVectorImpl<CoroFrameInst *> &CoroFrames,
SmallVectorImpl<CoroSaveInst *> &UnusedCoroSaves, CoroPromiseInst *PI) {
- // The coro.frame intrinsic is always lowered to the result of coro.begin.
- for (CoroFrameInst *CF : CoroFrames) {
- CF->replaceAllUsesWith(CoroBegin);
- CF->eraseFromParent();
- }
- CoroFrames.clear();
-
// Remove orphaned coro.saves.
for (CoroSaveInst *CoroSave : UnusedCoroSaves)
CoroSave->eraseFromParent();
More information about the llvm-commits
mailing list