aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib
diff options
context:
space:
mode:
authorVladislav Dzhidzhoev <vdzhidzhoev@accesssoftek.com>2023-06-15 18:04:32 +0200
committerVladislav Dzhidzhoev <vdzhidzhoev@accesssoftek.com>2023-06-15 18:04:32 +0200
commitfbdeb8cbc147f8f49fbd4bf23fae01bd142f0f5d (patch)
treeadafb5b1b81e23b3f185cdcabc44ac42b844fa5d /llvm/lib
parentdcdfc963d7934a1313094b6fe9ce7aa04debe495 (diff)
downloadllvm-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.cpp84
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp128
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h53
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp120
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h18
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfFile.h7
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp2
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h4
-rw-r--r--llvm/lib/IR/DIBuilder.cpp20
-rw-r--r--llvm/lib/IR/Verifier.cpp8
-rw-r--r--llvm/lib/Linker/IRMover.cpp34
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);
+ }
}
}