diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index 518121e200190..ba8daf7662319 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -178,7 +178,7 @@ unsigned DwarfCompileUnit::getOrCreateSourceID(const DIFile *File) { DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE( const DIGlobalVariable *GV, ArrayRef GlobalExprs) { // Check for pre-existence. - if (DIE *Die = getDIE(GV)) + if (DIE *Die = getDIEs(GV).getVariableDIE(GV)) return Die; assert(GV); @@ -795,7 +795,9 @@ DIE *DwarfCompileUnit::constructLexicalScopeDIE(LexicalScope *Scope) { DIE *DwarfCompileUnit::constructVariableDIE(DbgVariable &DV, bool Abstract) { auto *VariableDie = DIE::get(DIEValueAllocator, DV.getTag()); - insertDIE(DV.getVariable(), VariableDie); + getDIEs(DV.getVariable()) + .getLVs() + .insertDIE(DV.getVariable(), &DV, VariableDie, Abstract); DV.setDIE(*VariableDie); // Abstract variables don't get common attributes later, so apply them now. if (Abstract) { @@ -1010,7 +1012,9 @@ DIE *DwarfCompileUnit::constructVariableDIE(DbgVariable &DV, DIE *DwarfCompileUnit::constructLabelDIE(DbgLabel &DL, const LexicalScope &Scope) { auto LabelDie = DIE::get(DIEValueAllocator, DL.getTag()); - insertDIE(DL.getLabel(), LabelDie); + getDIEs(DL.getLabel()) + .getLabels() + .insertDIE(DL.getLabel(), &DL, LabelDie, Scope.isAbstractScope()); DL.setDIE(*LabelDie); if (Scope.isAbstractScope()) @@ -1472,8 +1476,9 @@ DIE *DwarfCompileUnit::getOrCreateImportedEntityDIE( return IMDie; } -void DwarfCompileUnit::finishSubprogramDefinition(const DISubprogram *SP) { - DIE *D = getDIE(SP); +void DwarfCompileUnit::finishSubprogramDefinition(const DISubprogram *SP, + const Function *F) { + DIE *D = getDIEs(SP).getLocalScopes().getConcreteDIE(SP, F); if (DIE *AbsSPDIE = getAbstractScopeDIEs().lookup(SP)) { if (D) // If this subprogram has an abstract definition, reference that diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h index a3bbc8364599d..b0dcc3e432a03 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h @@ -79,16 +79,10 @@ class DwarfCompileUnit final : public DwarfUnit { // List of concrete lexical block scopes belong to subprograms within this CU. DenseMap LexicalBlockDIEs; - // List of abstract local scopes (either DISubprogram or DILexicalBlock). - DenseMap AbstractLocalScopeDIEs; - SmallPtrSet FinalizedAbstractSubprograms; - // List of inlined lexical block scopes that belong to subprograms within this // CU. DenseMap> InlinedLocalScopeDIEs; - DenseMap> AbstractEntities; - /// DWO ID for correlating skeleton and split units. uint64_t DWOId = 0; @@ -126,22 +120,20 @@ class DwarfCompileUnit final : public DwarfUnit { bool isDwoUnit() const override; - DenseMap &getAbstractScopeDIEs() { - if (isDwoUnit() && !DD->shareAcrossDWOCUs()) - return AbstractLocalScopeDIEs; - return DU->getAbstractScopeDIEs(); + DwarfInfoHolder &getDIEs(const DINode *N) { return DwarfUnit::getDIEs(N); } + + DwarfInfoHolder &getDIEs() { return getDIEs(nullptr); } + + DwarfInfoHolder::AbstractScopeMapT &getAbstractScopeDIEs() { + return getDIEs().getLocalScopes().getAbstractDIEs(); } DenseMap> &getAbstractEntities() { - if (isDwoUnit() && !DD->shareAcrossDWOCUs()) - return AbstractEntities; - return DU->getAbstractEntities(); + return getDIEs().getAbstractEntities(); } auto &getFinalizedAbstractSubprograms() { - if (isDwoUnit() && !DD->shareAcrossDWOCUs()) - return FinalizedAbstractSubprograms; - return DU->getFinalizedAbstractSubprograms(); + return getDIEs().getFinalizedAbstractSubprograms(); } void finishNonUnitTypeDIE(DIE& D, const DICompositeType *CTy) override; @@ -327,7 +319,7 @@ class DwarfCompileUnit final : public DwarfUnit { DIE *getOrCreateImportedEntityDIE(const DIImportedEntity *IE); DIE *constructImportedEntityDIE(const DIImportedEntity *IE); - void finishSubprogramDefinition(const DISubprogram *SP); + void finishSubprogramDefinition(const DISubprogram *SP, const Function *F); void finishEntityDefinition(const DbgEntity *Entity); void attachLexicalScopesAbstractOrigins(); diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index d751a7f9f01ef..5aa8b932facdc 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -502,7 +502,8 @@ void DwarfDebug::addSubprogramNames( // well into the name table. Only do that if we are going to actually emit // that name. if (LinkageName != "" && SP->getName() != LinkageName && - (useAllLinkageNames() || InfoHolder.getAbstractScopeDIEs().lookup(SP))) + (useAllLinkageNames() || + InfoHolder.getDIEs().getLocalScopes().getAbstractDIEs().lookup(SP))) addAccelName(Unit, NameTableKind, LinkageName, Die); // If this is an Objective-C selector name add it to the ObjC accelerator @@ -1263,11 +1264,13 @@ void DwarfDebug::finishEntityDefinitions() { } void DwarfDebug::finishSubprogramDefinitions() { - for (const DISubprogram *SP : ProcessedSPNodes) { + for (auto SPF : ProcessedSPNodes) { + const DISubprogram *SP = SPF.first; assert(SP->getUnit()->getEmissionKind() != DICompileUnit::NoDebug); - forBothCUs( - getOrCreateDwarfCompileUnit(SP->getUnit()), - [&](DwarfCompileUnit &CU) { CU.finishSubprogramDefinition(SP); }); + forBothCUs(getOrCreateDwarfCompileUnit(SP->getUnit()), + [&](DwarfCompileUnit &CU) { + CU.finishSubprogramDefinition(SP, SPF.second); + }); } } @@ -2784,7 +2787,7 @@ void DwarfDebug::endFunctionImpl(const MachineFunction *MF) { constructAbstractSubprogramScopeDIE(TheCU, AScope); } - ProcessedSPNodes.insert(SP); + ProcessedSPNodes.insert(std::make_pair(SP, &F)); DIE &ScopeDIE = TheCU.constructSubprogramScopeDIE(SP, F, FnScope, FunctionLineTableLabel); if (auto *SkelCU = TheCU.getSkeleton()) diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h index 1a1b28a6fc035..42ac225e2d17e 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -373,7 +373,8 @@ class DwarfDebug : public DebugHandlerBase { /// This is a collection of subprogram MDNodes that are processed to /// create DIEs. - SmallSetVector ProcessedSPNodes; + SmallSetVector, 16> + ProcessedSPNodes; /// Map function-local imported entities to their parent local scope /// (either DILexicalBlock or DISubprogram) for a processed function diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfFile.h b/llvm/lib/CodeGen/AsmPrinter/DwarfFile.h index ef1524d875c84..94d4e5f0b7f05 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfFile.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfFile.h @@ -15,9 +15,12 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/CodeGen/DIE.h" +#include "llvm/IR/DebugInfoMetadata.h" #include "llvm/Support/Allocator.h" +#include #include #include +#include #include namespace llvm { @@ -26,9 +29,6 @@ class AsmPrinter; class DbgEntity; class DbgVariable; class DbgLabel; -class DINode; -class DILocalScope; -class DISubprogram; class DwarfCompileUnit; class DwarfUnit; class LexicalScope; @@ -53,6 +53,144 @@ struct RangeSpanList { SmallVector Ranges; }; +/// Tracks abstract and concrete DIEs for debug info entities of a certain type. +template class DINodeInfoHolder { +public: + using AbstractMapT = DenseMap; + using ConcreteMapT = + DenseMap>; + +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> + 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 { +public: + using LocalScopeHolderT = DINodeInfoHolder; + using AbstractScopeMapT = LocalScopeHolderT::AbstractMapT; + +private: + /// DIEs of local DbgVariables. + DINodeInfoHolder LVHolder; + /// DIEs of labels. + DINodeInfoHolder LabelHolder; + DenseMap> AbstractEntities; + /// DIEs of abstract local scopes and concrete non-inlined subprograms. + /// Inlined subprograms and concrete lexical blocks are not stored here. + LocalScopeHolderT LSHolder; + /// Keeps track of abstract subprograms to populate them only once. + // FIXME: merge creation and population of abstract scopes. + SmallPtrSet FinalizedAbstractSubprograms; + + /// Other DINodes with the corresponding DIEs. + DenseMap MDNodeToDieMap; + +public: + void insertDIE(const DINode *N, DIE *Die) { + assert((!isa(N) && !isa(N) && + !isa(N)) && + "Use getLabels().insertDIE() for labels or getLVs().insertDIE() for " + "local variables, or getSubprogram().insertDIE() for subprograms."); + auto [_, Inserted] = MDNodeToDieMap.try_emplace(N, Die); + assert((Inserted || isa(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(N) && !isa(N) && + !isa(N))) && + "Use getLabels().getDIE() for labels or getLVs().getDIE() for " + "local variables, or getLocalScopes().getDIE() for local scopes."); + return D; + } + + auto &getLVs() { return LVHolder; } + auto &getLVs() const { return LVHolder; } + + auto &getLabels() { return LabelHolder; } + auto &getLabels() const { return LabelHolder; } + + auto &getLocalScopes() { return LSHolder; } + auto &getLocalScopes() const { return LSHolder; } + + /// For a global variable, returns DIE of the variable. + /// + /// For a local variable, returns abstract DIE of the variable. + /// If no abstract DIE was created, returns any concrete DIE of the variable. + DIE *getVariableDIE(const DIVariable *V) const { + if (auto *LV = dyn_cast(V)) + if (DIE *D = getLVs().getDIE(LV)) + return D; + return getDIE(V); + } + + DenseMap> &getAbstractEntities() { + return AbstractEntities; + } + + auto &getFinalizedAbstractSubprograms() { + return FinalizedAbstractSubprograms; + } +}; + class DwarfFile { // Target of Dwarf emission, used for sizing of abbreviations. AsmPrinter *Asm; @@ -93,17 +231,7 @@ class DwarfFile { using LabelList = SmallVector; DenseMap ScopeLabels; - // Collection of abstract subprogram DIEs. - DenseMap AbstractLocalScopeDIEs; - DenseMap> AbstractEntities; - /// Keeps track of abstract subprograms to populate them only once. - // FIXME: merge creation and population of abstract scopes. - SmallPtrSet FinalizedAbstractSubprograms; - - /// Maps MDNodes for type system with the corresponding DIEs. These DIEs can - /// be shared across CUs, that is why we keep the map here instead - /// of in DwarfCompileUnit. - DenseMap DITypeNodeToDieMap; + DwarfInfoHolder InfoHolder; public: DwarfFile(AsmPrinter *AP, StringRef Pref, BumpPtrAllocator &DA); @@ -171,25 +299,7 @@ class DwarfFile { return ScopeLabels; } - DenseMap &getAbstractScopeDIEs() { - return AbstractLocalScopeDIEs; - } - - DenseMap> &getAbstractEntities() { - return AbstractEntities; - } - - auto &getFinalizedAbstractSubprograms() { - return FinalizedAbstractSubprograms; - } - - void insertDIE(const MDNode *TypeMD, DIE *Die) { - DITypeNodeToDieMap.insert(std::make_pair(TypeMD, Die)); - } - - DIE *getDIE(const MDNode *TypeMD) { - return DITypeNodeToDieMap.lookup(TypeMD); - } + DwarfInfoHolder &getDIEs() { return InfoHolder; } }; } // end namespace llvm diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp index aa078f3f81d49..b0d0fa147b3fc 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -188,28 +188,16 @@ bool DwarfUnit::isShareableAcrossCUs(const DINode *D) const { // together. if (isDwoUnit() && !DD->shareAcrossDWOCUs()) return false; - return (isa(D) || - (isa(D) && !cast(D)->isDefinition())) && - !DD->generateTypeUnits(); -} - -DIE *DwarfUnit::getDIE(const DINode *D) const { - if (isShareableAcrossCUs(D)) - return DU->getDIE(D); - return MDNodeToDieMap.lookup(D); + return !D || ((isa(D) || (isa(D) && + !cast(D)->isDefinition())) && + !DD->generateTypeUnits()); } void DwarfUnit::insertDIE(const DINode *Desc, DIE *D) { - if (isShareableAcrossCUs(Desc)) { - DU->insertDIE(Desc, D); - return; - } - MDNodeToDieMap.insert(std::make_pair(Desc, D)); + getDIEs(Desc).insertDIE(Desc, D); } -void DwarfUnit::insertDIE(DIE *D) { - MDNodeToDieMap.insert(std::make_pair(nullptr, D)); -} +void DwarfUnit::insertDIE(DIE *D) { InfoHolder.insertDIE(D); } void DwarfUnit::addFlag(DIE &Die, dwarf::Attribute Attribute) { if (DD->getDwarfVersion() >= 4) @@ -424,6 +412,14 @@ DIE &DwarfUnit::createAndAddDIE(dwarf::Tag Tag, DIE &Parent, const DINode *N) { return Die; } +DIE &DwarfUnit::createAndAddSubprogramDIE(DIE &Parent, const DISubprogram *SP, + const Function *F) { + DIE &Die = + Parent.addChild(DIE::get(DIEValueAllocator, dwarf::DW_TAG_subprogram)); + getDIEs(SP).getLocalScopes().insertConcreteDIE(SP, F, &Die); + return Die; +} + void DwarfUnit::addBlock(DIE &Die, dwarf::Attribute Attribute, DIELoc *Loc) { Loc->computeSize(Asm->getDwarfFormParams()); DIELocs.push_back(Loc); // Memoize so we can call the destructor later on. @@ -803,7 +799,7 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DIStringType *STy) { addString(Buffer, dwarf::DW_AT_name, Name); if (DIVariable *Var = STy->getStringLength()) { - if (auto *VarDIE = getDIE(Var)) + if (auto *VarDIE = getDIEs(Var).getVariableDIE(Var)) addDIEEntry(Buffer, dwarf::DW_AT_string_length, *VarDIE); } else if (DIExpression *Expr = STy->getStringLengthExp()) { DIELoc *Loc = new (DIEValueAllocator) DIELoc; @@ -1122,8 +1118,8 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DICompositeType *CTy) { constructTypeDIE(VariantPart, Composite); } } else if (Tag == dwarf::DW_TAG_namelist) { - auto *Var = dyn_cast(Element); - auto *VarDIE = getDIE(Var); + auto *Var = dyn_cast(Element); + auto *VarDIE = getDIEs(Var).getVariableDIE(Var); if (VarDIE) { DIE &ItemDie = createAndAddDIE(dwarf::DW_TAG_namelist_item, Buffer); addDIEEntry(ItemDie, dwarf::DW_AT_namelist_item, *VarDIE); @@ -1185,7 +1181,7 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DICompositeType *CTy) { Tag == dwarf::DW_TAG_class_type || Tag == dwarf::DW_TAG_structure_type || Tag == dwarf::DW_TAG_union_type) { if (auto *Var = dyn_cast_or_null(CTy->getRawSizeInBits())) { - if (auto *VarDIE = getDIE(Var)) + if (auto *VarDIE = getDIEs(Var).getVariableDIE(Var)) addDIEEntry(Buffer, dwarf::DW_AT_bit_size, *VarDIE); } else if (auto *Exp = dyn_cast_or_null(CTy->getRawSizeInBits())) { @@ -1340,6 +1336,19 @@ DIE *DwarfUnit::getOrCreateModule(const DIModule *M) { return &MDie; } +DIE *DwarfUnit::getExistingSubprogramDIE(const DISubprogram *SP, + const Function *F) const { + if (!F) { + if (DIE *SPDie = getDIEs(SP).getLocalScopes().getAnyConcreteDIE(SP)) + return SPDie; + } else { + if (DIE *SPDie = getDIEs(SP).getLocalScopes().getConcreteDIE(SP, F)) + return SPDie; + } + + return nullptr; +} + DIE *DwarfUnit::getOrCreateSubprogramDIE(const DISubprogram *SP, const Function *FnHint, bool Minimal) { // Construct the context before querying for the existence of the DIE in case @@ -1348,7 +1357,7 @@ DIE *DwarfUnit::getOrCreateSubprogramDIE(const DISubprogram *SP, DIE *ContextDIE = getOrCreateSubprogramContextDIE(SP, shouldPlaceInUnitDIE(SP, Minimal)); - if (DIE *SPDie = getDIE(SP)) + if (DIE *SPDie = getExistingSubprogramDIE(SP, FnHint)) return SPDie; if (auto *SPDecl = SP->getDeclaration()) { @@ -1360,13 +1369,13 @@ DIE *DwarfUnit::getOrCreateSubprogramDIE(const DISubprogram *SP, // FIXME: Should the creation of definition subprogram DIE during // the creation of declaration subprogram DIE be allowed? // See https://github.com/llvm/llvm-project/pull/154636. - if (DIE *SPDie = getDIE(SP)) + if (DIE *SPDie = getExistingSubprogramDIE(SP, FnHint)) return SPDie; } } // DW_TAG_inlined_subroutine may refer to this DIE. - DIE &SPDie = createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE, SP); + DIE &SPDie = createAndAddSubprogramDIE(*ContextDIE, SP, FnHint); // Stop here and fill this in later, depending on whether or not this // subprogram turns out to have inlined instances or not. @@ -1392,7 +1401,8 @@ bool DwarfUnit::applySubprogramDefinitionAttributes(const DISubprogram *SP, if (DefinitionArgs[0] != nullptr && DeclArgs[0] != DefinitionArgs[0]) addType(SPDie, DefinitionArgs[0]); - DeclDie = getDIE(SPDecl); + DeclDie = + getDIEs(SPDecl).getLocalScopes().getConcreteDIE(SPDecl, nullptr); assert(DeclDie && "This DIE should've already been constructed when the " "definition DIE was created in " "getOrCreateSubprogramDIE"); @@ -1416,7 +1426,8 @@ bool DwarfUnit::applySubprogramDefinitionAttributes(const DISubprogram *SP, StringRef LinkageName = SP->getLinkageName(); // Always emit linkage name for abstract subprograms. if (DeclLinkageName != LinkageName && - (DD->useAllLinkageNames() || DU->getAbstractScopeDIEs().lookup(SP))) + (DD->useAllLinkageNames() || + DU->getDIEs().getLocalScopes().getAbstractDIEs().lookup(SP))) addLinkageName(SPDie, LinkageName); if (!DeclDie) @@ -1586,7 +1597,7 @@ void DwarfUnit::constructSubrangeDIE(DIE &DW_Subrange, const DISubrangeType *SR, auto AddBoundTypeEntry = [&](dwarf::Attribute Attr, DISubrangeType::BoundType Bound) -> void { if (auto *BV = dyn_cast_if_present(Bound)) { - if (auto *VarDIE = getDIE(BV)) + if (auto *VarDIE = getDIEs(BV).getVariableDIE(BV)) addDIEEntry(DW_Subrange, Attr, *VarDIE); } else if (auto *BE = dyn_cast_if_present(Bound)) { DIELoc *Loc = new (DIEValueAllocator) DIELoc; @@ -1628,7 +1639,7 @@ void DwarfUnit::constructSubrangeDIE(DIE &Buffer, const DISubrange *SR) { auto AddBoundTypeEntry = [&](dwarf::Attribute Attr, DISubrange::BoundType Bound) -> void { if (auto *BV = dyn_cast_if_present(Bound)) { - if (auto *VarDIE = getDIE(BV)) + if (auto *VarDIE = getDIEs(BV).getVariableDIE(BV)) addDIEEntry(DW_Subrange, Attr, *VarDIE); } else if (auto *BE = dyn_cast_if_present(Bound)) { DIELoc *Loc = new (DIEValueAllocator) DIELoc; @@ -1670,7 +1681,7 @@ void DwarfUnit::constructGenericSubrangeDIE(DIE &Buffer, auto AddBoundTypeEntry = [&](dwarf::Attribute Attr, DIGenericSubrange::BoundType Bound) -> void { if (auto *BV = dyn_cast_if_present(Bound)) { - if (auto *VarDIE = getDIE(BV)) + if (auto *VarDIE = getDIEs(BV).getVariableDIE(BV)) addDIEEntry(DwGenericSubrange, Attr, *VarDIE); } else if (auto *BE = dyn_cast_if_present(Bound)) { if (BE->isConstant() && @@ -1749,7 +1760,7 @@ void DwarfUnit::constructArrayTypeDIE(DIE &Buffer, const DICompositeType *CTy) { } if (DIVariable *Var = CTy->getDataLocation()) { - if (auto *VarDIE = getDIE(Var)) + if (auto *VarDIE = getDIEs(Var).getVariableDIE(Var)) addDIEEntry(Buffer, dwarf::DW_AT_data_location, *VarDIE); } else if (DIExpression *Expr = CTy->getDataLocationExp()) { DIELoc *Loc = new (DIEValueAllocator) DIELoc; @@ -1760,7 +1771,7 @@ void DwarfUnit::constructArrayTypeDIE(DIE &Buffer, const DICompositeType *CTy) { } if (DIVariable *Var = CTy->getAssociated()) { - if (auto *VarDIE = getDIE(Var)) + if (auto *VarDIE = getDIEs(Var).getVariableDIE(Var)) addDIEEntry(Buffer, dwarf::DW_AT_associated, *VarDIE); } else if (DIExpression *Expr = CTy->getAssociatedExp()) { DIELoc *Loc = new (DIEValueAllocator) DIELoc; @@ -1771,7 +1782,7 @@ void DwarfUnit::constructArrayTypeDIE(DIE &Buffer, const DICompositeType *CTy) { } if (DIVariable *Var = CTy->getAllocated()) { - if (auto *VarDIE = getDIE(Var)) + if (auto *VarDIE = getDIEs(Var).getVariableDIE(Var)) addDIEEntry(Buffer, dwarf::DW_AT_allocated, *VarDIE); } else if (DIExpression *Expr = CTy->getAllocatedExp()) { DIELoc *Loc = new (DIEValueAllocator) DIELoc; @@ -1896,7 +1907,7 @@ DIE &DwarfUnit::constructMemberDIE(DIE &Buffer, const DIDerivedType *DT) { if (DT->getRawSizeInBits() == nullptr) { // No size, just ignore. } else if (auto *Var = dyn_cast(DT->getRawSizeInBits())) { - if (auto *VarDIE = getDIE(Var)) + if (auto *VarDIE = getDIEs(Var).getVariableDIE(Var)) addDIEEntry(MemberDie, dwarf::DW_AT_bit_size, *VarDIE); } else if (auto *Exp = dyn_cast(DT->getRawSizeInBits())) { DIELoc *Loc = new (DIEValueAllocator) DIELoc; @@ -1921,7 +1932,7 @@ DIE &DwarfUnit::constructMemberDIE(DIE &Buffer, const DIDerivedType *DT) { // See https://dwarfstd.org/issues/250501.1.html if (auto *Var = dyn_cast_or_null(DT->getRawOffsetInBits())) { if (!Asm->TM.Options.DebugStrictDwarf || DD->getDwarfVersion() >= 6) { - if (auto *VarDIE = getDIE(Var)) + if (auto *VarDIE = getDIEs(Var).getVariableDIE(Var)) addDIEEntry(MemberDie, dwarf::DW_AT_data_bit_offset, *VarDIE); } } else if (auto *Expr = diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h index 9288d7edbf156..626e08964a875 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h @@ -61,7 +61,7 @@ class DwarfUnit : public DIEUnit { /// Tracks the mapping of unit level debug information variables to debug /// information entries. - DenseMap MDNodeToDieMap; + DwarfInfoHolder InfoHolder; /// A list of all the DIEBlocks in use. std::vector DIEBlocks; @@ -139,7 +139,7 @@ class DwarfUnit : public DIEUnit { /// We delegate the request to DwarfDebug when the MDNode can be part of the /// type system, since DIEs for the type system can be shared across CUs and /// the mappings are kept in DwarfDebug. - DIE *getDIE(const DINode *D) const; + DIE *getDIE(const DINode *D) const { return getDIEs(D).getDIE(D); } /// Returns a fresh newly allocated DIELoc. DIELoc *getDIELoc() { return new (DIEValueAllocator) DIELoc; } @@ -153,6 +153,18 @@ class DwarfUnit : public DIEUnit { void insertDIE(DIE *D); + const DwarfInfoHolder &getDIEs(const DINode *N) const { + if (isShareableAcrossCUs(N)) + return DU->getDIEs(); + + return InfoHolder; + } + + DwarfInfoHolder &getDIEs(const DINode *N) { + return const_cast( + const_cast(this)->getDIEs(N)); + } + /// Add a flag that is true to the DIE. void addFlag(DIE &Die, dwarf::Attribute Attribute); @@ -286,6 +298,8 @@ class DwarfUnit : public DIEUnit { /// Create a DIE with the given Tag, add the DIE to its parent, and /// call insertDIE if MD is not null. DIE &createAndAddDIE(dwarf::Tag Tag, DIE &Parent, const DINode *N = nullptr); + DIE &createAndAddSubprogramDIE(DIE &Parent, const DISubprogram *SP, + const Function *F); bool useSegmentedStringOffsetsTable() const { return DD->useSegmentedStringOffsetsTable(); @@ -387,6 +401,9 @@ class DwarfUnit : public DIEUnit { void constructTemplateValueParameterDIE(DIE &Buffer, const DITemplateValueParameter *TVP); + DIE *getExistingSubprogramDIE(const DISubprogram *SP, + const Function *FnHint) const; + /// Return the default lower bound for an array. /// /// If the DWARF version doesn't handle the language, return -1.