3131#include " llvm/Analysis/CFG.h"
3232#include " llvm/Analysis/CallGraph.h"
3333#include " llvm/Analysis/ConstantFolding.h"
34+ #include " llvm/Analysis/DebugInfoCache.h"
3435#include " llvm/Analysis/LazyCallGraph.h"
3536#include " llvm/Analysis/OptimizationRemarkEmitter.h"
3637#include " llvm/Analysis/TargetTransformInfo.h"
@@ -85,15 +86,39 @@ using namespace llvm;
8586
8687namespace {
8788
89+ const DebugInfoFinder *cachedDIFinder (Function &F,
90+ const DebugInfoCache *DICache) {
91+ if (!DICache)
92+ return nullptr ;
93+
94+ auto *SP = F.getSubprogram ();
95+ auto *CU = SP ? SP->getUnit () : nullptr ;
96+ if (!CU)
97+ return nullptr ;
98+
99+ auto Found = DICache->Result .find (CU);
100+ if (Found == DICache->Result .end ())
101+ return nullptr ;
102+
103+ return &Found->getSecond ();
104+ }
105+
88106// / Collect (a known) subset of global debug info metadata potentially used by
89107// / the function \p F.
90108// /
91109// / This metadata set can be used to avoid cloning debug info not owned by \p F
92110// / and is shared among all potential clones \p F.
93- void collectGlobalDebugInfo (Function &F, MetadataSetTy &GlobalDebugInfo) {
111+ void collectGlobalDebugInfo (Function &F, MetadataSetTy &GlobalDebugInfo,
112+ const DebugInfoCache *DICache) {
94113 TimeTraceScope FunctionScope (" CollectGlobalDebugInfo" );
95114
96115 DebugInfoFinder DIFinder;
116+
117+ // Copy DIFinder from cache which is primed on F's compile unit when available
118+ auto *PrimedDIFinder = cachedDIFinder (F, DICache);
119+ if (PrimedDIFinder)
120+ DIFinder = *PrimedDIFinder;
121+
97122 DISubprogram *SPClonedWithinModule = CollectDebugInfoForCloning (
98123 F, CloneFunctionChangeType::LocalChangesOnly, DIFinder);
99124
@@ -1517,11 +1542,11 @@ namespace {
15171542struct SwitchCoroutineSplitter {
15181543 static void split (Function &F, coro::Shape &Shape,
15191544 SmallVectorImpl<Function *> &Clones,
1520- TargetTransformInfo &TTI) {
1545+ TargetTransformInfo &TTI, const DebugInfoCache *DICache ) {
15211546 assert (Shape.ABI == coro::ABI::Switch);
15221547
15231548 MetadataSetTy GlobalDebugInfo;
1524- collectGlobalDebugInfo (F, GlobalDebugInfo);
1549+ collectGlobalDebugInfo (F, GlobalDebugInfo, DICache );
15251550
15261551 // Create a resume clone by cloning the body of the original function,
15271552 // setting new entry block and replacing coro.suspend an appropriate value
@@ -1835,7 +1860,8 @@ CallInst *coro::createMustTailCall(DebugLoc Loc, Function *MustTailCallFn,
18351860
18361861void coro::AsyncABI::splitCoroutine (Function &F, coro::Shape &Shape,
18371862 SmallVectorImpl<Function *> &Clones,
1838- TargetTransformInfo &TTI) {
1863+ TargetTransformInfo &TTI,
1864+ const DebugInfoCache *DICache) {
18391865 assert (Shape.ABI == coro::ABI::Async);
18401866 assert (Clones.empty ());
18411867 // Reset various things that the optimizer might have decided it
@@ -1922,7 +1948,7 @@ void coro::AsyncABI::splitCoroutine(Function &F, coro::Shape &Shape,
19221948 assert (Clones.size () == Shape.CoroSuspends .size ());
19231949
19241950 MetadataSetTy GlobalDebugInfo;
1925- collectGlobalDebugInfo (F, GlobalDebugInfo);
1951+ collectGlobalDebugInfo (F, GlobalDebugInfo, DICache );
19261952
19271953 for (auto CS : llvm::enumerate (Shape.CoroSuspends )) {
19281954 auto *Suspend = CS.value ();
@@ -1935,7 +1961,8 @@ void coro::AsyncABI::splitCoroutine(Function &F, coro::Shape &Shape,
19351961
19361962void coro::AnyRetconABI::splitCoroutine (Function &F, coro::Shape &Shape,
19371963 SmallVectorImpl<Function *> &Clones,
1938- TargetTransformInfo &TTI) {
1964+ TargetTransformInfo &TTI,
1965+ const DebugInfoCache *DICache) {
19391966 assert (Shape.ABI == coro::ABI::Retcon || Shape.ABI == coro::ABI::RetconOnce);
19401967 assert (Clones.empty ());
19411968
@@ -2057,7 +2084,7 @@ void coro::AnyRetconABI::splitCoroutine(Function &F, coro::Shape &Shape,
20572084 assert (Clones.size () == Shape.CoroSuspends .size ());
20582085
20592086 MetadataSetTy GlobalDebugInfo;
2060- collectGlobalDebugInfo (F, GlobalDebugInfo);
2087+ collectGlobalDebugInfo (F, GlobalDebugInfo, DICache );
20612088
20622089 for (auto CS : llvm::enumerate (Shape.CoroSuspends )) {
20632090 auto Suspend = CS.value ();
@@ -2111,13 +2138,15 @@ static bool hasSafeElideCaller(Function &F) {
21112138
21122139void coro::SwitchABI::splitCoroutine (Function &F, coro::Shape &Shape,
21132140 SmallVectorImpl<Function *> &Clones,
2114- TargetTransformInfo &TTI) {
2115- SwitchCoroutineSplitter::split (F, Shape, Clones, TTI);
2141+ TargetTransformInfo &TTI,
2142+ const DebugInfoCache *DICache) {
2143+ SwitchCoroutineSplitter::split (F, Shape, Clones, TTI, DICache);
21162144}
21172145
21182146static void doSplitCoroutine (Function &F, SmallVectorImpl<Function *> &Clones,
21192147 coro::BaseABI &ABI, TargetTransformInfo &TTI,
2120- bool OptimizeFrame) {
2148+ bool OptimizeFrame,
2149+ const DebugInfoCache *DICache) {
21212150 PrettyStackTraceFunction prettyStackTrace (F);
21222151
21232152 auto &Shape = ABI.Shape ;
@@ -2142,7 +2171,7 @@ static void doSplitCoroutine(Function &F, SmallVectorImpl<Function *> &Clones,
21422171 if (isNoSuspendCoroutine) {
21432172 handleNoSuspendCoroutine (Shape);
21442173 } else {
2145- ABI.splitCoroutine (F, Shape, Clones, TTI);
2174+ ABI.splitCoroutine (F, Shape, Clones, TTI, DICache );
21462175 }
21472176
21482177 // Replace all the swifterror operations in the original function.
@@ -2339,6 +2368,9 @@ PreservedAnalyses CoroSplitPass::run(LazyCallGraph::SCC &C,
23392368 auto &FAM =
23402369 AM.getResult <FunctionAnalysisManagerCGSCCProxy>(C, CG).getManager ();
23412370
2371+ const auto &MAMProxy = AM.getResult <ModuleAnalysisManagerCGSCCProxy>(C, CG);
2372+ const auto *DICache = MAMProxy.getCachedResult <DebugInfoCacheAnalysis>(M);
2373+
23422374 // Check for uses of llvm.coro.prepare.retcon/async.
23432375 SmallVector<Function *, 2 > PrepareFns;
23442376 addPrepareFunction (M, PrepareFns, " llvm.coro.prepare.retcon" );
@@ -2375,7 +2407,7 @@ PreservedAnalyses CoroSplitPass::run(LazyCallGraph::SCC &C,
23752407
23762408 SmallVector<Function *, 4 > Clones;
23772409 auto &TTI = FAM.getResult <TargetIRAnalysis>(F);
2378- doSplitCoroutine (F, Clones, *ABI, TTI, OptimizeFrame);
2410+ doSplitCoroutine (F, Clones, *ABI, TTI, OptimizeFrame, DICache );
23792411 CurrentSCC = &updateCallGraphAfterCoroutineSplit (
23802412 *N, Shape, Clones, *CurrentSCC, CG, AM, UR, FAM);
23812413
0 commit comments