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"
@@ -82,15 +83,39 @@ using namespace llvm;
82
83
83
84
namespace {
84
85
86
+ const DebugInfoFinder *cachedDIFinder (Function &F,
87
+ const DebugInfoCache *DICache) {
88
+ if (!DICache)
89
+ return nullptr ;
90
+
91
+ auto *SP = F.getSubprogram ();
92
+ auto *CU = SP ? SP->getUnit () : nullptr ;
93
+ if (!CU)
94
+ return nullptr ;
95
+
96
+ auto Found = DICache->Result .find (CU);
97
+ if (Found == DICache->Result .end ())
98
+ return nullptr ;
99
+
100
+ return &Found->getSecond ();
101
+ }
102
+
85
103
// / Collect (a known) subset of global debug info metadata potentially used by
86
104
// / the function \p F.
87
105
// /
88
106
// / This metadata set can be used to avoid cloning debug info not owned by \p F
89
107
// / and is shared among all potential clones \p F.
90
- void collectGlobalDebugInfo (Function &F, MetadataSetTy &GlobalDebugInfo) {
108
+ void collectGlobalDebugInfo (Function &F, MetadataSetTy &GlobalDebugInfo,
109
+ const DebugInfoCache *DICache) {
91
110
TimeTraceScope FunctionScope (" CollectGlobalDebugInfo" );
92
111
93
112
DebugInfoFinder DIFinder;
113
+
114
+ // Copy DIFinder from cache which is primed on F's compile unit when available
115
+ auto *PrimedDIFinder = cachedDIFinder (F, DICache);
116
+ if (PrimedDIFinder)
117
+ DIFinder = *PrimedDIFinder;
118
+
94
119
DISubprogram *SPClonedWithinModule = ProcessSubprogramAttachment (
95
120
F, CloneFunctionChangeType::LocalChangesOnly, DIFinder);
96
121
@@ -1514,11 +1539,11 @@ namespace {
1514
1539
struct SwitchCoroutineSplitter {
1515
1540
static void split (Function &F, coro::Shape &Shape,
1516
1541
SmallVectorImpl<Function *> &Clones,
1517
- TargetTransformInfo &TTI) {
1542
+ TargetTransformInfo &TTI, const DebugInfoCache *DICache ) {
1518
1543
assert (Shape.ABI == coro::ABI::Switch);
1519
1544
1520
1545
MetadataSetTy GlobalDebugInfo;
1521
- collectGlobalDebugInfo (F, GlobalDebugInfo);
1546
+ collectGlobalDebugInfo (F, GlobalDebugInfo, DICache );
1522
1547
1523
1548
// Create a resume clone by cloning the body of the original function,
1524
1549
// setting new entry block and replacing coro.suspend an appropriate value
@@ -1832,7 +1857,8 @@ CallInst *coro::createMustTailCall(DebugLoc Loc, Function *MustTailCallFn,
1832
1857
1833
1858
static void splitAsyncCoroutine (Function &F, coro::Shape &Shape,
1834
1859
SmallVectorImpl<Function *> &Clones,
1835
- TargetTransformInfo &TTI) {
1860
+ TargetTransformInfo &TTI,
1861
+ const DebugInfoCache *DICache) {
1836
1862
assert (Shape.ABI == coro::ABI::Async);
1837
1863
assert (Clones.empty ());
1838
1864
// Reset various things that the optimizer might have decided it
@@ -1919,7 +1945,7 @@ static void splitAsyncCoroutine(Function &F, coro::Shape &Shape,
1919
1945
assert (Clones.size () == Shape.CoroSuspends .size ());
1920
1946
1921
1947
MetadataSetTy GlobalDebugInfo;
1922
- collectGlobalDebugInfo (F, GlobalDebugInfo);
1948
+ collectGlobalDebugInfo (F, GlobalDebugInfo, DICache );
1923
1949
1924
1950
for (size_t Idx = 0 , End = Shape.CoroSuspends .size (); Idx != End; ++Idx) {
1925
1951
auto *Suspend = Shape.CoroSuspends [Idx];
@@ -1932,7 +1958,8 @@ static void splitAsyncCoroutine(Function &F, coro::Shape &Shape,
1932
1958
1933
1959
static void splitRetconCoroutine (Function &F, coro::Shape &Shape,
1934
1960
SmallVectorImpl<Function *> &Clones,
1935
- TargetTransformInfo &TTI) {
1961
+ TargetTransformInfo &TTI,
1962
+ const DebugInfoCache *DICache) {
1936
1963
assert (Shape.ABI == coro::ABI::Retcon || Shape.ABI == coro::ABI::RetconOnce);
1937
1964
assert (Clones.empty ());
1938
1965
@@ -2053,7 +2080,7 @@ static void splitRetconCoroutine(Function &F, coro::Shape &Shape,
2053
2080
assert (Clones.size () == Shape.CoroSuspends .size ());
2054
2081
2055
2082
MetadataSetTy GlobalDebugInfo;
2056
- collectGlobalDebugInfo (F, GlobalDebugInfo);
2083
+ collectGlobalDebugInfo (F, GlobalDebugInfo, DICache );
2057
2084
2058
2085
for (size_t i = 0 , e = Shape.CoroSuspends .size (); i != e; ++i) {
2059
2086
auto Suspend = Shape.CoroSuspends [i];
@@ -2108,7 +2135,8 @@ static bool hasSafeElideCaller(Function &F) {
2108
2135
static coro::Shape
2109
2136
splitCoroutine (Function &F, SmallVectorImpl<Function *> &Clones,
2110
2137
TargetTransformInfo &TTI, bool OptimizeFrame,
2111
- std::function<bool (Instruction &)> MaterializableCallback) {
2138
+ std::function<bool (Instruction &)> MaterializableCallback,
2139
+ const DebugInfoCache *DICache) {
2112
2140
PrettyStackTraceFunction prettyStackTrace (F);
2113
2141
2114
2142
// The suspend-crossing algorithm in buildCoroutineFrame get tripped
@@ -2138,14 +2166,14 @@ splitCoroutine(Function &F, SmallVectorImpl<Function *> &Clones,
2138
2166
} else {
2139
2167
switch (Shape.ABI ) {
2140
2168
case coro::ABI::Switch:
2141
- SwitchCoroutineSplitter::split (F, Shape, Clones, TTI);
2169
+ SwitchCoroutineSplitter::split (F, Shape, Clones, TTI, DICache );
2142
2170
break ;
2143
2171
case coro::ABI::Async:
2144
- splitAsyncCoroutine (F, Shape, Clones, TTI);
2172
+ splitAsyncCoroutine (F, Shape, Clones, TTI, DICache );
2145
2173
break ;
2146
2174
case coro::ABI::Retcon:
2147
2175
case coro::ABI::RetconOnce:
2148
- splitRetconCoroutine (F, Shape, Clones, TTI);
2176
+ splitRetconCoroutine (F, Shape, Clones, TTI, DICache );
2149
2177
break ;
2150
2178
}
2151
2179
}
@@ -2282,6 +2310,9 @@ PreservedAnalyses CoroSplitPass::run(LazyCallGraph::SCC &C,
2282
2310
auto &FAM =
2283
2311
AM.getResult <FunctionAnalysisManagerCGSCCProxy>(C, CG).getManager ();
2284
2312
2313
+ const auto &MAMProxy = AM.getResult <ModuleAnalysisManagerCGSCCProxy>(C, CG);
2314
+ const auto *DICache = MAMProxy.getCachedResult <DebugInfoCacheAnalysis>(M);
2315
+
2285
2316
// Check for uses of llvm.coro.prepare.retcon/async.
2286
2317
SmallVector<Function *, 2 > PrepareFns;
2287
2318
addPrepareFunction (M, PrepareFns, " llvm.coro.prepare.retcon" );
@@ -2307,7 +2338,7 @@ PreservedAnalyses CoroSplitPass::run(LazyCallGraph::SCC &C,
2307
2338
SmallVector<Function *, 4 > Clones;
2308
2339
coro::Shape Shape =
2309
2340
splitCoroutine (F, Clones, FAM.getResult <TargetIRAnalysis>(F),
2310
- OptimizeFrame, MaterializableCallback);
2341
+ OptimizeFrame, MaterializableCallback, DICache );
2311
2342
CurrentSCC = &updateCallGraphAfterCoroutineSplit (
2312
2343
*N, Shape, Clones, *CurrentSCC, CG, AM, UR, FAM);
2313
2344
0 commit comments