Skip to content

Commit 7745940

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 6442e01 commit 7745940

File tree

7 files changed

+66
-28
lines changed

7 files changed

+66
-28
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: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -120,13 +120,19 @@ template <typename DINodeT, typename DbgEntityT> class DINodeInfoHolder {
120120
/// These DIEs can be shared across CUs, that is why we keep the map here
121121
/// instead of in DwarfCompileUnit.
122122
class DwarfInfoHolder {
123+
public:
124+
using LocalScopeHolderT = DINodeInfoHolder<DILocalScope, Function>;
125+
using AbstractScopeMapT = LocalScopeHolderT::AbstractMapT;
126+
127+
private:
123128
/// DIEs of local DbgVariables.
124129
DINodeInfoHolder<DILocalVariable, DbgVariable> LVHolder;
125130
/// DIEs of labels.
126131
DINodeInfoHolder<DILabel, DbgLabel> LabelHolder;
127132
DenseMap<const DINode *, std::unique_ptr<DbgEntity>> AbstractEntities;
128-
// List of abstract local scopes (either DISubprogram or DILexicalBlock).
129-
DenseMap<const DILocalScope *, DIE *> AbstractLocalScopeDIEs;
133+
/// DIEs of abstract local scopes and concrete non-inlined subprograms.
134+
/// Inlined subprograms and concrete lexical blocks are not stored here.
135+
LocalScopeHolderT LSHolder;
130136
/// Keeps track of abstract subprograms to populate them only once.
131137
// FIXME: merge creation and population of abstract scopes.
132138
SmallPtrSet<const DISubprogram *, 8> FinalizedAbstractSubprograms;
@@ -136,21 +142,23 @@ class DwarfInfoHolder {
136142

137143
public:
138144
void insertDIE(const DINode *N, DIE *Die) {
139-
assert((!isa<DILabel>(N) && !isa<DILocalVariable>(N)) &&
145+
assert((!isa<DILabel>(N) && !isa<DILocalVariable>(N) &&
146+
!isa<DILocalScope>(N)) &&
140147
"Use getLabels().insertDIE() for labels or getLVs().insertDIE() for "
141-
"local variables");
148+
"local variables, or getSubprogram().insertDIE() for subprograms.");
142149
auto [_, Inserted] = MDNodeToDieMap.try_emplace(N, Die);
143-
assert((Inserted || isa<DISubprogram>(N) || isa<DIType>(N)) &&
150+
assert((Inserted || isa<DIType>(N)) &&
144151
"DIE for this DINode has already been added");
145152
}
146153

147154
void insertDIE(DIE *D) { MDNodeToDieMap.try_emplace(nullptr, D); }
148155

149156
DIE *getDIE(const DINode *N) const {
150157
DIE *D = MDNodeToDieMap.lookup(N);
151-
assert((!D || (!isa<DILabel>(N) && !isa<DILocalVariable>(N))) &&
158+
assert((!D || (!isa<DILabel>(N) && !isa<DILocalVariable>(N) &&
159+
!isa<DILocalScope>(N))) &&
152160
"Use getLabels().getDIE() for labels or getLVs().getDIE() for "
153-
"local variables");
161+
"local variables, or getLocalScopes().getDIE() for local scopes.");
154162
return D;
155163
}
156164

@@ -160,6 +168,9 @@ class DwarfInfoHolder {
160168
auto &getLabels() { return LabelHolder; }
161169
auto &getLabels() const { return LabelHolder; }
162170

171+
auto &getLocalScopes() { return LSHolder; }
172+
auto &getLocalScopes() const { return LSHolder; }
173+
163174
/// For a global variable, returns DIE of the variable.
164175
///
165176
/// For a local variable, returns abstract DIE of the variable.
@@ -171,10 +182,6 @@ class DwarfInfoHolder {
171182
return getDIE(V);
172183
}
173184

174-
DenseMap<const DILocalScope *, DIE *> &getAbstractScopeDIEs() {
175-
return AbstractLocalScopeDIEs;
176-
}
177-
178185
DenseMap<const DINode *, std::unique_ptr<DbgEntity>> &getAbstractEntities() {
179186
return AbstractEntities;
180187
}

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)