Skip to content

Commit 0cd4da0

Browse files
committed
[DwarfDebug] Associate subprogram DIEs with their Functions
Depends on: * llvm#152680 With this change, DINodeInfoHolder is used to store abstract and concrete out-of-line subprogram DIEs in DwarfInfoHolder. Every definition subprogram DIE is associated with a corresponding llvm::Function (declaration subprograms are associated with nullptr). When a concrete subprogram DIE is queried via `getOrCreateSubprogramDIE`, the corresponding llvm::Function should be provided. If none is provided: * DwarfUnit/DwarfTypeUnit falls back and returns any concrete DIE for the given DISubprogram, * DwarfCompileUnit is expected to return abstract DIE. This is a step to support attachment of a DISubprogram to multiple llvm::Functions (and to establish one-to-one-to-many correspondence between DISubprograms, abstract DIEs and function clones, and, later, to make the backend use uniquied DISubprograms).
1 parent b0c8d99 commit 0cd4da0

File tree

7 files changed

+63
-27
lines changed

7 files changed

+63
-27
lines changed

llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1476,8 +1476,9 @@ DIE *DwarfCompileUnit::getOrCreateImportedEntityDIE(
14761476
return IMDie;
14771477
}
14781478

1479-
void DwarfCompileUnit::finishSubprogramDefinition(const DISubprogram *SP) {
1480-
DIE *D = getDIE(SP);
1479+
void DwarfCompileUnit::finishSubprogramDefinition(const DISubprogram *SP,
1480+
const Function *F) {
1481+
DIE *D = getDIEs(SP).getLocalScopes().getConcreteDIE(SP, F);
14811482
if (DIE *AbsSPDIE = getAbstractScopeDIEs().lookup(SP)) {
14821483
if (D)
14831484
// If this subprogram has an abstract definition, reference that

llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,8 @@ class DwarfCompileUnit final : public DwarfUnit {
124124

125125
DwarfInfoHolder &getDIEs() { return getDIEs(nullptr); }
126126

127-
DenseMap<const DILocalScope *, DIE *> &getAbstractScopeDIEs() {
128-
return getDIEs().getAbstractScopeDIEs();
127+
DwarfInfoHolder::AbstractScopeMapT &getAbstractScopeDIEs() {
128+
return getDIEs().getLocalScopes().getAbstractDIEs();
129129
}
130130

131131
DenseMap<const DINode *, std::unique_ptr<DbgEntity>> &getAbstractEntities() {
@@ -319,7 +319,7 @@ class DwarfCompileUnit final : public DwarfUnit {
319319
DIE *getOrCreateImportedEntityDIE(const DIImportedEntity *IE);
320320
DIE *constructImportedEntityDIE(const DIImportedEntity *IE);
321321

322-
void finishSubprogramDefinition(const DISubprogram *SP);
322+
void finishSubprogramDefinition(const DISubprogram *SP, const Function *F);
323323
void finishEntityDefinition(const DbgEntity *Entity);
324324
void attachLexicalScopesAbstractOrigins();
325325

llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,7 @@ void DwarfDebug::addSubprogramNames(
503503
// that name.
504504
if (LinkageName != "" && SP->getName() != LinkageName &&
505505
(useAllLinkageNames() ||
506-
InfoHolder.getDIEs().getAbstractScopeDIEs().lookup(SP)))
506+
InfoHolder.getDIEs().getLocalScopes().getAbstractDIEs().lookup(SP)))
507507
addAccelName(Unit, NameTableKind, LinkageName, Die);
508508

509509
// If this is an Objective-C selector name add it to the ObjC accelerator
@@ -1264,11 +1264,13 @@ void DwarfDebug::finishEntityDefinitions() {
12641264
}
12651265

12661266
void DwarfDebug::finishSubprogramDefinitions() {
1267-
for (const DISubprogram *SP : ProcessedSPNodes) {
1267+
for (auto SPF : ProcessedSPNodes) {
1268+
const DISubprogram *SP = SPF.first;
12681269
assert(SP->getUnit()->getEmissionKind() != DICompileUnit::NoDebug);
1269-
forBothCUs(
1270-
getOrCreateDwarfCompileUnit(SP->getUnit()),
1271-
[&](DwarfCompileUnit &CU) { CU.finishSubprogramDefinition(SP); });
1270+
forBothCUs(getOrCreateDwarfCompileUnit(SP->getUnit()),
1271+
[&](DwarfCompileUnit &CU) {
1272+
CU.finishSubprogramDefinition(SP, SPF.second);
1273+
});
12721274
}
12731275
}
12741276

@@ -2785,7 +2787,7 @@ void DwarfDebug::endFunctionImpl(const MachineFunction *MF) {
27852787
constructAbstractSubprogramScopeDIE(TheCU, AScope);
27862788
}
27872789

2788-
ProcessedSPNodes.insert(SP);
2790+
ProcessedSPNodes.insert(std::make_pair(SP, &F));
27892791
DIE &ScopeDIE =
27902792
TheCU.constructSubprogramScopeDIE(SP, F, FnScope, FunctionLineTableLabel);
27912793
if (auto *SkelCU = TheCU.getSkeleton())

llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,8 @@ class DwarfDebug : public DebugHandlerBase {
373373

374374
/// This is a collection of subprogram MDNodes that are processed to
375375
/// create DIEs.
376-
SmallSetVector<const DISubprogram *, 16> ProcessedSPNodes;
376+
SmallSetVector<std::pair<const DISubprogram *, const Function *>, 16>
377+
ProcessedSPNodes;
377378

378379
/// Map function-local imported entities to their parent local scope
379380
/// (either DILexicalBlock or DISubprogram) for a processed function

llvm/lib/CodeGen/AsmPrinter/DwarfFile.h

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -119,18 +119,20 @@ class DwarfInfoHolder {
119119
public:
120120
using LVMapT = DINodeMap<DILocalVariable, DbgVariable>;
121121
using LabelMapT = DINodeMap<DILabel, DbgLabel>;
122+
using LocalScopeMapT = DINodeMap<DILocalScope, Function>;
122123
using AbstractEntityMapT =
123124
DenseMap<const DINode *, std::unique_ptr<DbgEntity>>;
124-
using AbstractScopeMapT = DenseMap<const DILocalScope *, DIE *>;
125+
using AbstractScopeMapT = LocalScopeMapT::AbstractMapT;
125126

126127
private:
127128
/// DIEs of local DbgVariables.
128129
LVMapT LVMap;
129130
/// DIEs of labels.
130131
LabelMapT LabelMap;
131132
AbstractEntityMapT AbstractEntities;
132-
// List of abstract local scopes (either DISubprogram or DILexicalBlock).
133-
AbstractScopeMapT AbstractLocalScopeDIEs;
133+
/// DIEs of abstract local scopes and concrete non-inlined subprograms.
134+
/// Inlined subprograms and concrete lexical blocks are not stored here.
135+
LocalScopeMapT LSMap;
134136
/// Keeps track of abstract subprograms to populate them only once.
135137
// FIXME: merge creation and population of abstract scopes.
136138
SmallPtrSet<const DISubprogram *, 8> FinalizedAbstractSubprograms;
@@ -140,21 +142,23 @@ class DwarfInfoHolder {
140142

141143
public:
142144
void insertDIE(const DINode *N, DIE *Die) {
143-
assert((!isa<DILabel>(N) && !isa<DILocalVariable>(N)) &&
145+
assert((!isa<DILabel>(N) && !isa<DILocalVariable>(N) &&
146+
!isa<DILocalScope>(N)) &&
144147
"Use getLabels().insertDIE() for labels or getLVs().insertDIE() for "
145-
"local variables");
148+
"local variables, or getSubprogram().insertDIE() for subprograms.");
146149
auto [_, Inserted] = MDNodeToDieMap.try_emplace(N, Die);
147-
assert((Inserted || isa<DISubprogram>(N) || isa<DIType>(N)) &&
150+
assert((Inserted || isa<DIType>(N)) &&
148151
"DIE for this DINode has already been added");
149152
}
150153

151154
void insertDIE(DIE *D) { MDNodeToDieMap.try_emplace(nullptr, D); }
152155

153156
DIE *getDIE(const DINode *N) const {
154157
DIE *D = MDNodeToDieMap.lookup(N);
155-
assert((!D || (!isa<DILabel>(N) && !isa<DILocalVariable>(N))) &&
158+
assert((!D || (!isa<DILabel>(N) && !isa<DILocalVariable>(N) &&
159+
!isa<DILocalScope>(N))) &&
156160
"Use getLabels().getDIE() for labels or getLVs().getDIE() for "
157-
"local variables");
161+
"local variables, or getLocalScopes().getDIE() for local scopes.");
158162
return D;
159163
}
160164

@@ -164,6 +168,9 @@ class DwarfInfoHolder {
164168
LabelMapT &getLabels() { return LabelMap; }
165169
const LabelMapT &getLabels() const { return LabelMap; }
166170

171+
LocalScopeMapT &getLocalScopes() { return LSMap; }
172+
const LocalScopeMapT &getLocalScopes() const { return LSMap; }
173+
167174
/// For a global variable, returns DIE of the variable.
168175
///
169176
/// For a local variable, returns abstract DIE of the variable.
@@ -175,8 +182,6 @@ class DwarfInfoHolder {
175182
return getDIE(V);
176183
}
177184

178-
AbstractScopeMapT &getAbstractScopeDIEs() { return AbstractLocalScopeDIEs; }
179-
180185
AbstractEntityMapT &getAbstractEntities() { return AbstractEntities; }
181186

182187
auto &getFinalizedAbstractSubprograms() {

llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,14 @@ DIE &DwarfUnit::createAndAddDIE(dwarf::Tag Tag, DIE &Parent, const DINode *N) {
412412
return Die;
413413
}
414414

415+
DIE &DwarfUnit::createAndAddSubprogramDIE(DIE &Parent, const DISubprogram *SP,
416+
const Function *F) {
417+
DIE &Die =
418+
Parent.addChild(DIE::get(DIEValueAllocator, dwarf::DW_TAG_subprogram));
419+
getDIEs(SP).getLocalScopes().insertConcreteDIE(SP, F, &Die);
420+
return Die;
421+
}
422+
415423
void DwarfUnit::addBlock(DIE &Die, dwarf::Attribute Attribute, DIELoc *Loc) {
416424
Loc->computeSize(Asm->getDwarfFormParams());
417425
DIELocs.push_back(Loc); // Memoize so we can call the destructor later on.
@@ -1328,6 +1336,19 @@ DIE *DwarfUnit::getOrCreateModule(const DIModule *M) {
13281336
return &MDie;
13291337
}
13301338

1339+
DIE *DwarfUnit::getExistingSubprogramDIE(const DISubprogram *SP,
1340+
const Function *F) const {
1341+
if (!F) {
1342+
if (DIE *SPDie = getDIEs(SP).getLocalScopes().getAnyConcreteDIE(SP))
1343+
return SPDie;
1344+
} else {
1345+
if (DIE *SPDie = getDIEs(SP).getLocalScopes().getConcreteDIE(SP, F))
1346+
return SPDie;
1347+
}
1348+
1349+
return nullptr;
1350+
}
1351+
13311352
DIE *DwarfUnit::getOrCreateSubprogramDIE(const DISubprogram *SP,
13321353
const Function *FnHint, bool Minimal) {
13331354
// Construct the context before querying for the existence of the DIE in case
@@ -1336,7 +1357,7 @@ DIE *DwarfUnit::getOrCreateSubprogramDIE(const DISubprogram *SP,
13361357
DIE *ContextDIE =
13371358
getOrCreateSubprogramContextDIE(SP, shouldPlaceInUnitDIE(SP, Minimal));
13381359

1339-
if (DIE *SPDie = getDIE(SP))
1360+
if (DIE *SPDie = getExistingSubprogramDIE(SP, FnHint))
13401361
return SPDie;
13411362

13421363
if (auto *SPDecl = SP->getDeclaration()) {
@@ -1348,13 +1369,13 @@ DIE *DwarfUnit::getOrCreateSubprogramDIE(const DISubprogram *SP,
13481369
// FIXME: Should the creation of definition subprogram DIE during
13491370
// the creation of declaration subprogram DIE be allowed?
13501371
// See https://github.com/llvm/llvm-project/pull/154636.
1351-
if (DIE *SPDie = getDIE(SP))
1372+
if (DIE *SPDie = getExistingSubprogramDIE(SP, FnHint))
13521373
return SPDie;
13531374
}
13541375
}
13551376

13561377
// DW_TAG_inlined_subroutine may refer to this DIE.
1357-
DIE &SPDie = createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE, SP);
1378+
DIE &SPDie = createAndAddSubprogramDIE(*ContextDIE, SP, FnHint);
13581379

13591380
// Stop here and fill this in later, depending on whether or not this
13601381
// subprogram turns out to have inlined instances or not.
@@ -1380,7 +1401,8 @@ bool DwarfUnit::applySubprogramDefinitionAttributes(const DISubprogram *SP,
13801401
if (DefinitionArgs[0] != nullptr && DeclArgs[0] != DefinitionArgs[0])
13811402
addType(SPDie, DefinitionArgs[0]);
13821403

1383-
DeclDie = getDIE(SPDecl);
1404+
DeclDie =
1405+
getDIEs(SPDecl).getLocalScopes().getConcreteDIE(SPDecl, nullptr);
13841406
assert(DeclDie && "This DIE should've already been constructed when the "
13851407
"definition DIE was created in "
13861408
"getOrCreateSubprogramDIE");
@@ -1405,7 +1427,7 @@ bool DwarfUnit::applySubprogramDefinitionAttributes(const DISubprogram *SP,
14051427
// Always emit linkage name for abstract subprograms.
14061428
if (DeclLinkageName != LinkageName &&
14071429
(DD->useAllLinkageNames() ||
1408-
DU->getDIEs().getAbstractScopeDIEs().lookup(SP)))
1430+
DU->getDIEs().getLocalScopes().getAbstractDIEs().lookup(SP)))
14091431
addLinkageName(SPDie, LinkageName);
14101432

14111433
if (!DeclDie)

llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,8 @@ class DwarfUnit : public DIEUnit {
298298
/// Create a DIE with the given Tag, add the DIE to its parent, and
299299
/// call insertDIE if MD is not null.
300300
DIE &createAndAddDIE(dwarf::Tag Tag, DIE &Parent, const DINode *N = nullptr);
301+
DIE &createAndAddSubprogramDIE(DIE &Parent, const DISubprogram *SP,
302+
const Function *F);
301303

302304
bool useSegmentedStringOffsetsTable() const {
303305
return DD->useSegmentedStringOffsetsTable();
@@ -399,6 +401,9 @@ class DwarfUnit : public DIEUnit {
399401
void constructTemplateValueParameterDIE(DIE &Buffer,
400402
const DITemplateValueParameter *TVP);
401403

404+
DIE *getExistingSubprogramDIE(const DISubprogram *SP,
405+
const Function *FnHint) const;
406+
402407
/// Return the default lower bound for an array.
403408
///
404409
/// If the DWARF version doesn't handle the language, return -1.

0 commit comments

Comments
 (0)