diff --git a/llvm/include/llvm/Transforms/Coroutines/ABI.h b/llvm/include/llvm/Transforms/Coroutines/ABI.h index 0b2d405f3caec..2cf614b6bb1e2 100644 --- a/llvm/include/llvm/Transforms/Coroutines/ABI.h +++ b/llvm/include/llvm/Transforms/Coroutines/ABI.h @@ -15,6 +15,7 @@ #ifndef LLVM_TRANSFORMS_COROUTINES_ABI_H #define LLVM_TRANSFORMS_COROUTINES_ABI_H +#include "llvm/Analysis/DebugInfoCache.h" #include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/Transforms/Coroutines/CoroShape.h" #include "llvm/Transforms/Coroutines/MaterializationUtils.h" @@ -53,7 +54,8 @@ class BaseABI { // Perform the function splitting according to the ABI. virtual void splitCoroutine(Function &F, coro::Shape &Shape, SmallVectorImpl &Clones, - TargetTransformInfo &TTI) = 0; + TargetTransformInfo &TTI, + const DebugInfoCache *DICache) = 0; Function &F; coro::Shape &Shape; @@ -73,7 +75,8 @@ class SwitchABI : public BaseABI { void splitCoroutine(Function &F, coro::Shape &Shape, SmallVectorImpl &Clones, - TargetTransformInfo &TTI) override; + TargetTransformInfo &TTI, + const DebugInfoCache *DICache) override; }; class AsyncABI : public BaseABI { @@ -86,7 +89,8 @@ class AsyncABI : public BaseABI { void splitCoroutine(Function &F, coro::Shape &Shape, SmallVectorImpl &Clones, - TargetTransformInfo &TTI) override; + TargetTransformInfo &TTI, + const DebugInfoCache *DICache) override; }; class AnyRetconABI : public BaseABI { @@ -99,7 +103,8 @@ class AnyRetconABI : public BaseABI { void splitCoroutine(Function &F, coro::Shape &Shape, SmallVectorImpl &Clones, - TargetTransformInfo &TTI) override; + TargetTransformInfo &TTI, + const DebugInfoCache *DICache) override; }; } // end namespace coro diff --git a/llvm/lib/Analysis/CGSCCPassManager.cpp b/llvm/lib/Analysis/CGSCCPassManager.cpp index 948bc2435ab27..3ba085cdb0be8 100644 --- a/llvm/lib/Analysis/CGSCCPassManager.cpp +++ b/llvm/lib/Analysis/CGSCCPassManager.cpp @@ -14,6 +14,7 @@ #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/iterator_range.h" +#include "llvm/Analysis/DebugInfoCache.h" #include "llvm/Analysis/LazyCallGraph.h" #include "llvm/IR/Constant.h" #include "llvm/IR/InstIterator.h" @@ -139,6 +140,11 @@ ModuleToPostOrderCGSCCPassAdaptor::run(Module &M, ModuleAnalysisManager &AM) { // Get the call graph for this module. LazyCallGraph &CG = AM.getResult(M); + // Prime DebugInfoCache. + // TODO: Currently, the only user is CoroSplitPass. Consider running + // conditionally. + AM.getResult(M); + // Get Function analysis manager from its proxy. FunctionAnalysisManager &FAM = AM.getCachedResult(M)->getManager(); @@ -350,6 +356,7 @@ ModuleToPostOrderCGSCCPassAdaptor::run(Module &M, ModuleAnalysisManager &AM) { // analysis proxies by handling them above and in any nested pass managers. PA.preserveSet>(); PA.preserve(); + PA.preserve(); PA.preserve(); PA.preserve(); return PA; diff --git a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp index ff5df12c398c5..1563cdcce01e9 100644 --- a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp @@ -32,6 +32,7 @@ #include "llvm/Analysis/CFG.h" #include "llvm/Analysis/CallGraph.h" #include "llvm/Analysis/ConstantFolding.h" +#include "llvm/Analysis/DebugInfoCache.h" #include "llvm/Analysis/LazyCallGraph.h" #include "llvm/Analysis/OptimizationRemarkEmitter.h" #include "llvm/Analysis/TargetTransformInfo.h" @@ -79,15 +80,38 @@ using namespace llvm; #define DEBUG_TYPE "coro-split" namespace { +const DebugInfoFinder *cachedDIFinder(Function &F, + const DebugInfoCache *DICache) { + if (!DICache) + return nullptr; + + auto *SP = F.getSubprogram(); + auto *CU = SP ? SP->getUnit() : nullptr; + if (!CU) + return nullptr; + + if (auto Found = DICache->Result.find(CU); Found != DICache->Result.end()) + return &Found->getSecond(); + + return nullptr; +} + /// Collect (a known) subset of global debug info metadata potentially used by /// the function \p F. /// /// This metadata set can be used to avoid cloning debug info not owned by \p F /// and is shared among all potential clones \p F. -MetadataSetTy collectCommonDebugInfo(Function &F) { +MetadataSetTy collectCommonDebugInfo(Function &F, + const DebugInfoCache *DICache) { TimeTraceScope FunctionScope("CollectCommonDebugInfo"); DebugInfoFinder DIFinder; + + // Copy DIFinder from cache which is primed on F's compile unit when available + auto *PrimedDIFinder = cachedDIFinder(F, DICache); + if (PrimedDIFinder) + DIFinder = *PrimedDIFinder; + DISubprogram *SPClonedWithinModule = CollectDebugInfoForCloning( F, CloneFunctionChangeType::LocalChangesOnly, DIFinder); @@ -1393,10 +1417,10 @@ namespace { struct SwitchCoroutineSplitter { static void split(Function &F, coro::Shape &Shape, SmallVectorImpl &Clones, - TargetTransformInfo &TTI) { + TargetTransformInfo &TTI, const DebugInfoCache *DICache) { assert(Shape.ABI == coro::ABI::Switch); - MetadataSetTy CommonDebugInfo{collectCommonDebugInfo(F)}; + MetadataSetTy CommonDebugInfo{collectCommonDebugInfo(F, DICache)}; // Create a resume clone by cloning the body of the original function, // setting new entry block and replacing coro.suspend an appropriate value @@ -1710,7 +1734,8 @@ CallInst *coro::createMustTailCall(DebugLoc Loc, Function *MustTailCallFn, void coro::AsyncABI::splitCoroutine(Function &F, coro::Shape &Shape, SmallVectorImpl &Clones, - TargetTransformInfo &TTI) { + TargetTransformInfo &TTI, + const DebugInfoCache *DICache) { assert(Shape.ABI == coro::ABI::Async); assert(Clones.empty()); // Reset various things that the optimizer might have decided it @@ -1796,7 +1821,7 @@ void coro::AsyncABI::splitCoroutine(Function &F, coro::Shape &Shape, assert(Clones.size() == Shape.CoroSuspends.size()); - MetadataSetTy CommonDebugInfo{collectCommonDebugInfo(F)}; + MetadataSetTy CommonDebugInfo{collectCommonDebugInfo(F, DICache)}; for (auto [Idx, CS] : llvm::enumerate(Shape.CoroSuspends)) { auto *Suspend = CS; @@ -1809,7 +1834,8 @@ void coro::AsyncABI::splitCoroutine(Function &F, coro::Shape &Shape, void coro::AnyRetconABI::splitCoroutine(Function &F, coro::Shape &Shape, SmallVectorImpl &Clones, - TargetTransformInfo &TTI) { + TargetTransformInfo &TTI, + const DebugInfoCache *DICache) { assert(Shape.ABI == coro::ABI::Retcon || Shape.ABI == coro::ABI::RetconOnce); assert(Clones.empty()); @@ -1930,7 +1956,7 @@ void coro::AnyRetconABI::splitCoroutine(Function &F, coro::Shape &Shape, assert(Clones.size() == Shape.CoroSuspends.size()); - MetadataSetTy CommonDebugInfo{collectCommonDebugInfo(F)}; + MetadataSetTy CommonDebugInfo{collectCommonDebugInfo(F, DICache)}; for (auto [Idx, CS] : llvm::enumerate(Shape.CoroSuspends)) { auto Suspend = CS; @@ -1984,13 +2010,15 @@ static bool hasSafeElideCaller(Function &F) { void coro::SwitchABI::splitCoroutine(Function &F, coro::Shape &Shape, SmallVectorImpl &Clones, - TargetTransformInfo &TTI) { - SwitchCoroutineSplitter::split(F, Shape, Clones, TTI); + TargetTransformInfo &TTI, + const DebugInfoCache *DICache) { + SwitchCoroutineSplitter::split(F, Shape, Clones, TTI, DICache); } static void doSplitCoroutine(Function &F, SmallVectorImpl &Clones, coro::BaseABI &ABI, TargetTransformInfo &TTI, - bool OptimizeFrame) { + bool OptimizeFrame, + const DebugInfoCache *DICache) { PrettyStackTraceFunction prettyStackTrace(F); auto &Shape = ABI.Shape; @@ -2015,7 +2043,7 @@ static void doSplitCoroutine(Function &F, SmallVectorImpl &Clones, if (isNoSuspendCoroutine) { handleNoSuspendCoroutine(Shape); } else { - ABI.splitCoroutine(F, Shape, Clones, TTI); + ABI.splitCoroutine(F, Shape, Clones, TTI, DICache); } // Replace all the swifterror operations in the original function. @@ -2212,6 +2240,9 @@ PreservedAnalyses CoroSplitPass::run(LazyCallGraph::SCC &C, auto &FAM = AM.getResult(C, CG).getManager(); + const auto &MAMProxy = AM.getResult(C, CG); + const auto *DICache = MAMProxy.getCachedResult(M); + // Check for uses of llvm.coro.prepare.retcon/async. SmallVector PrepareFns; addPrepareFunction(M, PrepareFns, "llvm.coro.prepare.retcon"); @@ -2248,7 +2279,7 @@ PreservedAnalyses CoroSplitPass::run(LazyCallGraph::SCC &C, SmallVector Clones; auto &TTI = FAM.getResult(F); - doSplitCoroutine(F, Clones, *ABI, TTI, OptimizeFrame); + doSplitCoroutine(F, Clones, *ABI, TTI, OptimizeFrame, DICache); CurrentSCC = &updateCallGraphAfterCoroutineSplit( *N, Shape, Clones, *CurrentSCC, CG, AM, UR, FAM); diff --git a/llvm/test/Other/new-pass-manager.ll b/llvm/test/Other/new-pass-manager.ll index f0fe708806f1b..53fd6fe2a317e 100644 --- a/llvm/test/Other/new-pass-manager.ll +++ b/llvm/test/Other/new-pass-manager.ll @@ -23,6 +23,7 @@ ; CHECK-CGSCC-PASS-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*(FunctionAnalysisManager|AnalysisManager<.*Function.*>).*}},{{.*}}Module> ; CHECK-CGSCC-PASS-NEXT: Running analysis: LazyCallGraphAnalysis ; CHECK-CGSCC-PASS-NEXT: Running analysis: TargetLibraryAnalysis +; CHECK-CGSCC-PASS-NEXT: Running analysis: DebugInfoCacheAnalysis ; CHECK-CGSCC-PASS-NEXT: Running analysis: FunctionAnalysisManagerCGSCCProxy ; CHECK-CGSCC-PASS-NEXT: Running analysis: OuterAnalysisManagerProxy<{{.*}}LazyCallGraph::SCC{{.*}}> ; CHECK-CGSCC-PASS-NEXT: Running pass: NoOpCGSCCPass diff --git a/llvm/test/Other/new-pm-defaults.ll b/llvm/test/Other/new-pm-defaults.ll index 7cf035b0c6f37..19bfec3ab718e 100644 --- a/llvm/test/Other/new-pm-defaults.ll +++ b/llvm/test/Other/new-pm-defaults.ll @@ -139,6 +139,7 @@ ; CHECK-O-NEXT: Running pass: RequireAnalysisPass<{{.*}}ProfileSummaryAnalysis ; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy ; CHECK-O-NEXT: Running analysis: LazyCallGraphAnalysis +; CHECK-O-NEXT: Running analysis: DebugInfoCacheAnalysis ; CHECK-O-NEXT: Running analysis: FunctionAnalysisManagerCGSCCProxy ; CHECK-O-NEXT: Running analysis: OuterAnalysisManagerProxy<{{.*}}LazyCallGraph::SCC{{.*}}> ; CHECK-O-NEXT: Running pass: DevirtSCCRepeatedPass diff --git a/llvm/test/Other/new-pm-lto-defaults.ll b/llvm/test/Other/new-pm-lto-defaults.ll index f788db1e338a1..8f4fa763b5209 100644 --- a/llvm/test/Other/new-pm-lto-defaults.ll +++ b/llvm/test/Other/new-pm-lto-defaults.ll @@ -43,6 +43,7 @@ ; CHECK-O23SZ-NEXT: Running analysis: OptimizationRemarkEmitterAnalysis ; CHECK-O23SZ-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}SCC ; CHECK-O23SZ-NEXT: Running analysis: LazyCallGraphAnalysis +; CHECK-O23SZ-NEXT: Running analysis: DebugInfoCacheAnalysis ; CHECK-O23SZ-NEXT: Running analysis: FunctionAnalysisManagerCGSCCProxy ; CHECK-O23SZ-NEXT: Running analysis: OuterAnalysisManagerProxy<{{.*}}LazyCallGraph{{.*}}> ; CHECK-O23SZ-NEXT: Running pass: PostOrderFunctionAttrsPass diff --git a/llvm/test/Other/new-pm-pgo-preinline.ll b/llvm/test/Other/new-pm-pgo-preinline.ll index f07a3728ba3d4..97813bb243364 100644 --- a/llvm/test/Other/new-pm-pgo-preinline.ll +++ b/llvm/test/Other/new-pm-pgo-preinline.ll @@ -5,6 +5,7 @@ ; CHECK-Osz-NEXT: Running analysis: InlineAdvisorAnalysis ; CHECK-Osz-NEXT: Running analysis: InnerAnalysisManagerProxy ; CHECK-Osz-NEXT: Running analysis: LazyCallGraphAnalysis +; CHECK-Osz-NEXT: Running analysis: DebugInfoCacheAnalysis ; CHECK-Osz-NEXT: Running analysis: FunctionAnalysisManagerCGSCCProxy on (foo) ; CHECK-Osz-NEXT: Running analysis: OuterAnalysisManagerProxy ; CHECK-Osz-NEXT: Running pass: InlinerPass on (foo) diff --git a/llvm/test/Other/new-pm-thinlto-postlink-defaults.ll b/llvm/test/Other/new-pm-thinlto-postlink-defaults.ll index ed13402e1c4b1..e1ad86015fda9 100644 --- a/llvm/test/Other/new-pm-thinlto-postlink-defaults.ll +++ b/llvm/test/Other/new-pm-thinlto-postlink-defaults.ll @@ -74,6 +74,7 @@ ; CHECK-O-NEXT: Running pass: RequireAnalysisPass<{{.*}}ProfileSummaryAnalysis ; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy ; CHECK-O-NEXT: Running analysis: LazyCallGraphAnalysis +; CHECK-O-NEXT: Running analysis: DebugInfoCacheAnalysis ; CHECK-O-NEXT: Running analysis: FunctionAnalysisManagerCGSCCProxy ; CHECK-O-NEXT: Running analysis: OuterAnalysisManagerProxy ; CHECK-O-NEXT: Running pass: DevirtSCCRepeatedPass diff --git a/llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll b/llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll index c82c34f7ff01e..3f6c5351e8e8e 100644 --- a/llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll +++ b/llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll @@ -62,6 +62,7 @@ ; CHECK-O-NEXT: Running pass: RequireAnalysisPass<{{.*}}ProfileSummaryAnalysis ; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy ; CHECK-O-NEXT: Running analysis: LazyCallGraphAnalysis +; CHECK-O-NEXT: Running analysis: DebugInfoCacheAnalysis ; CHECK-O-NEXT: Running analysis: FunctionAnalysisManagerCGSCCProxy ; CHECK-O-NEXT: Running analysis: OuterAnalysisManagerProxy<{{.*}}LazyCallGraph::SCC{{.*}}> ; CHECK-O-NEXT: Running pass: DevirtSCCRepeatedPass diff --git a/llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll b/llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll index d375747547d61..371dde305b099 100644 --- a/llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll +++ b/llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll @@ -71,6 +71,7 @@ ; CHECK-O-NEXT: Invalidating analysis: AAManager ; CHECK-O-NEXT: Running pass: RequireAnalysisPass<{{.*}}ProfileSummaryAnalysis ; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy +; CHECK-O-NEXT: Running analysis: DebugInfoCacheAnalysis ; CHECK-O-NEXT: Running analysis: FunctionAnalysisManagerCGSCCProxy ; CHECK-O-NEXT: Running analysis: OuterAnalysisManagerProxy ; CHECK-O-NEXT: Running pass: DevirtSCCRepeatedPass diff --git a/llvm/test/Other/new-pm-thinlto-prelink-defaults.ll b/llvm/test/Other/new-pm-thinlto-prelink-defaults.ll index 5aacd26def2be..860fb99525030 100644 --- a/llvm/test/Other/new-pm-thinlto-prelink-defaults.ll +++ b/llvm/test/Other/new-pm-thinlto-prelink-defaults.ll @@ -106,6 +106,7 @@ ; CHECK-O-NEXT: Running pass: RequireAnalysisPass<{{.*}}ProfileSummaryAnalysis ; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy ; CHECK-O-NEXT: Running analysis: LazyCallGraphAnalysis +; CHECK-O-NEXT: Running analysis: DebugInfoCacheAnalysis ; CHECK-O-NEXT: Running analysis: FunctionAnalysisManagerCGSCCProxy ; CHECK-O-NEXT: Running analysis: OuterAnalysisManagerProxy ; CHECK-O-NEXT: Running pass: DevirtSCCRepeatedPass diff --git a/llvm/test/Other/new-pm-thinlto-prelink-pgo-defaults.ll b/llvm/test/Other/new-pm-thinlto-prelink-pgo-defaults.ll index f6a9406596803..c1602e4c952a5 100644 --- a/llvm/test/Other/new-pm-thinlto-prelink-pgo-defaults.ll +++ b/llvm/test/Other/new-pm-thinlto-prelink-pgo-defaults.ll @@ -62,6 +62,7 @@ ; CHECK-O-NEXT: Running analysis: InlineAdvisorAnalysis ; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy ; CHECK-O-NEXT: Running analysis: LazyCallGraphAnalysis +; CHECK-O-NEXT: Running analysis: DebugInfoCacheAnalysis ; CHECK-O-NEXT: Running analysis: FunctionAnalysisManagerCGSCCProxy on (foo) ; CHECK-O-NEXT: Running analysis: OuterAnalysisManagerProxy ; CHECK-O-NEXT: Running pass: InlinerPass on (foo) @@ -81,6 +82,7 @@ ; CHECK-O-NEXT: Invalidating analysis: InnerAnalysisManagerProxy ; CHECK-O-NEXT: Invalidating analysis: LazyCallGraphAnalysis on ; CHECK-O-NEXT: Invalidating analysis: InnerAnalysisManagerProxy +; CHECK-O-NEXT: Invalidating analysis: DebugInfoCacheAnalysis ; CHECK-O-NEXT: Running pass: RequireAnalysisPass<{{.*}}ProfileSummaryAnalysis ; CHECK-O-NEXT: Running pass: PGOIndirectCallPromotion on ; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy @@ -97,6 +99,7 @@ ; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy ; CHECK-O-NEXT: Running analysis: LazyCallGraphAnalysis ; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis on foo +; CHECK-O-NEXT: Running analysis: DebugInfoCacheAnalysis ; CHECK-O-NEXT: Running analysis: FunctionAnalysisManagerCGSCCProxy ; CHECK-O-NEXT: Running analysis: OuterAnalysisManagerProxy<{{.*}}LazyCallGraph::SCC{{.*}}> ; CHECK-O-NEXT: Running pass: DevirtSCCRepeatedPass diff --git a/llvm/test/Other/new-pm-thinlto-prelink-samplepgo-defaults.ll b/llvm/test/Other/new-pm-thinlto-prelink-samplepgo-defaults.ll index 48a9433d24999..d338817d07646 100644 --- a/llvm/test/Other/new-pm-thinlto-prelink-samplepgo-defaults.ll +++ b/llvm/test/Other/new-pm-thinlto-prelink-samplepgo-defaults.ll @@ -76,6 +76,7 @@ ; CHECK-O-NEXT: Invalidating analysis: AAManager ; CHECK-O-NEXT: Running pass: RequireAnalysisPass<{{.*}}ProfileSummaryAnalysis ; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy +; CHECK-O-NEXT: Running analysis: DebugInfoCacheAnalysis ; CHECK-O-NEXT: Running analysis: FunctionAnalysisManagerCGSCCProxy ; CHECK-O-NEXT: Running analysis: OuterAnalysisManagerProxy<{{.*}}LazyCallGraph::SCC{{.*}}> ; CHECK-O-NEXT: Running pass: DevirtSCCRepeatedPass diff --git a/llvm/unittests/Analysis/CGSCCPassManagerTest.cpp b/llvm/unittests/Analysis/CGSCCPassManagerTest.cpp index cf649776c04fd..7072752bbb9d9 100644 --- a/llvm/unittests/Analysis/CGSCCPassManagerTest.cpp +++ b/llvm/unittests/Analysis/CGSCCPassManagerTest.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Analysis/CGSCCPassManager.h" +#include "llvm/Analysis/DebugInfoCache.h" #include "llvm/Analysis/LazyCallGraph.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/AsmParser/Parser.h" @@ -16,8 +17,8 @@ #include "llvm/IR/Instructions.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" -#include "llvm/IR/PassManager.h" #include "llvm/IR/PassInstrumentation.h" +#include "llvm/IR/PassManager.h" #include "llvm/IR/Verifier.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Transforms/Utils/CallGraphUpdater.h" @@ -255,6 +256,7 @@ class CGSCCPassManagerTest : public ::testing::Test { "}\n")) { FAM.registerPass([&] { return TargetLibraryAnalysis(); }); MAM.registerPass([&] { return LazyCallGraphAnalysis(); }); + MAM.registerPass([&] { return DebugInfoCacheAnalysis(); }); MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); }); // Register required pass instrumentation analysis.