From 86dd52c644b8a04cd56e61af66a34ad439a7a01e Mon Sep 17 00:00:00 2001 From: NewSigma Date: Tue, 3 Jun 2025 11:15:39 +0800 Subject: [PATCH 1/4] Erase lifetime intrinsics for spilled allocas --- llvm/lib/Transforms/Coroutines/CoroFrame.cpp | 25 +++++++++++--------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp index 2f5f1089067bf..fdfddcc3425e9 100644 --- a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp @@ -1212,14 +1212,26 @@ static void insertSpills(const FrameDataInfo &FrameData, coro::Shape &Shape) { Builder.SetInsertPoint(Shape.AllocaSpillBlock, Shape.AllocaSpillBlock->begin()); SmallVector UsersToUpdate; + SmallVector Lifetimes; for (const auto &A : FrameData.Allocas) { AllocaInst *Alloca = A.Alloca; UsersToUpdate.clear(); + Lifetimes.clear(); for (User *U : Alloca->users()) { auto *I = cast(U); - if (DT.dominates(Shape.CoroBegin, I)) + if (I->isLifetimeStartOrEnd()) + Lifetimes.push_back(I); + else if (DT.dominates(Shape.CoroBegin, I)) UsersToUpdate.push_back(I); } + + // If it is hard to analyze, we will give up and put allocas to frame, + // even if they never cross suspend points. + // Lifetime intrinsics referring to alloca may fail guard storing to frame. + // Lifetime intrinsics referring to frames may block further optimizations. + for (auto *I : Lifetimes) + I->eraseFromParent(); + if (UsersToUpdate.empty()) continue; auto *G = GetFramePointer(Alloca); @@ -1233,17 +1245,8 @@ static void insertSpills(const FrameDataInfo &FrameData, coro::Shape &Shape) { for (auto *DVR : DbgVariableRecords) DVR->replaceVariableLocationOp(Alloca, G); - for (Instruction *I : UsersToUpdate) { - // It is meaningless to retain the lifetime intrinsics refer for the - // member of coroutine frames and the meaningless lifetime intrinsics - // are possible to block further optimizations. - if (I->isLifetimeStartOrEnd()) { - I->eraseFromParent(); - continue; - } - + for (Instruction *I : UsersToUpdate) I->replaceUsesOfWith(Alloca, G); - } } Builder.SetInsertPoint(&*Shape.getInsertPtAfterFramePtr()); for (const auto &A : FrameData.Allocas) { From d3692f3207a9d096de89c0906758b91103f5b902 Mon Sep 17 00:00:00 2001 From: NewSigma Date: Tue, 3 Jun 2025 15:46:30 +0800 Subject: [PATCH 2/4] Keep original comments --- llvm/lib/Transforms/Coroutines/CoroFrame.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp index fdfddcc3425e9..c2afa559e4aaf 100644 --- a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp @@ -1226,9 +1226,12 @@ static void insertSpills(const FrameDataInfo &FrameData, coro::Shape &Shape) { } // If it is hard to analyze, we will give up and put allocas to frame, - // even if they never cross suspend points. - // Lifetime intrinsics referring to alloca may fail guard storing to frame. - // Lifetime intrinsics referring to frames may block further optimizations. + // even if they never cross suspend points.Lifetime intrinsics referring + // to alloca may fail guard storing to frame. + // + // It is meaningless to retain the lifetime intrinsics refer for the + // member of coroutine frames and the meaningless lifetime intrinsics + // are possible to block further optimizations. for (auto *I : Lifetimes) I->eraseFromParent(); From a735ee537252202016b51369bac0121b038e50d9 Mon Sep 17 00:00:00 2001 From: Weibo He Date: Tue, 3 Jun 2025 15:58:20 +0800 Subject: [PATCH 3/4] Update llvm/lib/Transforms/Coroutines/CoroFrame.cpp Co-authored-by: Chuanqi Xu --- llvm/lib/Transforms/Coroutines/CoroFrame.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp index c2afa559e4aaf..1fd42efe7bbf9 100644 --- a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp @@ -1225,10 +1225,6 @@ static void insertSpills(const FrameDataInfo &FrameData, coro::Shape &Shape) { UsersToUpdate.push_back(I); } - // If it is hard to analyze, we will give up and put allocas to frame, - // even if they never cross suspend points.Lifetime intrinsics referring - // to alloca may fail guard storing to frame. - // // It is meaningless to retain the lifetime intrinsics refer for the // member of coroutine frames and the meaningless lifetime intrinsics // are possible to block further optimizations. From 8aa52a4edfdcc1e1ceb624ba908b36ba76b4a70d Mon Sep 17 00:00:00 2001 From: NewSigma Date: Tue, 3 Jun 2025 16:33:15 +0800 Subject: [PATCH 4/4] Erase lifetimes directly --- llvm/lib/Transforms/Coroutines/CoroFrame.cpp | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp index 1fd42efe7bbf9..53d78edda2e9f 100644 --- a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp @@ -1212,25 +1212,20 @@ static void insertSpills(const FrameDataInfo &FrameData, coro::Shape &Shape) { Builder.SetInsertPoint(Shape.AllocaSpillBlock, Shape.AllocaSpillBlock->begin()); SmallVector UsersToUpdate; - SmallVector Lifetimes; for (const auto &A : FrameData.Allocas) { AllocaInst *Alloca = A.Alloca; UsersToUpdate.clear(); - Lifetimes.clear(); - for (User *U : Alloca->users()) { + for (User *U : make_early_inc_range(Alloca->users())) { auto *I = cast(U); + // It is meaningless to retain the lifetime intrinsics refer for the + // member of coroutine frames and the meaningless lifetime intrinsics + // are possible to block further optimizations. if (I->isLifetimeStartOrEnd()) - Lifetimes.push_back(I); + I->eraseFromParent(); else if (DT.dominates(Shape.CoroBegin, I)) UsersToUpdate.push_back(I); } - // It is meaningless to retain the lifetime intrinsics refer for the - // member of coroutine frames and the meaningless lifetime intrinsics - // are possible to block further optimizations. - for (auto *I : Lifetimes) - I->eraseFromParent(); - if (UsersToUpdate.empty()) continue; auto *G = GetFramePointer(Alloca);