[llvm] [DwarfDebug] Track abstract entities in DwarfUnit separately (PR #152680)
David Blaikie via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 10 22:08:00 PDT 2025
================
@@ -53,6 +53,137 @@ struct RangeSpanList {
SmallVector<RangeSpan, 2> Ranges;
};
+/// Tracks abstract and concrete DIEs for debug info entities of a certain type.
+template <typename DINodeT, typename DbgEntityT> class DINodeInfoHolder {
+public:
+ using AbstractMapT = DenseMap<const DINodeT *, DIE *>;
+ using ConcreteMapT =
+ DenseMap<const DINodeT *, SmallDenseMap<const DbgEntityT *, DIE *, 2>>;
+
+private:
+ AbstractMapT AbstractMap;
+ ConcreteMapT ConcreteMap;
+
+public:
+ void insertAbstractDIE(const DINodeT *N, DIE *D) {
+ auto [_, Inserted] = AbstractMap.try_emplace(N, D);
+ assert(Inserted && "Duplicate abstract DIE for debug info node");
+ }
+
+ void insertConcreteDIE(const DINodeT *N, const DbgEntityT *E, DIE *D) {
+ auto [_, Inserted] = ConcreteMap[N].try_emplace(E, D);
+ assert(Inserted && "Duplicate concrete DIE for debug info node");
+ }
+
+ void insertDIE(const DINodeT *N, const DbgEntityT *E, DIE *D, bool Abstract) {
+ if (Abstract)
+ insertAbstractDIE(N, D);
+ else
+ insertConcreteDIE(N, E, D);
+ }
+
+ DIE *getAbstractDIE(const DINodeT *N) const { return AbstractMap.lookup(N); }
+
+ std::optional<
+ std::reference_wrapper<const typename ConcreteMapT::mapped_type>>
+ getConcreteDIEs(const DINodeT *N) const {
+ if (auto I = ConcreteMap.find(N); I != ConcreteMap.end())
+ return std::make_optional(std::ref(I->second));
+ return std::nullopt;
+ }
+
+ DIE *getConcreteDIE(const DINodeT *N, const DbgEntityT *E) const {
+ if (auto I = getConcreteDIEs(N))
+ return I->get().lookup(E);
+ return nullptr;
+ }
+
+ DIE *getAnyConcreteDIE(const DINodeT *N) const {
+ if (auto I = getConcreteDIEs(N))
+ return I->get().empty() ? nullptr : I->get().begin()->second;
+ return nullptr;
+ }
+
+ /// Returns abstract DIE for the entity.
+ /// If no abstract DIE was created, returns any concrete DIE for the entity.
+ DIE *getDIE(const DINodeT *N) const {
+ if (DIE *D = getAbstractDIE(N))
+ return D;
+
+ return getAnyConcreteDIE(N);
+ }
+
+ AbstractMapT &getAbstractDIEs() { return AbstractMap; }
+};
+
+/// Tracks DIEs for debug info entites.
+/// These DIEs can be shared across CUs, that is why we keep the map here
+/// instead of in DwarfCompileUnit.
+class DwarfInfoHolder {
+ /// DIEs of local DbgVariables.
+ DINodeInfoHolder<DILocalVariable, DbgVariable> LVHolder;
+ /// DIEs of labels.
+ DINodeInfoHolder<DILabel, DbgLabel> LabelHolder;
+ DenseMap<const DINode *, std::unique_ptr<DbgEntity>> AbstractEntities;
+ // List of abstract local scopes (either DISubprogram or DILexicalBlock).
+ DenseMap<const DILocalScope *, DIE *> AbstractLocalScopeDIEs;
+ /// Keeps track of abstract subprograms to populate them only once.
+ // FIXME: merge creation and population of abstract scopes.
+ SmallPtrSet<const DISubprogram *, 8> FinalizedAbstractSubprograms;
+
+ /// Other DINodes with the corresponding DIEs.
+ DenseMap<const DINode *, DIE *> MDNodeToDieMap;
+
+public:
+ void insertDIE(const DINode *N, DIE *Die) {
+ assert((!isa<DILabel>(N) && !isa<DILocalVariable>(N)) &&
+ "Use getLabels().insertDIE() for labels or getLVs().insertDIE() for "
+ "local variables");
+ auto [_, Inserted] = MDNodeToDieMap.try_emplace(N, Die);
+ assert((Inserted || isa<DISubprogram>(N) || isa<DIType>(N)) &&
+ "DIE for this DINode has already been added");
+ }
+
+ void insertDIE(DIE *D) { MDNodeToDieMap.try_emplace(nullptr, D); }
+
+ DIE *getDIE(const DINode *N) const {
+ DIE *D = MDNodeToDieMap.lookup(N);
+ assert((!D || (!isa<DILabel>(N) && !isa<DILocalVariable>(N))) &&
+ "Use getLabels().getDIE() for labels or getLVs().getDIE() for "
+ "local variables");
+ return D;
+ }
+
+ auto &getLVs() { return LVHolder; }
+ auto &getLVs() const { return LVHolder; }
+
+ auto &getLabels() { return LabelHolder; }
+ auto &getLabels() const { return LabelHolder; }
----------------
dwblaikie wrote:
Probably worth spelling out the return types
https://github.com/llvm/llvm-project/pull/152680
More information about the llvm-commits
mailing list