diff options
author | Vladislav Dzhidzhoev <vdzhidzhoev@accesssoftek.com> | 2023-06-15 18:04:32 +0200 |
---|---|---|
committer | Vladislav Dzhidzhoev <vdzhidzhoev@accesssoftek.com> | 2023-06-15 18:04:32 +0200 |
commit | fbdeb8cbc147f8f49fbd4bf23fae01bd142f0f5d (patch) | |
tree | adafb5b1b81e23b3f185cdcabc44ac42b844fa5d /llvm/lib | |
parent | dcdfc963d7934a1313094b6fe9ce7aa04debe495 (diff) | |
download | llvm-fbdeb8cbc147f8f49fbd4bf23fae01bd142f0f5d.zip llvm-fbdeb8cbc147f8f49fbd4bf23fae01bd142f0f5d.tar.gz llvm-fbdeb8cbc147f8f49fbd4bf23fae01bd142f0f5d.tar.bz2 |
Revert "[DebugMetadata][DwarfDebug] Fix DWARF emisson of function-local imported entities (3/7)"
This reverts commit d80fdc6fc1a6e717af1bcd7a7313e65de433ba85.
split-dwarf-local-impor3.ll fails because of an issue with
Dwo sections emission on Windows platform.
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Bitcode/Reader/MetadataLoader.cpp | 84 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp | 128 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h | 53 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 120 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h | 18 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfFile.h | 7 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h | 4 | ||||
-rw-r--r-- | llvm/lib/IR/DIBuilder.cpp | 20 | ||||
-rw-r--r-- | llvm/lib/IR/Verifier.cpp | 8 | ||||
-rw-r--r-- | llvm/lib/Linker/IRMover.cpp | 34 |
11 files changed, 176 insertions, 302 deletions
diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp index f13c26e..4b5cfed 100644 --- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp +++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp @@ -15,7 +15,6 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/STLFunctionalExtras.h" -#include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" @@ -54,7 +53,6 @@ #include <deque> #include <iterator> #include <limits> -#include <map> #include <optional> #include <string> #include <tuple> @@ -465,9 +463,6 @@ class MetadataLoader::MetadataLoaderImpl { bool NeedUpgradeToDIGlobalVariableExpression = false; bool NeedDeclareExpressionUpgrade = false; - /// Map DILocalScope to the enclosing DISubprogram, if any. - DenseMap<DILocalScope *, DISubprogram *> ParentSubprogram; - /// True if metadata is being parsed for a module being ThinLTO imported. bool IsImporting = false; @@ -526,84 +521,6 @@ class MetadataLoader::MetadataLoaderImpl { } } - DISubprogram *findEnclosingSubprogram(DILocalScope *S) { - if (!S) - return nullptr; - if (auto *SP = ParentSubprogram[S]) { - return SP; - } - - DILocalScope *InitialScope = S; - DenseSet<DILocalScope *> Visited; - while (S && !isa<DISubprogram>(S)) { - S = dyn_cast_or_null<DILocalScope>(S->getScope()); - if (Visited.contains(S)) - break; - Visited.insert(S); - } - ParentSubprogram[InitialScope] = llvm::dyn_cast_or_null<DISubprogram>(S); - - return ParentSubprogram[InitialScope]; - } - - /// Move local imports from DICompileUnit's 'imports' field to - /// DISubprogram's retainedNodes. - void upgradeCULocals() { - if (NamedMDNode *CUNodes = TheModule.getNamedMetadata("llvm.dbg.cu")) { - for (unsigned I = 0, E = CUNodes->getNumOperands(); I != E; ++I) { - auto *CU = dyn_cast<DICompileUnit>(CUNodes->getOperand(I)); - if (!CU) - continue; - - if (auto *RawImported = CU->getRawImportedEntities()) { - // Collect a set of imported entities to be moved. - SmallPtrSet<Metadata *, 8> EntitiesToRemove; - for (Metadata *Op : CU->getImportedEntities()->operands()) { - auto *IE = cast<DIImportedEntity>(Op); - if (auto *S = dyn_cast_or_null<DILocalScope>(IE->getScope())) { - EntitiesToRemove.insert(IE); - } - } - - if (!EntitiesToRemove.empty()) { - // Make a new list of CU's 'imports'. - SmallVector<Metadata *> NewImports; - for (Metadata *Op : CU->getImportedEntities()->operands()) { - if (!EntitiesToRemove.contains(cast<DIImportedEntity>(Op))) { - NewImports.push_back(Op); - } - } - - // Find DISubprogram corresponding to each entity. - std::map<DISubprogram *, SmallVector<Metadata *>> SPToEntities; - for (auto *I : EntitiesToRemove) { - auto *Entity = cast<DIImportedEntity>(I); - if (auto *SP = findEnclosingSubprogram( - cast<DILocalScope>(Entity->getScope()))) { - SPToEntities[SP].push_back(Entity); - } - } - - // Update DISubprograms' retainedNodes. - for (auto I = SPToEntities.begin(); I != SPToEntities.end(); ++I) { - auto *SP = I->first; - auto RetainedNodes = SP->getRetainedNodes(); - SmallVector<Metadata *> MDs(RetainedNodes.begin(), - RetainedNodes.end()); - MDs.append(I->second); - SP->replaceRetainedNodes(MDNode::get(Context, MDs)); - } - - // Remove entities with local scope from CU. - CU->replaceImportedEntities(MDTuple::get(Context, NewImports)); - } - } - } - } - - ParentSubprogram.clear(); - } - /// Remove a leading DW_OP_deref from DIExpressions in a dbg.declare that /// describes a function argument. void upgradeDeclareExpressions(Function &F) { @@ -708,7 +625,6 @@ class MetadataLoader::MetadataLoaderImpl { void upgradeDebugInfo() { upgradeCUSubprograms(); upgradeCUVariables(); - upgradeCULocals(); } void callMDTypeCallback(Metadata **Val, unsigned TypeID); diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index 58ed213..fd583a3 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -694,7 +694,7 @@ DIE *DwarfCompileUnit::constructInlinedScopeDIE(LexicalScope *Scope, auto *InlinedSP = getDISubprogram(DS); // Find the subprogram's DwarfCompileUnit in the SPMap in case the subprogram // was inlined from another compile unit. - DIE *OriginDIE = getAbstractScopeDIEs()[InlinedSP]; + DIE *OriginDIE = getAbstractSPDies()[InlinedSP]; assert(OriginDIE && "Unable to find original DIE for an inlined subprogram."); auto ScopeDIE = DIE::get(DIEValueAllocator, dwarf::DW_TAG_inlined_subroutine); @@ -726,20 +726,10 @@ DIE *DwarfCompileUnit::constructInlinedScopeDIE(LexicalScope *Scope, DIE *DwarfCompileUnit::constructLexicalScopeDIE(LexicalScope *Scope) { if (DD->isLexicalScopeDIENull(Scope)) return nullptr; - const auto *DS = Scope->getScopeNode(); auto ScopeDIE = DIE::get(DIEValueAllocator, dwarf::DW_TAG_lexical_block); - if (Scope->isAbstractScope()) { - assert(!getAbstractScopeDIEs().count(DS) && - "Abstract DIE for this scope exists!"); - getAbstractScopeDIEs()[DS] = ScopeDIE; + if (Scope->isAbstractScope()) return ScopeDIE; - } - if (!Scope->getInlinedAt()) { - assert(!LexicalBlockDIEs.count(DS) && - "Concrete out-of-line DIE for this scope exists!"); - LexicalBlockDIEs[DS] = ScopeDIE; - } attachRangesOrLowHighPC(*ScopeDIE, Scope->getRanges()); @@ -1107,35 +1097,35 @@ DIE *DwarfCompileUnit::createAndAddScopeChildren(LexicalScope *Scope, for (DbgVariable *DV : Locals) ScopeDIE.addChild(constructVariableDIE(*DV, *Scope, ObjectPointer)); + // Emit imported entities (skipped in gmlt-like data). + if (!includeMinimalInlineScopes()) { + for (const auto *IE : ImportedEntities[Scope->getScopeNode()]) + ScopeDIE.addChild(constructImportedEntityDIE(cast<DIImportedEntity>(IE))); + } + // Emit labels. for (DbgLabel *DL : DU->getScopeLabels().lookup(Scope)) ScopeDIE.addChild(constructLabelDIE(*DL, *Scope)); - // Track other local entities (skipped in gmlt-like data). - // This creates mapping between CU and a set of local declarations that - // should be emitted for subprograms in this CU. - if (!includeMinimalInlineScopes() && !Scope->getInlinedAt()) { - auto &LocalDecls = DD->getLocalDeclsForScope(Scope->getScopeNode()); - DeferredLocalDecls.insert(LocalDecls.begin(), LocalDecls.end()); - } - // Emit inner lexical scopes. - auto skipLexicalScope = [this](LexicalScope *S) -> bool { - if (isa<DISubprogram>(S->getScopeNode())) - return false; - auto Vars = DU->getScopeVariables().lookup(S); + auto needToEmitLexicalScope = [this](LexicalScope *LS) { + if (isa<DISubprogram>(LS->getScopeNode())) + return true; + auto Vars = DU->getScopeVariables().lookup(LS); if (!Vars.Args.empty() || !Vars.Locals.empty()) - return false; - return includeMinimalInlineScopes() || - DD->getLocalDeclsForScope(S->getScopeNode()).empty(); + return true; + if (!includeMinimalInlineScopes() && + !ImportedEntities[LS->getScopeNode()].empty()) + return true; + return false; }; for (LexicalScope *LS : Scope->getChildren()) { // If the lexical block doesn't have non-scope children, skip // its emission and put its children directly to the parent scope. - if (skipLexicalScope(LS)) - createAndAddScopeChildren(LS, ScopeDIE); - else + if (needToEmitLexicalScope(LS)) constructScopeDIE(LS, ScopeDIE); + else + createAndAddScopeChildren(LS, ScopeDIE); } return ObjectPointer; @@ -1143,10 +1133,12 @@ DIE *DwarfCompileUnit::createAndAddScopeChildren(LexicalScope *Scope, void DwarfCompileUnit::constructAbstractSubprogramScopeDIE( LexicalScope *Scope) { - auto *SP = cast<DISubprogram>(Scope->getScopeNode()); - if (getAbstractScopeDIEs().count(SP)) + DIE *&AbsDef = getAbstractSPDies()[Scope->getScopeNode()]; + if (AbsDef) return; + auto *SP = cast<DISubprogram>(Scope->getScopeNode()); + DIE *ContextDIE; DwarfCompileUnit *ContextCU = this; @@ -1169,19 +1161,14 @@ void DwarfCompileUnit::constructAbstractSubprogramScopeDIE( // Passing null as the associated node because the abstract definition // shouldn't be found by lookup. - DIE &AbsDef = ContextCU->createAndAddDIE(dwarf::DW_TAG_subprogram, - *ContextDIE, nullptr); - - // Store the DIE before creating children. - ContextCU->getAbstractScopeDIEs()[SP] = &AbsDef; - - ContextCU->applySubprogramAttributesToDefinition(SP, AbsDef); - ContextCU->addSInt(AbsDef, dwarf::DW_AT_inline, + AbsDef = &ContextCU->createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE, nullptr); + ContextCU->applySubprogramAttributesToDefinition(SP, *AbsDef); + ContextCU->addSInt(*AbsDef, dwarf::DW_AT_inline, DD->getDwarfVersion() <= 4 ? std::optional<dwarf::Form>() : dwarf::DW_FORM_implicit_const, dwarf::DW_INL_inlined); - if (DIE *ObjectPointer = ContextCU->createAndAddScopeChildren(Scope, AbsDef)) - ContextCU->addDIEEntry(AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer); + if (DIE *ObjectPointer = ContextCU->createAndAddScopeChildren(Scope, *AbsDef)) + ContextCU->addDIEEntry(*AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer); } bool DwarfCompileUnit::useGNUAnalogForDwarf5Feature() const { @@ -1325,20 +1312,12 @@ DIE *DwarfCompileUnit::constructImportedEntityDIE( EntityDie = getOrCreateNameSpace(NS); else if (auto *M = dyn_cast<DIModule>(Entity)) EntityDie = getOrCreateModule(M); - else if (auto *SP = dyn_cast<DISubprogram>(Entity)) { - // If there is an abstract subprogram, refer to it. Note that this assumes - // that all the abstract subprograms have been already created (which is - // correct until imported entities get emitted in DwarfDebug::endModule()). - if (auto *AbsSPDie = getAbstractScopeDIEs().lookup(SP)) - EntityDie = AbsSPDie; - else - EntityDie = getOrCreateSubprogramDIE(SP); - } else if (auto *T = dyn_cast<DIType>(Entity)) + else if (auto *SP = dyn_cast<DISubprogram>(Entity)) + EntityDie = getOrCreateSubprogramDIE(SP); + else if (auto *T = dyn_cast<DIType>(Entity)) EntityDie = getOrCreateTypeDIE(T); else if (auto *GV = dyn_cast<DIGlobalVariable>(Entity)) EntityDie = getOrCreateGlobalVariableDIE(GV, {}); - else if (auto *IE = dyn_cast<DIImportedEntity>(Entity)) - EntityDie = getOrCreateImportedEntityDIE(IE); else EntityDie = getDIE(Entity); assert(EntityDie); @@ -1369,24 +1348,9 @@ DIE *DwarfCompileUnit::constructImportedEntityDIE( return IMDie; } -DIE *DwarfCompileUnit::getOrCreateImportedEntityDIE( - const DIImportedEntity *IE) { - - // Check for pre-existence. - if (DIE *Die = getDIE(IE)) - return Die; - - DIE *ContextDIE = getOrCreateContextDIE(IE->getScope()); - assert(ContextDIE && "Empty scope for the imported entity!"); - - DIE *IMDie = constructImportedEntityDIE(IE); - ContextDIE->addChild(IMDie); - return IMDie; -} - void DwarfCompileUnit::finishSubprogramDefinition(const DISubprogram *SP) { DIE *D = getDIE(SP); - if (DIE *AbsSPDIE = getAbstractScopeDIEs().lookup(SP)) { + if (DIE *AbsSPDIE = getAbstractSPDies().lookup(SP)) { if (D) // If this subprogram has an abstract definition, reference that addDIEEntry(*D, dwarf::DW_AT_abstract_origin, *AbsSPDIE); @@ -1680,29 +1644,3 @@ void DwarfCompileUnit::createBaseTypeDIEs() { Btr.Die = &Die; } } - -DIE *DwarfCompileUnit::getLexicalBlockDIE(const DILexicalBlock *LB) { - // Assume if there is an abstract tree all the DIEs are already emitted. - bool isAbstract = getAbstractScopeDIEs().count(LB->getSubprogram()); - if (isAbstract && getAbstractScopeDIEs().count(LB)) - return getAbstractScopeDIEs()[LB]; - assert(!isAbstract && "Missed lexical block DIE in abstract tree!"); - - // Return a concrete DIE if it exists or nullptr otherwise. - return LexicalBlockDIEs.lookup(LB); -} - -DIE *DwarfCompileUnit::getOrCreateContextDIE(const DIScope *Context) { - if (isa_and_nonnull<DILocalScope>(Context)) { - if (auto *LFScope = dyn_cast<DILexicalBlockFile>(Context)) - Context = LFScope->getNonLexicalBlockFileScope(); - if (auto *LScope = dyn_cast<DILexicalBlock>(Context)) - return getLexicalBlockDIE(LScope); - - // Otherwise the context must be a DISubprogram. - auto *SPScope = cast<DISubprogram>(Context); - if (getAbstractScopeDIEs().count(SPScope)) - return getAbstractScopeDIEs()[SPScope]; - } - return DwarfUnit::getOrCreateContextDIE(Context); -} diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h index 6ef73eb..5581b91 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h @@ -61,6 +61,11 @@ class DwarfCompileUnit final : public DwarfUnit { /// The start of the unit macro info within macro section. MCSymbol *MacroLabelBegin; + using ImportedEntityList = SmallVector<const MDNode *, 8>; + using ImportedEntityMap = DenseMap<const MDNode *, ImportedEntityList>; + + ImportedEntityMap ImportedEntities; + /// GlobalNames - A map of globally visible named entities for this unit. StringMap<const DIE *> GlobalNames; @@ -74,20 +79,7 @@ class DwarfCompileUnit final : public DwarfUnit { // ranges/locs. const MCSymbol *BaseAddress = nullptr; - using MDNodeSetVector = - SetVector<const MDNode *, SmallVector<const MDNode *, 4>, - SmallPtrSet<const MDNode *, 4>>; - - // List of entities (either static locals, types or imports) that - // belong to subprograms within this CU. - MDNodeSetVector DeferredLocalDecls; - - // List of concrete lexical block scopes belong to subprograms within this CU. - DenseMap<const DILocalScope *, DIE *> LexicalBlockDIEs; - - // List of abstract local scopes (either DISubprogram or DILexicalBlock). - DenseMap<const DILocalScope *, DIE *> AbstractLocalScopeDIEs; - + DenseMap<const MDNode *, DIE *> AbstractSPDies; DenseMap<const DINode *, std::unique_ptr<DbgEntity>> AbstractEntities; /// DWO ID for correlating skeleton and split units. @@ -102,10 +94,10 @@ class DwarfCompileUnit final : public DwarfUnit { bool isDwoUnit() const override; - DenseMap<const DILocalScope *, DIE *> &getAbstractScopeDIEs() { + DenseMap<const MDNode *, DIE *> &getAbstractSPDies() { if (isDwoUnit() && !DD->shareAcrossDWOCUs()) - return AbstractLocalScopeDIEs; - return DU->getAbstractScopeDIEs(); + return AbstractSPDies; + return DU->getAbstractSPDies(); } DenseMap<const DINode *, std::unique_ptr<DbgEntity>> &getAbstractEntities() { @@ -183,6 +175,17 @@ public: unsigned getOrCreateSourceID(const DIFile *File) override; + void addImportedEntity(const DIImportedEntity* IE) { + DIScope *Scope = IE->getScope(); + assert(Scope && "Invalid Scope encoding!"); + if (!isa<DILocalScope>(Scope)) + // No need to add imported enities that are not local declaration. + return; + + auto *LocalScope = cast<DILocalScope>(Scope)->getNonLexicalBlockFileScope(); + ImportedEntities[LocalScope].push_back(IE); + } + /// addRange - Add an address range to the list of ranges for this unit. void addRange(RangeSpan Range); @@ -214,11 +217,6 @@ public: /// attach DW_AT_low_pc/DW_AT_high_pc labels. DIE *constructLexicalScopeDIE(LexicalScope *Scope); - /// Get a DIE for the given DILexicalBlock. - /// Note that this function assumes that the DIE has been already created - /// and it's an error, if it hasn't. - DIE *getLexicalBlockDIE(const DILexicalBlock *LB); - /// constructVariableDIE - Construct a DIE for the given DbgVariable. DIE *constructVariableDIE(DbgVariable &DV, bool Abstract = false); @@ -230,10 +228,6 @@ public: void createBaseTypeDIEs(); - /// Construct a DIE for a given scope. - /// This instance of 'getOrCreateContextDIE()' can handle DILocalScope. - DIE *getOrCreateContextDIE(const DIScope *Ty) override; - /// Construct a DIE for this subprogram scope. DIE &constructSubprogramScopeDIE(const DISubprogram *Sub, LexicalScope *Scope); @@ -272,9 +266,8 @@ public: void constructCallSiteParmEntryDIEs(DIE &CallSiteDIE, SmallVector<DbgCallSiteParam, 4> &Params); - /// Get or create a DIE for an imported entity. - DIE *getOrCreateImportedEntityDIE(const DIImportedEntity *IE); - DIE *constructImportedEntityDIE(const DIImportedEntity *IE); + /// Construct import_module DIE. + DIE *constructImportedEntityDIE(const DIImportedEntity *Module); void finishSubprogramDefinition(const DISubprogram *SP); void finishEntityDefinition(const DbgEntity *Entity); @@ -371,8 +364,6 @@ public: bool hasDwarfPubSections() const; void addBaseTypeRef(DIEValueList &Die, int64_t Idx); - - MDNodeSetVector &getDeferredLocalDecls() { return DeferredLocalDecls; } }; } // end namespace llvm diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 50ce812..67af6e9 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -507,7 +507,7 @@ void DwarfDebug::addSubprogramNames(const DICompileUnit &CU, // well into the name table. Only do that if we are going to actually emit // that name. if (SP->getLinkageName() != "" && SP->getName() != SP->getLinkageName() && - (useAllLinkageNames() || InfoHolder.getAbstractScopeDIEs().lookup(SP))) + (useAllLinkageNames() || InfoHolder.getAbstractSPDies().lookup(SP))) addAccelName(CU, SP->getLinkageName(), Die); // If this is an Objective-C selector name add it to the ObjC accelerator @@ -1105,6 +1105,9 @@ DwarfDebug::getOrCreateDwarfCompileUnit(const DICompileUnit *DIUnit) { DwarfCompileUnit &NewCU = *OwnedUnit; InfoHolder.addUnit(std::move(OwnedUnit)); + for (auto *IE : DIUnit->getImportedEntities()) + NewCU.addImportedEntity(IE); + // LTO with assembly output shares a single line table amongst multiple CUs. // To avoid the compilation directory being ambiguous, let the line table // explicitly describe the directory of all files, never relying on the @@ -1127,6 +1130,14 @@ DwarfDebug::getOrCreateDwarfCompileUnit(const DICompileUnit *DIUnit) { return NewCU; } +void DwarfDebug::constructAndAddImportedEntityDIE(DwarfCompileUnit &TheCU, + const DIImportedEntity *N) { + if (isa<DILocalScope>(N->getScope())) + return; + if (DIE *D = TheCU.getOrCreateContextDIE(N->getScope())) + D->addChild(TheCU.constructImportedEntityDIE(N)); +} + /// Sort and unique GVEs by comparing their fragment offset. static SmallVectorImpl<DwarfCompileUnit::GlobalExpr> & sortGlobalExprs(SmallVectorImpl<DwarfCompileUnit::GlobalExpr> &GVEs) { @@ -1204,8 +1215,16 @@ void DwarfDebug::beginModule(Module *M) { DebugLocs.setSym(Asm->createTempSymbol("loclists_table_base")); for (DICompileUnit *CUNode : M->debug_compile_units()) { - if (CUNode->getImportedEntities().empty() && - CUNode->getEnumTypes().empty() && CUNode->getRetainedTypes().empty() && + // FIXME: Move local imported entities into a list attached to the + // subprogram, then this search won't be needed and a + // getImportedEntities().empty() test should go below with the rest. + bool HasNonLocalImportedEntities = llvm::any_of( + CUNode->getImportedEntities(), [](const DIImportedEntity *IE) { + return !isa<DILocalScope>(IE->getScope()); + }); + + if (!HasNonLocalImportedEntities && CUNode->getEnumTypes().empty() && + CUNode->getRetainedTypes().empty() && CUNode->getGlobalVariables().empty() && CUNode->getMacros().empty()) continue; @@ -1423,17 +1442,8 @@ void DwarfDebug::endModule() { DwarfCompileUnit *CU = &*P.second; // Emit imported entities. - for (auto *IE : CUNode->getImportedEntities()) { - assert(!isa_and_nonnull<DILocalScope>(IE->getScope()) && - "Unexpected function-local entity in 'imports' CU field."); - CU->getOrCreateImportedEntityDIE(IE); - } - for (const auto *D : CU->getDeferredLocalDecls()) { - if (auto *IE = dyn_cast<DIImportedEntity>(D)) - CU->getOrCreateImportedEntityDIE(IE); - else - llvm_unreachable("Unexpected local retained node!"); - } + for (auto *IE : CUNode->getImportedEntities()) + constructAndAddImportedEntityDIE(*CU, IE); // Emit base types. CU->createBaseTypeDIEs(); @@ -1510,6 +1520,16 @@ void DwarfDebug::endModule() { // FIXME: AbstractVariables.clear(); } +void DwarfDebug::ensureAbstractEntityIsCreated(DwarfCompileUnit &CU, + const DINode *Node, + const MDNode *ScopeNode) { + if (CU.getExistingAbstractEntity(Node)) + return; + + CU.createAbstractEntity(Node, LScopes.getOrCreateAbstractScope( + cast<DILocalScope>(ScopeNode))); +} + void DwarfDebug::ensureAbstractEntityIsCreatedIfScoped(DwarfCompileUnit &CU, const DINode *Node, const MDNode *ScopeNode) { if (CU.getExistingAbstractEntity(Node)) @@ -1520,21 +1540,6 @@ void DwarfDebug::ensureAbstractEntityIsCreatedIfScoped(DwarfCompileUnit &CU, CU.createAbstractEntity(Node, Scope); } -static const DILocalScope *getRetainedNodeScope(const MDNode *N) { - const DIScope *S; - if (const auto *LV = dyn_cast<DILocalVariable>(N)) - S = LV->getScope(); - else if (const auto *L = dyn_cast<DILabel>(N)) - S = L->getScope(); - else if (const auto *IE = dyn_cast<DIImportedEntity>(N)) - S = IE->getScope(); - else - llvm_unreachable("Unexpected retained node!"); - - // Ensure the scope is not a DILexicalBlockFile. - return cast<DILocalScope>(S)->getNonLexicalBlockFileScope(); -} - // Collect variable information from side table maintained by MF. void DwarfDebug::collectVariableInfoFromMFTable( DwarfCompileUnit &TheCU, DenseSet<InlinedEntity> &Processed) { @@ -1979,18 +1984,19 @@ void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU, createConcreteEntity(TheCU, *Scope, Label, IL.second, Sym); } - // Collect info for retained nodes. + // Collect info for variables/labels that were optimized out. for (const DINode *DN : SP->getRetainedNodes()) { - const auto *LS = getRetainedNodeScope(DN); - if (isa<DILocalVariable>(DN) || isa<DILabel>(DN)) { - if (!Processed.insert(InlinedEntity(DN, nullptr)).second) - continue; - LexicalScope *LexS = LScopes.findLexicalScope(LS); - if (LexS) - createConcreteEntity(TheCU, *LexS, DN, nullptr); - } else { - LocalDeclsPerLS[LS].insert(DN); + if (!Processed.insert(InlinedEntity(DN, nullptr)).second) + continue; + LexicalScope *Scope = nullptr; + if (auto *DV = dyn_cast<DILocalVariable>(DN)) { + Scope = LScopes.findLexicalScope(DV->getScope()); + } else if (auto *DL = dyn_cast<DILabel>(DN)) { + Scope = LScopes.findLexicalScope(DL->getScope()); } + + if (Scope) + createConcreteEntity(TheCU, *Scope, DN, nullptr); } } @@ -2305,28 +2311,27 @@ void DwarfDebug::endFunctionImpl(const MachineFunction *MF) { } #ifndef NDEBUG - size_t NumAbstractSubprograms = LScopes.getAbstractScopesList().size(); + size_t NumAbstractScopes = LScopes.getAbstractScopesList().size(); #endif + // Construct abstract scopes. for (LexicalScope *AScope : LScopes.getAbstractScopesList()) { const auto *SP = cast<DISubprogram>(AScope->getScopeNode()); for (const DINode *DN : SP->getRetainedNodes()) { - const auto *LS = getRetainedNodeScope(DN); - // Ensure LexicalScope is created for the scope of this node. - auto *LexS = LScopes.getOrCreateAbstractScope(LS); - assert(LexS && "Expected the LexicalScope to be created."); - if (isa<DILocalVariable>(DN) || isa<DILabel>(DN)) { - // Collect info for variables/labels that were optimized out. - if (!Processed.insert(InlinedEntity(DN, nullptr)).second || - TheCU.getExistingAbstractEntity(DN)) - continue; - TheCU.createAbstractEntity(DN, LexS); - } else { - // Remember the node if this is a local declarations. - LocalDeclsPerLS[LS].insert(DN); - } - assert( - LScopes.getAbstractScopesList().size() == NumAbstractSubprograms && - "getOrCreateAbstractScope() inserted an abstract subprogram scope"); + if (!Processed.insert(InlinedEntity(DN, nullptr)).second) + continue; + + const MDNode *Scope = nullptr; + if (auto *DV = dyn_cast<DILocalVariable>(DN)) + Scope = DV->getScope(); + else if (auto *DL = dyn_cast<DILabel>(DN)) + Scope = DL->getScope(); + else + llvm_unreachable("Unexpected DI type!"); + + // Collect info for variables/labels that were optimized out. + ensureAbstractEntityIsCreated(TheCU, DN, Scope); + assert(LScopes.getAbstractScopesList().size() == NumAbstractScopes + && "ensureAbstractEntityIsCreated inserted abstract scopes"); } constructAbstractSubprogramScopeDIE(TheCU, AScope); } @@ -2347,7 +2352,6 @@ void DwarfDebug::endFunctionImpl(const MachineFunction *MF) { // can be used cross-function) InfoHolder.getScopeVariables().clear(); InfoHolder.getScopeLabels().clear(); - LocalDeclsPerLS.clear(); PrevLabel = nullptr; CurFn = nullptr; } diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h index 1af4b64..44b2f24 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -320,13 +320,6 @@ class DwarfDebug : public DebugHandlerBase { /// create DIEs. SmallSetVector<const DISubprogram *, 16> ProcessedSPNodes; - /// Map function-local imported entities to their parent local scope - /// (either DILexicalBlock or DISubprogram) for a processed function - /// (including inlined subprograms). - using MDNodeSet = SetVector<const MDNode *, SmallVector<const MDNode *, 2>, - SmallPtrSet<const MDNode *, 2>>; - DenseMap<const DILocalScope *, MDNodeSet> LocalDeclsPerLS; - /// If nonnull, stores the current machine function we're processing. const MachineFunction *CurFn = nullptr; @@ -461,6 +454,9 @@ private: using InlinedEntity = DbgValueHistoryMap::InlinedEntity; + void ensureAbstractEntityIsCreated(DwarfCompileUnit &CU, + const DINode *Node, + const MDNode *Scope); void ensureAbstractEntityIsCreatedIfScoped(DwarfCompileUnit &CU, const DINode *Node, const MDNode *Scope); @@ -600,6 +596,10 @@ private: void finishUnitAttributes(const DICompileUnit *DIUnit, DwarfCompileUnit &NewCU); + /// Construct imported_module or imported_declaration DIE. + void constructAndAddImportedEntityDIE(DwarfCompileUnit &TheCU, + const DIImportedEntity *N); + /// Register a source line with debug info. Returns the unique /// label that was emitted and which provides correspondence to the /// source line list. @@ -838,10 +838,6 @@ public: /// If the \p File has an MD5 checksum, return it as an MD5Result /// allocated in the MCContext. std::optional<MD5::MD5Result> getMD5AsBytes(const DIFile *File) const; - - MDNodeSet &getLocalDeclsForScope(const DILocalScope *S) { - return LocalDeclsPerLS[S]; - } }; } // end namespace llvm diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfFile.h b/llvm/lib/CodeGen/AsmPrinter/DwarfFile.h index 464f4f0..79a6ce7 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfFile.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfFile.h @@ -26,7 +26,6 @@ class DbgEntity; class DbgVariable; class DbgLabel; class DINode; -class DILocalScope; class DwarfCompileUnit; class DwarfUnit; class LexicalScope; @@ -88,7 +87,7 @@ class DwarfFile { DenseMap<LexicalScope *, LabelList> ScopeLabels; // Collection of abstract subprogram DIEs. - DenseMap<const DILocalScope *, DIE *> AbstractLocalScopeDIEs; + DenseMap<const MDNode *, DIE *> AbstractSPDies; DenseMap<const DINode *, std::unique_ptr<DbgEntity>> AbstractEntities; /// Maps MDNodes for type system with the corresponding DIEs. These DIEs can @@ -163,8 +162,8 @@ public: return ScopeLabels; } - DenseMap<const DILocalScope *, DIE *> &getAbstractScopeDIEs() { - return AbstractLocalScopeDIEs; + DenseMap<const MDNode *, DIE *> &getAbstractSPDies() { + return AbstractSPDies; } DenseMap<const DINode *, std::unique_ptr<DbgEntity>> &getAbstractEntities() { diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp index d30f0ef..c11e3d2 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -1223,7 +1223,7 @@ bool DwarfUnit::applySubprogramDefinitionAttributes(const DISubprogram *SP, "decl has a linkage name and it is different"); if (DeclLinkageName.empty() && // Always emit it for abstract subprograms. - (DD->useAllLinkageNames() || DU->getAbstractScopeDIEs().lookup(SP))) + (DD->useAllLinkageNames() || DU->getAbstractSPDies().lookup(SP))) addLinkageName(SPDie, LinkageName); if (!DeclDie) diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h index 8f17e94..0caa6ad 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h @@ -245,10 +245,10 @@ public: DIE *createTypeDIE(const DIScope *Context, DIE &ContextDIE, const DIType *Ty); /// Find existing DIE or create new DIE for the given type. - virtual DIE *getOrCreateTypeDIE(const MDNode *TyNode); + DIE *getOrCreateTypeDIE(const MDNode *TyNode); /// Get context owner's DIE. - virtual DIE *getOrCreateContextDIE(const DIScope *Context); + DIE *getOrCreateContextDIE(const DIScope *Context); /// Construct DIEs for types that contain vtables. void constructContainingTypeDIEs(); diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp index ae1a1a3..4fa61b8 100644 --- a/llvm/lib/IR/DIBuilder.cpp +++ b/llvm/lib/IR/DIBuilder.cpp @@ -35,7 +35,7 @@ DIBuilder::DIBuilder(Module &m, bool AllowUnresolvedNodes, DICompileUnit *CU) if (const auto &GVs = CUNode->getGlobalVariables()) AllGVs.assign(GVs.begin(), GVs.end()); if (const auto &IMs = CUNode->getImportedEntities()) - ImportedModules.assign(IMs.begin(), IMs.end()); + AllImportedModules.assign(IMs.begin(), IMs.end()); if (const auto &MNs = CUNode->getMacros()) AllMacrosPerParent.insert({nullptr, {MNs.begin(), MNs.end()}}); } @@ -93,10 +93,10 @@ void DIBuilder::finalize() { if (!AllGVs.empty()) CUNode->replaceGlobalVariables(MDTuple::get(VMContext, AllGVs)); - if (!ImportedModules.empty()) + if (!AllImportedModules.empty()) CUNode->replaceImportedEntities(MDTuple::get( - VMContext, SmallVector<Metadata *, 16>(ImportedModules.begin(), - ImportedModules.end()))); + VMContext, SmallVector<Metadata *, 16>(AllImportedModules.begin(), + AllImportedModules.end()))); for (const auto &I : AllMacrosPerParent) { // DIMacroNode's with nullptr parent are DICompileUnit direct children. @@ -160,7 +160,7 @@ static DIImportedEntity * createImportedModule(LLVMContext &C, dwarf::Tag Tag, DIScope *Context, Metadata *NS, DIFile *File, unsigned Line, StringRef Name, DINodeArray Elements, - SmallVectorImpl<TrackingMDNodeRef> &ImportedModules) { + SmallVectorImpl<TrackingMDNodeRef> &AllImportedModules) { if (Line) assert(File && "Source location has line number but no file"); unsigned EntitiesCount = C.pImpl->DIImportedEntitys.size(); @@ -169,7 +169,7 @@ createImportedModule(LLVMContext &C, dwarf::Tag Tag, DIScope *Context, if (EntitiesCount < C.pImpl->DIImportedEntitys.size()) // A new Imported Entity was just added to the context. // Add it to the Imported Modules list. - ImportedModules.emplace_back(M); + AllImportedModules.emplace_back(M); return M; } @@ -179,7 +179,7 @@ DIImportedEntity *DIBuilder::createImportedModule(DIScope *Context, DINodeArray Elements) { return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_module, Context, NS, File, Line, StringRef(), Elements, - getImportTrackingVector(Context)); + AllImportedModules); } DIImportedEntity *DIBuilder::createImportedModule(DIScope *Context, @@ -188,7 +188,7 @@ DIImportedEntity *DIBuilder::createImportedModule(DIScope *Context, DINodeArray Elements) { return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_module, Context, NS, File, Line, StringRef(), Elements, - getImportTrackingVector(Context)); + AllImportedModules); } DIImportedEntity *DIBuilder::createImportedModule(DIScope *Context, DIModule *M, @@ -196,7 +196,7 @@ DIImportedEntity *DIBuilder::createImportedModule(DIScope *Context, DIModule *M, DINodeArray Elements) { return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_module, Context, M, File, Line, StringRef(), Elements, - getImportTrackingVector(Context)); + AllImportedModules); } DIImportedEntity * @@ -207,7 +207,7 @@ DIBuilder::createImportedDeclaration(DIScope *Context, DINode *Decl, // types that have one. return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_declaration, Context, Decl, File, Line, Name, Elements, - getImportTrackingVector(Context)); + AllImportedModules); } DIFile *DIBuilder::createFile(StringRef Filename, StringRef Directory, diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 293d443..4c96bae 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -1383,11 +1383,9 @@ void Verifier::visitDISubprogram(const DISubprogram &N) { auto *Node = dyn_cast<MDTuple>(RawNode); CheckDI(Node, "invalid retained nodes list", &N, RawNode); for (Metadata *Op : Node->operands()) { - CheckDI(Op && (isa<DILocalVariable>(Op) || isa<DILabel>(Op) || - isa<DIImportedEntity>(Op)), - "invalid retained nodes, expected DILocalVariable, DILabel or " - "DIImportedEntity", - &N, Node, Op); + CheckDI(Op && (isa<DILocalVariable>(Op) || isa<DILabel>(Op)), + "invalid retained nodes, expected DILocalVariable or DILabel", &N, + Node, Op); } } CheckDI(!hasConflictingReferenceFlags(N.getFlags()), diff --git a/llvm/lib/Linker/IRMover.cpp b/llvm/lib/Linker/IRMover.cpp index df090c59..97794ee 100644 --- a/llvm/lib/Linker/IRMover.cpp +++ b/llvm/lib/Linker/IRMover.cpp @@ -1211,7 +1211,39 @@ void IRLinker::prepareCompileUnitsForImport() { // size inefficient. CU->replaceGlobalVariables(nullptr); - CU->replaceImportedEntities(nullptr); + // Imported entities only need to be mapped in if they have local + // scope, as those might correspond to an imported entity inside a + // function being imported (any locally scoped imported entities that + // don't end up referenced by an imported function will not be emitted + // into the object). Imported entities not in a local scope + // (e.g. on the namespace) only need to be emitted by the originating + // module. Create a list of the locally scoped imported entities, and + // replace the source CUs imported entity list with the new list, so + // only those are mapped in. + // FIXME: Locally-scoped imported entities could be moved to the + // functions they are local to instead of listing them on the CU, and + // we would naturally only link in those needed by function importing. + SmallVector<TrackingMDNodeRef, 4> AllImportedModules; + bool ReplaceImportedEntities = false; + for (auto *IE : CU->getImportedEntities()) { + DIScope *Scope = IE->getScope(); + assert(Scope && "Invalid Scope encoding!"); + if (isa<DILocalScope>(Scope)) + AllImportedModules.emplace_back(IE); + else + ReplaceImportedEntities = true; + } + if (ReplaceImportedEntities) { + if (!AllImportedModules.empty()) + CU->replaceImportedEntities(MDTuple::get( + CU->getContext(), + SmallVector<Metadata *, 16>(AllImportedModules.begin(), + AllImportedModules.end()))); + else + // If there were no local scope imported entities, we can map + // the whole list to nullptr. + CU->replaceImportedEntities(nullptr); + } } } |