3232#include " llvm/Analysis/CFG.h"
3333#include " llvm/Analysis/CallGraph.h"
3434#include " llvm/Analysis/ConstantFolding.h"
35+ #include " llvm/Analysis/DebugInfoCache.h"
3536#include " llvm/Analysis/LazyCallGraph.h"
3637#include " llvm/Analysis/OptimizationRemarkEmitter.h"
3738#include " llvm/Analysis/TargetTransformInfo.h"
@@ -79,15 +80,39 @@ using namespace llvm;
7980#define DEBUG_TYPE " coro-split"
8081
8182namespace {
83+ const DebugInfoFinder *cachedDIFinder (Function &F,
84+ const DebugInfoCache *DICache) {
85+ if (!DICache)
86+ return nullptr ;
87+
88+ auto *SP = F.getSubprogram ();
89+ auto *CU = SP ? SP->getUnit () : nullptr ;
90+ if (!CU)
91+ return nullptr ;
92+
93+ auto Found = DICache->Result .find (CU);
94+ if (Found == DICache->Result .end ())
95+ return nullptr ;
96+
97+ return &Found->getSecond ();
98+ }
99+
82100// / Collect (a known) subset of global debug info metadata potentially used by
83101// / the function \p F.
84102// /
85103// / This metadata set can be used to avoid cloning debug info not owned by \p F
86104// / and is shared among all potential clones \p F.
87- void collectGlobalDebugInfo (Function &F, MetadataSetTy &GlobalDebugInfo) {
105+ void collectGlobalDebugInfo (Function &F, MetadataSetTy &GlobalDebugInfo,
106+ const DebugInfoCache *DICache) {
88107 TimeTraceScope FunctionScope (" CollectGlobalDebugInfo" );
89108
90109 DebugInfoFinder DIFinder;
110+
111+ // Copy DIFinder from cache which is primed on F's compile unit when available
112+ auto *PrimedDIFinder = cachedDIFinder (F, DICache);
113+ if (PrimedDIFinder)
114+ DIFinder = *PrimedDIFinder;
115+
91116 DISubprogram *SPClonedWithinModule = CollectDebugInfoForCloning (
92117 F, CloneFunctionChangeType::LocalChangesOnly, DIFinder);
93118
@@ -1394,11 +1419,11 @@ namespace {
13941419struct SwitchCoroutineSplitter {
13951420 static void split (Function &F, coro::Shape &Shape,
13961421 SmallVectorImpl<Function *> &Clones,
1397- TargetTransformInfo &TTI) {
1422+ TargetTransformInfo &TTI, const DebugInfoCache *DICache ) {
13981423 assert (Shape.ABI == coro::ABI::Switch);
13991424
14001425 MetadataSetTy GlobalDebugInfo;
1401- collectGlobalDebugInfo (F, GlobalDebugInfo);
1426+ collectGlobalDebugInfo (F, GlobalDebugInfo, DICache );
14021427
14031428 // Create a resume clone by cloning the body of the original function,
14041429 // setting new entry block and replacing coro.suspend an appropriate value
@@ -1712,7 +1737,8 @@ CallInst *coro::createMustTailCall(DebugLoc Loc, Function *MustTailCallFn,
17121737
17131738void coro::AsyncABI::splitCoroutine (Function &F, coro::Shape &Shape,
17141739 SmallVectorImpl<Function *> &Clones,
1715- TargetTransformInfo &TTI) {
1740+ TargetTransformInfo &TTI,
1741+ const DebugInfoCache *DICache) {
17161742 assert (Shape.ABI == coro::ABI::Async);
17171743 assert (Clones.empty ());
17181744 // Reset various things that the optimizer might have decided it
@@ -1799,7 +1825,7 @@ void coro::AsyncABI::splitCoroutine(Function &F, coro::Shape &Shape,
17991825 assert (Clones.size () == Shape.CoroSuspends .size ());
18001826
18011827 MetadataSetTy GlobalDebugInfo;
1802- collectGlobalDebugInfo (F, GlobalDebugInfo);
1828+ collectGlobalDebugInfo (F, GlobalDebugInfo, DICache );
18031829
18041830 for (auto [Idx, CS] : llvm::enumerate (Shape.CoroSuspends )) {
18051831 auto *Suspend = CS;
@@ -1812,7 +1838,8 @@ void coro::AsyncABI::splitCoroutine(Function &F, coro::Shape &Shape,
18121838
18131839void coro::AnyRetconABI::splitCoroutine (Function &F, coro::Shape &Shape,
18141840 SmallVectorImpl<Function *> &Clones,
1815- TargetTransformInfo &TTI) {
1841+ TargetTransformInfo &TTI,
1842+ const DebugInfoCache *DICache) {
18161843 assert (Shape.ABI == coro::ABI::Retcon || Shape.ABI == coro::ABI::RetconOnce);
18171844 assert (Clones.empty ());
18181845
@@ -1934,7 +1961,7 @@ void coro::AnyRetconABI::splitCoroutine(Function &F, coro::Shape &Shape,
19341961 assert (Clones.size () == Shape.CoroSuspends .size ());
19351962
19361963 MetadataSetTy GlobalDebugInfo;
1937- collectGlobalDebugInfo (F, GlobalDebugInfo);
1964+ collectGlobalDebugInfo (F, GlobalDebugInfo, DICache );
19381965
19391966 for (auto [Idx, CS] : llvm::enumerate (Shape.CoroSuspends )) {
19401967 auto Suspend = CS;
@@ -1988,13 +2015,15 @@ static bool hasSafeElideCaller(Function &F) {
19882015
19892016void coro::SwitchABI::splitCoroutine (Function &F, coro::Shape &Shape,
19902017 SmallVectorImpl<Function *> &Clones,
1991- TargetTransformInfo &TTI) {
1992- SwitchCoroutineSplitter::split (F, Shape, Clones, TTI);
2018+ TargetTransformInfo &TTI,
2019+ const DebugInfoCache *DICache) {
2020+ SwitchCoroutineSplitter::split (F, Shape, Clones, TTI, DICache);
19932021}
19942022
19952023static void doSplitCoroutine (Function &F, SmallVectorImpl<Function *> &Clones,
19962024 coro::BaseABI &ABI, TargetTransformInfo &TTI,
1997- bool OptimizeFrame) {
2025+ bool OptimizeFrame,
2026+ const DebugInfoCache *DICache) {
19982027 PrettyStackTraceFunction prettyStackTrace (F);
19992028
20002029 auto &Shape = ABI.Shape ;
@@ -2019,7 +2048,7 @@ static void doSplitCoroutine(Function &F, SmallVectorImpl<Function *> &Clones,
20192048 if (isNoSuspendCoroutine) {
20202049 handleNoSuspendCoroutine (Shape);
20212050 } else {
2022- ABI.splitCoroutine (F, Shape, Clones, TTI);
2051+ ABI.splitCoroutine (F, Shape, Clones, TTI, DICache );
20232052 }
20242053
20252054 // Replace all the swifterror operations in the original function.
@@ -2216,6 +2245,9 @@ PreservedAnalyses CoroSplitPass::run(LazyCallGraph::SCC &C,
22162245 auto &FAM =
22172246 AM.getResult <FunctionAnalysisManagerCGSCCProxy>(C, CG).getManager ();
22182247
2248+ const auto &MAMProxy = AM.getResult <ModuleAnalysisManagerCGSCCProxy>(C, CG);
2249+ const auto *DICache = MAMProxy.getCachedResult <DebugInfoCacheAnalysis>(M);
2250+
22192251 // Check for uses of llvm.coro.prepare.retcon/async.
22202252 SmallVector<Function *, 2 > PrepareFns;
22212253 addPrepareFunction (M, PrepareFns, " llvm.coro.prepare.retcon" );
@@ -2252,7 +2284,7 @@ PreservedAnalyses CoroSplitPass::run(LazyCallGraph::SCC &C,
22522284
22532285 SmallVector<Function *, 4 > Clones;
22542286 auto &TTI = FAM.getResult <TargetIRAnalysis>(F);
2255- doSplitCoroutine (F, Clones, *ABI, TTI, OptimizeFrame);
2287+ doSplitCoroutine (F, Clones, *ABI, TTI, OptimizeFrame, DICache );
22562288 CurrentSCC = &updateCallGraphAfterCoroutineSplit (
22572289 *N, Shape, Clones, *CurrentSCC, CG, AM, UR, FAM);
22582290
0 commit comments