32
32
#include " llvm/Analysis/CFG.h"
33
33
#include " llvm/Analysis/CallGraph.h"
34
34
#include " llvm/Analysis/ConstantFolding.h"
35
+ #include " llvm/Analysis/DebugInfoCache.h"
35
36
#include " llvm/Analysis/LazyCallGraph.h"
36
37
#include " llvm/Analysis/OptimizationRemarkEmitter.h"
37
38
#include " llvm/Analysis/TargetTransformInfo.h"
@@ -79,16 +80,39 @@ using namespace llvm;
79
80
#define DEBUG_TYPE " coro-split"
80
81
81
82
namespace {
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
+
82
99
// / Collect (a known) subset of global debug info metadata potentially used by
83
100
// / the function \p F.
84
101
// /
85
102
// / This metadata set can be used to avoid cloning debug info not owned by \p F
86
103
// / and is shared among all potential clones \p F.
87
- MetadataSetTy collectCommonDebugInfo (Function &F) {
104
+ MetadataSetTy collectCommonDebugInfo (Function &F,
105
+ const DebugInfoCache *DICache) {
88
106
TimeTraceScope FunctionScope (" CollectCommonDebugInfo" );
89
107
90
108
MetadataSetTy CommonDebugInfo;
91
109
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
+
92
116
DISubprogram *SPClonedWithinModule = CollectDebugInfoForCloning (
93
117
F, CloneFunctionChangeType::LocalChangesOnly, DIFinder);
94
118
@@ -1396,10 +1420,10 @@ namespace {
1396
1420
struct SwitchCoroutineSplitter {
1397
1421
static void split (Function &F, coro::Shape &Shape,
1398
1422
SmallVectorImpl<Function *> &Clones,
1399
- TargetTransformInfo &TTI) {
1423
+ TargetTransformInfo &TTI, const DebugInfoCache *DICache ) {
1400
1424
assert (Shape.ABI == coro::ABI::Switch);
1401
1425
1402
- MetadataSetTy CommonDebugInfo{collectCommonDebugInfo (F)};
1426
+ MetadataSetTy CommonDebugInfo{collectCommonDebugInfo (F, DICache )};
1403
1427
1404
1428
// Create a resume clone by cloning the body of the original function,
1405
1429
// setting new entry block and replacing coro.suspend an appropriate value
@@ -1713,7 +1737,8 @@ CallInst *coro::createMustTailCall(DebugLoc Loc, Function *MustTailCallFn,
1713
1737
1714
1738
void coro::AsyncABI::splitCoroutine (Function &F, coro::Shape &Shape,
1715
1739
SmallVectorImpl<Function *> &Clones,
1716
- TargetTransformInfo &TTI) {
1740
+ TargetTransformInfo &TTI,
1741
+ const DebugInfoCache *DICache) {
1717
1742
assert (Shape.ABI == coro::ABI::Async);
1718
1743
assert (Clones.empty ());
1719
1744
// Reset various things that the optimizer might have decided it
@@ -1799,7 +1824,7 @@ void coro::AsyncABI::splitCoroutine(Function &F, coro::Shape &Shape,
1799
1824
1800
1825
assert (Clones.size () == Shape.CoroSuspends .size ());
1801
1826
1802
- MetadataSetTy CommonDebugInfo{collectCommonDebugInfo (F)};
1827
+ MetadataSetTy CommonDebugInfo{collectCommonDebugInfo (F, DICache )};
1803
1828
1804
1829
for (auto [Idx, CS] : llvm::enumerate (Shape.CoroSuspends )) {
1805
1830
auto *Suspend = CS;
@@ -1812,7 +1837,8 @@ void coro::AsyncABI::splitCoroutine(Function &F, coro::Shape &Shape,
1812
1837
1813
1838
void coro::AnyRetconABI::splitCoroutine (Function &F, coro::Shape &Shape,
1814
1839
SmallVectorImpl<Function *> &Clones,
1815
- TargetTransformInfo &TTI) {
1840
+ TargetTransformInfo &TTI,
1841
+ const DebugInfoCache *DICache) {
1816
1842
assert (Shape.ABI == coro::ABI::Retcon || Shape.ABI == coro::ABI::RetconOnce);
1817
1843
assert (Clones.empty ());
1818
1844
@@ -1933,7 +1959,7 @@ void coro::AnyRetconABI::splitCoroutine(Function &F, coro::Shape &Shape,
1933
1959
1934
1960
assert (Clones.size () == Shape.CoroSuspends .size ());
1935
1961
1936
- MetadataSetTy CommonDebugInfo{collectCommonDebugInfo (F)};
1962
+ MetadataSetTy CommonDebugInfo{collectCommonDebugInfo (F, DICache )};
1937
1963
1938
1964
for (auto [Idx, CS] : llvm::enumerate (Shape.CoroSuspends )) {
1939
1965
auto Suspend = CS;
@@ -1987,13 +2013,15 @@ static bool hasSafeElideCaller(Function &F) {
1987
2013
1988
2014
void coro::SwitchABI::splitCoroutine (Function &F, coro::Shape &Shape,
1989
2015
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);
1992
2019
}
1993
2020
1994
2021
static void doSplitCoroutine (Function &F, SmallVectorImpl<Function *> &Clones,
1995
2022
coro::BaseABI &ABI, TargetTransformInfo &TTI,
1996
- bool OptimizeFrame) {
2023
+ bool OptimizeFrame,
2024
+ const DebugInfoCache *DICache) {
1997
2025
PrettyStackTraceFunction prettyStackTrace (F);
1998
2026
1999
2027
auto &Shape = ABI.Shape ;
@@ -2018,7 +2046,7 @@ static void doSplitCoroutine(Function &F, SmallVectorImpl<Function *> &Clones,
2018
2046
if (isNoSuspendCoroutine) {
2019
2047
handleNoSuspendCoroutine (Shape);
2020
2048
} else {
2021
- ABI.splitCoroutine (F, Shape, Clones, TTI);
2049
+ ABI.splitCoroutine (F, Shape, Clones, TTI, DICache );
2022
2050
}
2023
2051
2024
2052
// Replace all the swifterror operations in the original function.
@@ -2215,6 +2243,9 @@ PreservedAnalyses CoroSplitPass::run(LazyCallGraph::SCC &C,
2215
2243
auto &FAM =
2216
2244
AM.getResult <FunctionAnalysisManagerCGSCCProxy>(C, CG).getManager ();
2217
2245
2246
+ const auto &MAMProxy = AM.getResult <ModuleAnalysisManagerCGSCCProxy>(C, CG);
2247
+ const auto *DICache = MAMProxy.getCachedResult <DebugInfoCacheAnalysis>(M);
2248
+
2218
2249
// Check for uses of llvm.coro.prepare.retcon/async.
2219
2250
SmallVector<Function *, 2 > PrepareFns;
2220
2251
addPrepareFunction (M, PrepareFns, " llvm.coro.prepare.retcon" );
@@ -2251,7 +2282,7 @@ PreservedAnalyses CoroSplitPass::run(LazyCallGraph::SCC &C,
2251
2282
2252
2283
SmallVector<Function *, 4 > Clones;
2253
2284
auto &TTI = FAM.getResult <TargetIRAnalysis>(F);
2254
- doSplitCoroutine (F, Clones, *ABI, TTI, OptimizeFrame);
2285
+ doSplitCoroutine (F, Clones, *ABI, TTI, OptimizeFrame, DICache );
2255
2286
CurrentSCC = &updateCallGraphAfterCoroutineSplit (
2256
2287
*N, Shape, Clones, *CurrentSCC, CG, AM, UR, FAM);
2257
2288
0 commit comments