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,16 +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+ if (auto Found = DICache->Result .find (CU); Found != DICache->Result .end ())
94+ return &Found->getSecond ();
95+
96+ return nullptr ;
97+ }
98+
8299// / Collect (a known) subset of global debug info metadata potentially used by
83100// / the function \p F.
84101// /
85102// / This metadata set can be used to avoid cloning debug info not owned by \p F
86103// / and is shared among all potential clones \p F.
87- MetadataSetTy collectCommonDebugInfo (Function &F) {
104+ MetadataSetTy collectCommonDebugInfo (Function &F,
105+ const DebugInfoCache *DICache) {
88106 TimeTraceScope FunctionScope (" CollectCommonDebugInfo" );
89107
90108 MetadataSetTy CommonDebugInfo;
91109 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+
92116 DISubprogram *SPClonedWithinModule = CollectDebugInfoForCloning (
93117 F, CloneFunctionChangeType::LocalChangesOnly, DIFinder);
94118
@@ -1396,10 +1420,10 @@ namespace {
13961420struct SwitchCoroutineSplitter {
13971421 static void split (Function &F, coro::Shape &Shape,
13981422 SmallVectorImpl<Function *> &Clones,
1399- TargetTransformInfo &TTI) {
1423+ TargetTransformInfo &TTI, const DebugInfoCache *DICache ) {
14001424 assert (Shape.ABI == coro::ABI::Switch);
14011425
1402- MetadataSetTy CommonDebugInfo{collectCommonDebugInfo (F)};
1426+ MetadataSetTy CommonDebugInfo{collectCommonDebugInfo (F, DICache )};
14031427
14041428 // Create a resume clone by cloning the body of the original function,
14051429 // setting new entry block and replacing coro.suspend an appropriate value
@@ -1713,7 +1737,8 @@ CallInst *coro::createMustTailCall(DebugLoc Loc, Function *MustTailCallFn,
17131737
17141738void coro::AsyncABI::splitCoroutine (Function &F, coro::Shape &Shape,
17151739 SmallVectorImpl<Function *> &Clones,
1716- TargetTransformInfo &TTI) {
1740+ TargetTransformInfo &TTI,
1741+ const DebugInfoCache *DICache) {
17171742 assert (Shape.ABI == coro::ABI::Async);
17181743 assert (Clones.empty ());
17191744 // Reset various things that the optimizer might have decided it
@@ -1799,7 +1824,7 @@ void coro::AsyncABI::splitCoroutine(Function &F, coro::Shape &Shape,
17991824
18001825 assert (Clones.size () == Shape.CoroSuspends .size ());
18011826
1802- MetadataSetTy CommonDebugInfo{collectCommonDebugInfo (F)};
1827+ MetadataSetTy CommonDebugInfo{collectCommonDebugInfo (F, DICache )};
18031828
18041829 for (auto [Idx, CS] : llvm::enumerate (Shape.CoroSuspends )) {
18051830 auto *Suspend = CS;
@@ -1812,7 +1837,8 @@ void coro::AsyncABI::splitCoroutine(Function &F, coro::Shape &Shape,
18121837
18131838void coro::AnyRetconABI::splitCoroutine (Function &F, coro::Shape &Shape,
18141839 SmallVectorImpl<Function *> &Clones,
1815- TargetTransformInfo &TTI) {
1840+ TargetTransformInfo &TTI,
1841+ const DebugInfoCache *DICache) {
18161842 assert (Shape.ABI == coro::ABI::Retcon || Shape.ABI == coro::ABI::RetconOnce);
18171843 assert (Clones.empty ());
18181844
@@ -1933,7 +1959,7 @@ void coro::AnyRetconABI::splitCoroutine(Function &F, coro::Shape &Shape,
19331959
19341960 assert (Clones.size () == Shape.CoroSuspends .size ());
19351961
1936- MetadataSetTy CommonDebugInfo{collectCommonDebugInfo (F)};
1962+ MetadataSetTy CommonDebugInfo{collectCommonDebugInfo (F, DICache )};
19371963
19381964 for (auto [Idx, CS] : llvm::enumerate (Shape.CoroSuspends )) {
19391965 auto Suspend = CS;
@@ -1987,13 +2013,15 @@ static bool hasSafeElideCaller(Function &F) {
19872013
19882014void coro::SwitchABI::splitCoroutine (Function &F, coro::Shape &Shape,
19892015 SmallVectorImpl<Function *> &Clones,
1990- TargetTransformInfo &TTI) {
1991- SwitchCoroutineSplitter::split (F, Shape, Clones, TTI);
2016+ TargetTransformInfo &TTI,
2017+ const DebugInfoCache *DICache) {
2018+ SwitchCoroutineSplitter::split (F, Shape, Clones, TTI, DICache);
19922019}
19932020
19942021static void doSplitCoroutine (Function &F, SmallVectorImpl<Function *> &Clones,
19952022 coro::BaseABI &ABI, TargetTransformInfo &TTI,
1996- bool OptimizeFrame) {
2023+ bool OptimizeFrame,
2024+ const DebugInfoCache *DICache) {
19972025 PrettyStackTraceFunction prettyStackTrace (F);
19982026
19992027 auto &Shape = ABI.Shape ;
@@ -2018,7 +2046,7 @@ static void doSplitCoroutine(Function &F, SmallVectorImpl<Function *> &Clones,
20182046 if (isNoSuspendCoroutine) {
20192047 handleNoSuspendCoroutine (Shape);
20202048 } else {
2021- ABI.splitCoroutine (F, Shape, Clones, TTI);
2049+ ABI.splitCoroutine (F, Shape, Clones, TTI, DICache );
20222050 }
20232051
20242052 // Replace all the swifterror operations in the original function.
@@ -2215,6 +2243,9 @@ PreservedAnalyses CoroSplitPass::run(LazyCallGraph::SCC &C,
22152243 auto &FAM =
22162244 AM.getResult <FunctionAnalysisManagerCGSCCProxy>(C, CG).getManager ();
22172245
2246+ const auto &MAMProxy = AM.getResult <ModuleAnalysisManagerCGSCCProxy>(C, CG);
2247+ const auto *DICache = MAMProxy.getCachedResult <DebugInfoCacheAnalysis>(M);
2248+
22182249 // Check for uses of llvm.coro.prepare.retcon/async.
22192250 SmallVector<Function *, 2 > PrepareFns;
22202251 addPrepareFunction (M, PrepareFns, " llvm.coro.prepare.retcon" );
@@ -2251,7 +2282,7 @@ PreservedAnalyses CoroSplitPass::run(LazyCallGraph::SCC &C,
22512282
22522283 SmallVector<Function *, 4 > Clones;
22532284 auto &TTI = FAM.getResult <TargetIRAnalysis>(F);
2254- doSplitCoroutine (F, Clones, *ABI, TTI, OptimizeFrame);
2285+ doSplitCoroutine (F, Clones, *ABI, TTI, OptimizeFrame, DICache );
22552286 CurrentSCC = &updateCallGraphAfterCoroutineSplit (
22562287 *N, Shape, Clones, *CurrentSCC, CG, AM, UR, FAM);
22572288
0 commit comments