31
31
#include " llvm/Analysis/CFG.h"
32
32
#include " llvm/Analysis/CallGraph.h"
33
33
#include " llvm/Analysis/ConstantFolding.h"
34
+ #include " llvm/Analysis/DebugInfoCache.h"
34
35
#include " llvm/Analysis/LazyCallGraph.h"
35
36
#include " llvm/Analysis/OptimizationRemarkEmitter.h"
36
37
#include " llvm/Analysis/TargetTransformInfo.h"
@@ -85,15 +86,39 @@ using namespace llvm;
85
86
86
87
namespace {
87
88
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
+
88
106
// / Collect (a known) subset of global debug info metadata potentially used by
89
107
// / the function \p F.
90
108
// /
91
109
// / This metadata set can be used to avoid cloning debug info not owned by \p F
92
110
// / 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) {
94
113
TimeTraceScope FunctionScope (" CollectGlobalDebugInfo" );
95
114
96
115
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
+
97
122
DISubprogram *SPClonedWithinModule = CollectDebugInfoForCloning (
98
123
F, CloneFunctionChangeType::LocalChangesOnly, DIFinder);
99
124
@@ -1517,11 +1542,11 @@ namespace {
1517
1542
struct SwitchCoroutineSplitter {
1518
1543
static void split (Function &F, coro::Shape &Shape,
1519
1544
SmallVectorImpl<Function *> &Clones,
1520
- TargetTransformInfo &TTI) {
1545
+ TargetTransformInfo &TTI, const DebugInfoCache *DICache ) {
1521
1546
assert (Shape.ABI == coro::ABI::Switch);
1522
1547
1523
1548
MetadataSetTy GlobalDebugInfo;
1524
- collectGlobalDebugInfo (F, GlobalDebugInfo);
1549
+ collectGlobalDebugInfo (F, GlobalDebugInfo, DICache );
1525
1550
1526
1551
// Create a resume clone by cloning the body of the original function,
1527
1552
// setting new entry block and replacing coro.suspend an appropriate value
@@ -1835,7 +1860,8 @@ CallInst *coro::createMustTailCall(DebugLoc Loc, Function *MustTailCallFn,
1835
1860
1836
1861
void coro::AsyncABI::splitCoroutine (Function &F, coro::Shape &Shape,
1837
1862
SmallVectorImpl<Function *> &Clones,
1838
- TargetTransformInfo &TTI) {
1863
+ TargetTransformInfo &TTI,
1864
+ const DebugInfoCache *DICache) {
1839
1865
assert (Shape.ABI == coro::ABI::Async);
1840
1866
assert (Clones.empty ());
1841
1867
// Reset various things that the optimizer might have decided it
@@ -1922,7 +1948,7 @@ void coro::AsyncABI::splitCoroutine(Function &F, coro::Shape &Shape,
1922
1948
assert (Clones.size () == Shape.CoroSuspends .size ());
1923
1949
1924
1950
MetadataSetTy GlobalDebugInfo;
1925
- collectGlobalDebugInfo (F, GlobalDebugInfo);
1951
+ collectGlobalDebugInfo (F, GlobalDebugInfo, DICache );
1926
1952
1927
1953
for (auto [Idx, CS] : llvm::enumerate (Shape.CoroSuspends )) {
1928
1954
auto *Suspend = CS;
@@ -1935,7 +1961,8 @@ void coro::AsyncABI::splitCoroutine(Function &F, coro::Shape &Shape,
1935
1961
1936
1962
void coro::AnyRetconABI::splitCoroutine (Function &F, coro::Shape &Shape,
1937
1963
SmallVectorImpl<Function *> &Clones,
1938
- TargetTransformInfo &TTI) {
1964
+ TargetTransformInfo &TTI,
1965
+ const DebugInfoCache *DICache) {
1939
1966
assert (Shape.ABI == coro::ABI::Retcon || Shape.ABI == coro::ABI::RetconOnce);
1940
1967
assert (Clones.empty ());
1941
1968
@@ -2057,7 +2084,7 @@ void coro::AnyRetconABI::splitCoroutine(Function &F, coro::Shape &Shape,
2057
2084
assert (Clones.size () == Shape.CoroSuspends .size ());
2058
2085
2059
2086
MetadataSetTy GlobalDebugInfo;
2060
- collectGlobalDebugInfo (F, GlobalDebugInfo);
2087
+ collectGlobalDebugInfo (F, GlobalDebugInfo, DICache );
2061
2088
2062
2089
for (auto [Idx, CS] : llvm::enumerate (Shape.CoroSuspends )) {
2063
2090
auto Suspend = CS;
@@ -2111,13 +2138,15 @@ static bool hasSafeElideCaller(Function &F) {
2111
2138
2112
2139
void coro::SwitchABI::splitCoroutine (Function &F, coro::Shape &Shape,
2113
2140
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);
2116
2144
}
2117
2145
2118
2146
static void doSplitCoroutine (Function &F, SmallVectorImpl<Function *> &Clones,
2119
2147
coro::BaseABI &ABI, TargetTransformInfo &TTI,
2120
- bool OptimizeFrame) {
2148
+ bool OptimizeFrame,
2149
+ const DebugInfoCache *DICache) {
2121
2150
PrettyStackTraceFunction prettyStackTrace (F);
2122
2151
2123
2152
auto &Shape = ABI.Shape ;
@@ -2142,7 +2171,7 @@ static void doSplitCoroutine(Function &F, SmallVectorImpl<Function *> &Clones,
2142
2171
if (isNoSuspendCoroutine) {
2143
2172
handleNoSuspendCoroutine (Shape);
2144
2173
} else {
2145
- ABI.splitCoroutine (F, Shape, Clones, TTI);
2174
+ ABI.splitCoroutine (F, Shape, Clones, TTI, DICache );
2146
2175
}
2147
2176
2148
2177
// Replace all the swifterror operations in the original function.
@@ -2339,6 +2368,9 @@ PreservedAnalyses CoroSplitPass::run(LazyCallGraph::SCC &C,
2339
2368
auto &FAM =
2340
2369
AM.getResult <FunctionAnalysisManagerCGSCCProxy>(C, CG).getManager ();
2341
2370
2371
+ const auto &MAMProxy = AM.getResult <ModuleAnalysisManagerCGSCCProxy>(C, CG);
2372
+ const auto *DICache = MAMProxy.getCachedResult <DebugInfoCacheAnalysis>(M);
2373
+
2342
2374
// Check for uses of llvm.coro.prepare.retcon/async.
2343
2375
SmallVector<Function *, 2 > PrepareFns;
2344
2376
addPrepareFunction (M, PrepareFns, " llvm.coro.prepare.retcon" );
@@ -2375,7 +2407,7 @@ PreservedAnalyses CoroSplitPass::run(LazyCallGraph::SCC &C,
2375
2407
2376
2408
SmallVector<Function *, 4 > Clones;
2377
2409
auto &TTI = FAM.getResult <TargetIRAnalysis>(F);
2378
- doSplitCoroutine (F, Clones, *ABI, TTI, OptimizeFrame);
2410
+ doSplitCoroutine (F, Clones, *ABI, TTI, OptimizeFrame, DICache );
2379
2411
CurrentSCC = &updateCallGraphAfterCoroutineSplit (
2380
2412
*N, Shape, Clones, *CurrentSCC, CG, AM, UR, FAM);
2381
2413
0 commit comments