[llvm] [Coro] Amortize debug info processing cost in CoroSplit (PR #109032)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Dec 9 09:05:45 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-ir
Author: Artem Pianykh (artempyanykh)
<details>
<summary>Changes</summary>
More details about this stack are [in this topic on discourse](https://discourse.llvm.org/t/rfc-amortizing-debug-info-processing-cost-in-corosplit/81275).
TL;DR: In large modules with a bunch of coroutines the cost of debug info metadata processing can get very high (e.g. adding over a minute to the compile time). This stack does some refactoring around function cloning and caches some module-level calculations to speed up the pass.
Anecdata for a sample C++ source file:
||Baseline / 0|[IdentityMD set](https://github.com/llvm/llvm-project/commit/d7f598cc0f86e62838bd02fe5217d6eb58152956) |[Prebuilt GlobalDI](https://github.com/llvm/llvm-project/commit/e14a46f5224f0d974ad7dc5237cd4b9f82bb991b) |[Cached CU DIFinder](https://github.com/llvm/llvm-project/commit/4c76540db1990a49b6126de83c7ccd12e28e8cb0) |
| --- | --- | --- | --- | --- |
|CoroSplitPass|306ms|221ms|68ms|17ms|
|CoroCloner|101ms|72ms|63ms|0.5ms|
|CollectGlobalDI|-|-|63ms|13ms|
|Overall speed up |1x|1.4x|4.5x|18x|
Each commit is individually buildable and reviewable. I can extract them into separate PRs if the overall direction makes sense.
---
Patch is 67.56 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/109032.diff
27 Files Affected:
- (added) llvm/include/llvm/Analysis/DebugInfoCache.h (+50)
- (modified) llvm/include/llvm/IR/DebugInfo.h (+3-1)
- (modified) llvm/include/llvm/Transforms/Coroutines/ABI.h (+9-4)
- (modified) llvm/include/llvm/Transforms/Utils/Cloning.h (+42-13)
- (modified) llvm/include/llvm/Transforms/Utils/ValueMapper.h (+49-18)
- (modified) llvm/lib/Analysis/CGSCCPassManager.cpp (+7)
- (modified) llvm/lib/Analysis/CMakeLists.txt (+1)
- (added) llvm/lib/Analysis/DebugInfoCache.cpp (+47)
- (modified) llvm/lib/Passes/PassBuilder.cpp (+1)
- (modified) llvm/lib/Passes/PassRegistry.def (+1)
- (modified) llvm/lib/Transforms/Coroutines/CoroCloner.h (+20-11)
- (modified) llvm/lib/Transforms/Coroutines/CoroSplit.cpp (+82-15)
- (modified) llvm/lib/Transforms/Utils/CloneFunction.cpp (+111-80)
- (modified) llvm/lib/Transforms/Utils/ValueMapper.cpp (+15-4)
- (modified) llvm/test/Other/new-pass-manager.ll (+1)
- (modified) llvm/test/Other/new-pm-defaults.ll (+1)
- (modified) llvm/test/Other/new-pm-lto-defaults.ll (+1)
- (modified) llvm/test/Other/new-pm-pgo-preinline.ll (+1)
- (modified) llvm/test/Other/new-pm-thinlto-postlink-defaults.ll (+1)
- (modified) llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll (+1)
- (modified) llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll (+1)
- (modified) llvm/test/Other/new-pm-thinlto-prelink-defaults.ll (+1)
- (modified) llvm/test/Other/new-pm-thinlto-prelink-pgo-defaults.ll (+1)
- (modified) llvm/test/Other/new-pm-thinlto-prelink-samplepgo-defaults.ll (+1)
- (modified) llvm/unittests/Analysis/CGSCCPassManagerTest.cpp (+3-1)
- (modified) llvm/unittests/Analysis/CMakeLists.txt (+1)
- (added) llvm/unittests/Analysis/DebugInfoCacheTest.cpp (+211)
``````````diff
diff --git a/llvm/include/llvm/Analysis/DebugInfoCache.h b/llvm/include/llvm/Analysis/DebugInfoCache.h
new file mode 100644
index 00000000000000..dbd6802c99ea01
--- /dev/null
+++ b/llvm/include/llvm/Analysis/DebugInfoCache.h
@@ -0,0 +1,50 @@
+//===- llvm/Analysis/DebugInfoCache.h - debug info cache --------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains an analysis that builds a cache of debug info for each
+// DICompileUnit in a module.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_DEBUGINFOCACHE_H
+#define LLVM_ANALYSIS_DEBUGINFOCACHE_H
+
+#include "llvm/IR/DebugInfo.h"
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+/// Processes and caches debug info for each DICompileUnit in a module.
+///
+/// The result of the analysis is a set of DebugInfoFinders primed on their
+/// respective DICompileUnit. Such DebugInfoFinders can be used to speed up
+/// function cloning which otherwise requires an expensive traversal of
+/// DICompileUnit-level debug info. See an example usage in CoroSplit.
+class DebugInfoCache {
+public:
+ using DIFinderCache = SmallDenseMap<const DICompileUnit *, DebugInfoFinder>;
+ DIFinderCache Result;
+
+ DebugInfoCache(const Module &M);
+
+ bool invalidate(Module &, const PreservedAnalyses &,
+ ModuleAnalysisManager::Invalidator &);
+};
+
+class DebugInfoCacheAnalysis
+ : public AnalysisInfoMixin<DebugInfoCacheAnalysis> {
+ friend AnalysisInfoMixin<DebugInfoCacheAnalysis>;
+ static AnalysisKey Key;
+
+public:
+ using Result = DebugInfoCache;
+ Result run(Module &M, ModuleAnalysisManager &);
+};
+} // namespace llvm
+
+#endif
diff --git a/llvm/include/llvm/IR/DebugInfo.h b/llvm/include/llvm/IR/DebugInfo.h
index 73f45c3769be44..11907fbb7f20b3 100644
--- a/llvm/include/llvm/IR/DebugInfo.h
+++ b/llvm/include/llvm/IR/DebugInfo.h
@@ -120,11 +120,13 @@ class DebugInfoFinder {
/// Process subprogram.
void processSubprogram(DISubprogram *SP);
+ /// Process a compile unit.
+ void processCompileUnit(DICompileUnit *CU);
+
/// Clear all lists.
void reset();
private:
- void processCompileUnit(DICompileUnit *CU);
void processScope(DIScope *Scope);
void processType(DIType *DT);
bool addCompileUnit(DICompileUnit *CU);
diff --git a/llvm/include/llvm/Transforms/Coroutines/ABI.h b/llvm/include/llvm/Transforms/Coroutines/ABI.h
index 0b2d405f3caec4..2cf614b6bb1e2a 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<Function *> &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<Function *> &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<Function *> &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<Function *> &Clones,
- TargetTransformInfo &TTI) override;
+ TargetTransformInfo &TTI,
+ const DebugInfoCache *DICache) override;
};
} // end namespace coro
diff --git a/llvm/include/llvm/Transforms/Utils/Cloning.h b/llvm/include/llvm/Transforms/Utils/Cloning.h
index 3c8f2cbfaa9b81..9b256f9b4d6890 100644
--- a/llvm/include/llvm/Transforms/Utils/Cloning.h
+++ b/llvm/include/llvm/Transforms/Utils/Cloning.h
@@ -182,6 +182,29 @@ void CloneFunctionAttributesInto(Function *NewFunc, const Function *OldFunc,
ValueMapTypeRemapper *TypeMapper = nullptr,
ValueMaterializer *Materializer = nullptr);
+/// Clone OldFunc's metadata into NewFunc.
+///
+/// The caller is expected to populate \p VMap beforehand and set an appropriate
+/// \p RemapFlag.
+///
+/// NOTE: This function doesn't clone !llvm.dbg.cu when cloning into a different
+/// module. Use CloneFunctionInto for that behavior.
+void CloneFunctionMetadataInto(Function *NewFunc, const Function *OldFunc,
+ ValueToValueMapTy &VMap, RemapFlags RemapFlag,
+ ValueMapTypeRemapper *TypeMapper = nullptr,
+ ValueMaterializer *Materializer = nullptr,
+ const MetadataSetTy *IdentityMD = nullptr);
+
+/// Clone OldFunc's body into NewFunc.
+void CloneFunctionBodyInto(Function *NewFunc, const Function *OldFunc,
+ ValueToValueMapTy &VMap, RemapFlags RemapFlag,
+ SmallVectorImpl<ReturnInst *> &Returns,
+ const char *NameSuffix = "",
+ ClonedCodeInfo *CodeInfo = nullptr,
+ ValueMapTypeRemapper *TypeMapper = nullptr,
+ ValueMaterializer *Materializer = nullptr,
+ const MetadataSetTy *IdentityMD = nullptr);
+
void CloneAndPruneIntoFromInst(Function *NewFunc, const Function *OldFunc,
const Instruction *StartingInst,
ValueToValueMapTy &VMap, bool ModuleLevelChanges,
@@ -202,7 +225,7 @@ void CloneAndPruneIntoFromInst(Function *NewFunc, const Function *OldFunc,
///
void CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc,
ValueToValueMapTy &VMap, bool ModuleLevelChanges,
- SmallVectorImpl<ReturnInst*> &Returns,
+ SmallVectorImpl<ReturnInst *> &Returns,
const char *NameSuffix = "",
ClonedCodeInfo *CodeInfo = nullptr);
@@ -220,6 +243,13 @@ DISubprogram *CollectDebugInfoForCloning(const Function &F,
CloneFunctionChangeType Changes,
DebugInfoFinder &DIFinder);
+/// Based on \p Changes and \p DIFinder populate \p MD with debug info that
+/// needs to be identity mapped during Metadata cloning.
+void FindDebugInfoToIdentityMap(MetadataSetTy &MD,
+ CloneFunctionChangeType Changes,
+ DebugInfoFinder &DIFinder,
+ DISubprogram *SPClonedWithinModule);
+
/// This class captures the data input to the InlineFunction call, and records
/// the auxiliary results produced by it.
class InlineFunctionInfo {
@@ -341,32 +371,31 @@ void updateProfileCallee(
/// Find the 'llvm.experimental.noalias.scope.decl' intrinsics in the specified
/// basic blocks and extract their scope. These are candidates for duplication
/// when cloning.
-void identifyNoAliasScopesToClone(
- ArrayRef<BasicBlock *> BBs, SmallVectorImpl<MDNode *> &NoAliasDeclScopes);
+void identifyNoAliasScopesToClone(ArrayRef<BasicBlock *> BBs,
+ SmallVectorImpl<MDNode *> &NoAliasDeclScopes);
/// Find the 'llvm.experimental.noalias.scope.decl' intrinsics in the specified
/// instruction range and extract their scope. These are candidates for
/// duplication when cloning.
-void identifyNoAliasScopesToClone(
- BasicBlock::iterator Start, BasicBlock::iterator End,
- SmallVectorImpl<MDNode *> &NoAliasDeclScopes);
+void identifyNoAliasScopesToClone(BasicBlock::iterator Start,
+ BasicBlock::iterator End,
+ SmallVectorImpl<MDNode *> &NoAliasDeclScopes);
/// Duplicate the specified list of noalias decl scopes.
/// The 'Ext' string is added as an extension to the name.
/// Afterwards, the ClonedScopes contains the mapping of the original scope
/// MDNode onto the cloned scope.
/// Be aware that the cloned scopes are still part of the original scope domain.
-void cloneNoAliasScopes(
- ArrayRef<MDNode *> NoAliasDeclScopes,
- DenseMap<MDNode *, MDNode *> &ClonedScopes,
- StringRef Ext, LLVMContext &Context);
+void cloneNoAliasScopes(ArrayRef<MDNode *> NoAliasDeclScopes,
+ DenseMap<MDNode *, MDNode *> &ClonedScopes,
+ StringRef Ext, LLVMContext &Context);
/// Adapt the metadata for the specified instruction according to the
/// provided mapping. This is normally used after cloning an instruction, when
/// some noalias scopes needed to be cloned.
-void adaptNoAliasScopes(
- llvm::Instruction *I, const DenseMap<MDNode *, MDNode *> &ClonedScopes,
- LLVMContext &Context);
+void adaptNoAliasScopes(llvm::Instruction *I,
+ const DenseMap<MDNode *, MDNode *> &ClonedScopes,
+ LLVMContext &Context);
/// Clone the specified noalias decl scopes. Then adapt all instructions in the
/// NewBlocks basicblocks to the cloned versions.
diff --git a/llvm/include/llvm/Transforms/Utils/ValueMapper.h b/llvm/include/llvm/Transforms/Utils/ValueMapper.h
index 743cfeb7ef3f02..b8d612f11d519f 100644
--- a/llvm/include/llvm/Transforms/Utils/ValueMapper.h
+++ b/llvm/include/llvm/Transforms/Utils/ValueMapper.h
@@ -15,6 +15,7 @@
#define LLVM_TRANSFORMS_UTILS_VALUEMAPPER_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/simple_ilist.h"
#include "llvm/IR/ValueHandle.h"
#include "llvm/IR/ValueMap.h"
@@ -35,6 +36,7 @@ class Value;
using ValueToValueMapTy = ValueMap<const Value *, WeakTrackingVH>;
using DbgRecordIterator = simple_ilist<DbgRecord>::iterator;
+using MetadataSetTy = SmallPtrSet<const Metadata *, 16>;
/// This is a class that can be implemented by clients to remap types when
/// cloning constants and instructions.
@@ -136,6 +138,18 @@ inline RemapFlags operator|(RemapFlags LHS, RemapFlags RHS) {
/// alternate \a ValueToValueMapTy and \a ValueMaterializer and returns a ID to
/// pass into the schedule*() functions.
///
+/// NOTE: \c IdentityMD is used by CloneFunction* to directly specify metadata
+/// that should be identity mapped (and hence not cloned). The metadata will be
+/// identity mapped in \c VM on first use. There are several reasons for doing
+/// it this way rather than eagerly identity mapping metadata nodes in \c VM:
+/// 1. Mapping metadata is not cheap, particularly because of tracking.
+/// 2. When cloning a Function we identity map lots of global module-level
+/// metadata to avoid cloning it, while only a fraction of it is actually
+/// used by the function. Mapping on first use is a lot faster for modules
+/// with meaningful amount of debug info.
+/// 3. Eagerly identity mapping metadata makes it harder to cache module-level
+/// data (e.g. a set of metadata nodes in a \a DICompileUnit).
+///
/// TODO: lib/Linker really doesn't need the \a ValueHandle in the \a
/// ValueToValueMapTy. We should template \a ValueMapper (and its
/// implementation classes), and explicitly instantiate on two concrete
@@ -152,7 +166,8 @@ class ValueMapper {
public:
ValueMapper(ValueToValueMapTy &VM, RemapFlags Flags = RF_None,
ValueMapTypeRemapper *TypeMapper = nullptr,
- ValueMaterializer *Materializer = nullptr);
+ ValueMaterializer *Materializer = nullptr,
+ const MetadataSetTy *IdentityMD = nullptr);
ValueMapper(ValueMapper &&) = delete;
ValueMapper(const ValueMapper &) = delete;
ValueMapper &operator=(ValueMapper &&) = delete;
@@ -218,8 +233,10 @@ class ValueMapper {
inline Value *MapValue(const Value *V, ValueToValueMapTy &VM,
RemapFlags Flags = RF_None,
ValueMapTypeRemapper *TypeMapper = nullptr,
- ValueMaterializer *Materializer = nullptr) {
- return ValueMapper(VM, Flags, TypeMapper, Materializer).mapValue(*V);
+ ValueMaterializer *Materializer = nullptr,
+ const MetadataSetTy *IdentityMD = nullptr) {
+ return ValueMapper(VM, Flags, TypeMapper, Materializer, IdentityMD)
+ .mapValue(*V);
}
/// Lookup or compute a mapping for a piece of metadata.
@@ -231,7 +248,9 @@ inline Value *MapValue(const Value *V, ValueToValueMapTy &VM,
/// \c MD.
/// 3. Else if \c MD is a \a ConstantAsMetadata, call \a MapValue() and
/// re-wrap its return (returning nullptr on nullptr).
-/// 4. Else, \c MD is an \a MDNode. These are remapped, along with their
+/// 4. Else if \c MD is in \c IdentityMD then add an identity mapping for it
+/// and return it.
+/// 5. Else, \c MD is an \a MDNode. These are remapped, along with their
/// transitive operands. Distinct nodes are duplicated or moved depending
/// on \a RF_MoveDistinctNodes. Uniqued nodes are remapped like constants.
///
@@ -240,16 +259,20 @@ inline Value *MapValue(const Value *V, ValueToValueMapTy &VM,
inline Metadata *MapMetadata(const Metadata *MD, ValueToValueMapTy &VM,
RemapFlags Flags = RF_None,
ValueMapTypeRemapper *TypeMapper = nullptr,
- ValueMaterializer *Materializer = nullptr) {
- return ValueMapper(VM, Flags, TypeMapper, Materializer).mapMetadata(*MD);
+ ValueMaterializer *Materializer = nullptr,
+ const MetadataSetTy *IdentityMD = nullptr) {
+ return ValueMapper(VM, Flags, TypeMapper, Materializer, IdentityMD)
+ .mapMetadata(*MD);
}
/// Version of MapMetadata with type safety for MDNode.
inline MDNode *MapMetadata(const MDNode *MD, ValueToValueMapTy &VM,
RemapFlags Flags = RF_None,
ValueMapTypeRemapper *TypeMapper = nullptr,
- ValueMaterializer *Materializer = nullptr) {
- return ValueMapper(VM, Flags, TypeMapper, Materializer).mapMDNode(*MD);
+ ValueMaterializer *Materializer = nullptr,
+ const MetadataSetTy *IdentityMD = nullptr) {
+ return ValueMapper(VM, Flags, TypeMapper, Materializer, IdentityMD)
+ .mapMDNode(*MD);
}
/// Convert the instruction operands from referencing the current values into
@@ -263,8 +286,10 @@ inline MDNode *MapMetadata(const MDNode *MD, ValueToValueMapTy &VM,
inline void RemapInstruction(Instruction *I, ValueToValueMapTy &VM,
RemapFlags Flags = RF_None,
ValueMapTypeRemapper *TypeMapper = nullptr,
- ValueMaterializer *Materializer = nullptr) {
- ValueMapper(VM, Flags, TypeMapper, Materializer).remapInstruction(*I);
+ ValueMaterializer *Materializer = nullptr,
+ const MetadataSetTy *IdentityMD = nullptr) {
+ ValueMapper(VM, Flags, TypeMapper, Materializer, IdentityMD)
+ .remapInstruction(*I);
}
/// Remap the Values used in the DbgRecord \a DR using the value map \a
@@ -272,8 +297,10 @@ inline void RemapInstruction(Instruction *I, ValueToValueMapTy &VM,
inline void RemapDbgRecord(Module *M, DbgRecord *DR, ValueToValueMapTy &VM,
RemapFlags Flags = RF_None,
ValueMapTypeRemapper *TypeMapper = nullptr,
- ValueMaterializer *Materializer = nullptr) {
- ValueMapper(VM, Flags, TypeMapper, Materializer).remapDbgRecord(M, *DR);
+ ValueMaterializer *Materializer = nullptr,
+ const MetadataSetTy *IdentityMD = nullptr) {
+ ValueMapper(VM, Flags, TypeMapper, Materializer, IdentityMD)
+ .remapDbgRecord(M, *DR);
}
/// Remap the Values used in the DbgRecords \a Range using the value map \a
@@ -283,8 +310,9 @@ inline void RemapDbgRecordRange(Module *M,
ValueToValueMapTy &VM,
RemapFlags Flags = RF_None,
ValueMapTypeRemapper *TypeMapper = nullptr,
- ValueMaterializer *Materializer = nullptr) {
- ValueMapper(VM, Flags, TypeMapper, Materializer)
+ ValueMaterializer *Materializer = nullptr,
+ const MetadataSetTy *IdentityMD = nullptr) {
+ ValueMapper(VM, Flags, TypeMapper, Materializer, IdentityMD)
.remapDbgRecordRange(M, Range);
}
@@ -297,16 +325,19 @@ inline void RemapDbgRecordRange(Module *M,
inline void RemapFunction(Function &F, ValueToValueMapTy &VM,
RemapFlags Flags = RF_None,
ValueMapTypeRemapper *TypeMapper = nullptr,
- ValueMaterializer *Materializer = nullptr) {
- ValueMapper(VM, Flags, TypeMapper, Materializer).remapFunction(F);
+ ValueMaterializer *Materializer = nullptr,
+ const MetadataSetTy *IdentityMD = nullptr) {
+ ValueMapper(VM, Flags, TypeMapper, Materializer, IdentityMD).remapFunction(F);
}
/// Version of MapValue with type safety for Constant.
inline Constant *MapValue(const Constant *V, ValueToValueMapTy &VM,
RemapFlags Flags = RF_None,
ValueMapTypeRemapper *TypeMapper = nullptr,
- ValueMaterializer *Materializer = nullptr) {
- return ValueMapper(VM, Flags, TypeMapper, Materializer).mapConstant(*V);
+ ValueMaterializer *Materializer = nullptr,
+ const MetadataSetTy *IdentityMD = nullptr) {
+ return ValueMapper(VM, Flags, TypeMapper, Materializer, IdentityMD)
+ .mapConstant(*V);
}
} // end namespace llvm
diff --git a/llvm/lib/Analysis/CGSCCPassManager.cpp b/llvm/lib/Analysis/CGSCCPassManager.cpp
index 948bc2435ab275..3ba085cdb0be8b 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<LazyCallGraphAnalysis>(M);
+ // Prime DebugInfoCache.
+ // TODO: Currently, the only user is CoroSplitPass. Consider running
+ // conditionally.
+ AM.getResult<DebugInfoCacheAnalysis>(M);
+
// Get Function analysis manager from its proxy.
FunctionAnalysisManager &FAM =
AM.getCachedResult<FunctionAnalysisManagerModuleProxy>(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<AllAnalysesOn<LazyCallGraph::SCC>>();
PA.preserve<LazyCallGraphAnalysis>();
+ PA.preserve<DebugI...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/109032
More information about the llvm-commits
mailing list