Skip to content

Commit 4418434

Browse files
chbessonovadzhidzhoev
authored andcommitted
[DebugMetadata] Simplify handling subprogram's retainedNodes field. NFCI (1/7)
RFC https://discourse.llvm.org/t/rfc-dwarfdebug-fix-and-improve-handling-imported-entities-types-and-static-local-in-subprogram-and-lexical-block-scopes/68544 Currently, `retainedNodes` tracks function-local variables and labels. To support function-local import, types and static variables (which are globals in LLVM IR), subsequent patches use the same field. So this patch makes preliminary refactoring of the code tracking local entities to apply future functional changes lucidly and cleanly. No functional changes intended. Differential Revision: https://reviews.llvm.org/D143984
1 parent 6bcfab3 commit 4418434

File tree

8 files changed

+52
-65
lines changed

8 files changed

+52
-65
lines changed

clang/test/CodeGen/attr-btf_tag-disubprogram-callsite.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ int foo2(struct t1 *arg) {
1313
return foo(arg);
1414
}
1515

16-
// CHECK: ![[#]] = !DISubprogram(name: "foo", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[#]], flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: ![[#]], annotations: ![[ANNOT:[0-9]+]])
16+
// CHECK: ![[#]] = !DISubprogram(name: "foo", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[#]], flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, annotations: ![[ANNOT:[0-9]+]])
1717
// CHECK: ![[ANNOT]] = !{![[TAG1:[0-9]+]], ![[TAG2:[0-9]+]]}
1818
// CHECK: ![[TAG1]] = !{!"btf_decl_tag", !"tag1"}
1919
// CHECK: ![[TAG2]] = !{!"btf_decl_tag", !"tag2"}

clang/test/CodeGenCXX/aix-static-init-debug-info.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,15 @@ X v;
5252
// CHECK: ret void
5353
// CHECK: }
5454

55-
// CHECK: ![[DBGVAR16]] = distinct !DISubprogram(name: "__cxx_global_var_init", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, type: !{{[0-9]+}}, flags: DIFlagArtificial, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !{{[0-9]+}}, retainedNodes: !{{[0-9]+}})
55+
// CHECK: ![[DBGVAR16]] = distinct !DISubprogram(name: "__cxx_global_var_init", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, type: !{{[0-9]+}}, flags: DIFlagArtificial, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !{{[0-9]+}})
5656
// CHECK: ![[DBGVAR19]] = !DILocation(line: 14, column: 3, scope: ![[DBGVAR16]])
5757
// CHECK: ![[DBGVAR19b]] = !DILocation(line: 0, scope: ![[DBGVAR16]])
58-
// CHECK: ![[DBGVAR20]] = distinct !DISubprogram(name: "__dtor_v", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: 14, type: !{{[0-9]+}}, scopeLine: 14, flags: DIFlagArtificial, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !{{[0-9]+}}, retainedNodes: !{{[0-9]+}})
58+
// CHECK: ![[DBGVAR20]] = distinct !DISubprogram(name: "__dtor_v", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: 14, type: !{{[0-9]+}}, scopeLine: 14, flags: DIFlagArtificial, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !{{[0-9]+}})
5959
// CHECK: ![[DBGVAR21b]] = !DILocation(line: 0, scope: ![[DBGVAR20]])
6060
// CHECK: ![[DBGVAR21]] = !DILocation(line: 14, column: 3, scope: ![[DBGVAR20]])
61-
// CHECK: ![[DBGVAR22]] = distinct !DISubprogram(linkageName: "__finalize_v", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: 14, type: !{{[0-9]+}}, scopeLine: 14, flags: DIFlagArtificial, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !{{[0-9]+}}, retainedNodes: !{{[0-9]+}})
61+
// CHECK: ![[DBGVAR22]] = distinct !DISubprogram(linkageName: "__finalize_v", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: 14, type: !{{[0-9]+}}, scopeLine: 14, flags: DIFlagArtificial, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !{{[0-9]+}})
6262
// CHECK: ![[DBGVAR24]] = !DILocation(line: 14, column: 3, scope: ![[DBGVAR22]])
63-
// CHECK: ![[DBGVAR25]] = distinct !DISubprogram(linkageName: "_GLOBAL__sub_I__", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, type: !{{[0-9]+}}, flags: DIFlagArtificial, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !{{[0-9]+}}, retainedNodes: !{{[0-9]+}})
63+
// CHECK: ![[DBGVAR25]] = distinct !DISubprogram(linkageName: "_GLOBAL__sub_I__", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, type: !{{[0-9]+}}, flags: DIFlagArtificial, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !{{[0-9]+}})
6464
// CHECK: ![[DBGVAR26]] = !DILocation(line: 0, scope: ![[DBGVAR25]])
65-
// CHECK: ![[DBGVAR27]] = distinct !DISubprogram(linkageName: "_GLOBAL__D_a", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, type: !{{[0-9]+}}, flags: DIFlagArtificial, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !{{[0-9]+}}, retainedNodes: !{{[0-9]+}})
65+
// CHECK: ![[DBGVAR27]] = distinct !DISubprogram(linkageName: "_GLOBAL__D_a", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, type: !{{[0-9]+}}, flags: DIFlagArtificial, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !{{[0-9]+}})
6666
// CHECK: ![[DBGVAR28]] = !DILocation(line: 0, scope: ![[DBGVAR27]])

clang/test/CodeGenCXX/debug-info-cxx1y.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
// CHECK: [[TYPE_LIST]] = !{[[INT:![0-9]*]]}
1212
// CHECK: [[INT]] = !DIBasicType(name: "int"
1313

14-
// CHECK: [[EMPTY:![0-9]*]] = !{}
1514
// CHECK: [[FOO:![0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "foo",
16-
// CHECK-SAME: elements: [[EMPTY]]
15+
// CHECK-SAME: elements: [[EMPTY:![0-9]*]]
16+
// CHECK: [[EMPTY]] = !{}
1717

1818
// FIXME: The context of this definition should be the CU/file scope, not the class.
1919
// CHECK: !DISubprogram(name: "func", {{.*}} scope: [[FOO]]

clang/test/CodeGenCXX/debug-info-template.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ template<typename T1, typename T2, typename T3, typename T4>
222222
void f1() { }
223223
template void f1<t1 () volatile, t1 () const volatile, t1 () &, t1 () &&>();
224224
// CHECK: !DISubprogram(name: "f1<RawFuncQual::t1 () volatile, RawFuncQual::t1 () const volatile, RawFuncQual::t1 () &, RawFuncQual::t1 () &&>",
225-
// CHECK-SAME: templateParams: ![[RAW_FUNC_QUAL_ARGS:[0-9]*]],
225+
// CHECK-SAME: templateParams: ![[RAW_FUNC_QUAL_ARGS:[0-9]*]]
226226

227227
// CHECK: ![[RAW_FUNC_QUAL_ARGS]] = !{![[RAW_FUNC_QUAL_T1:[0-9]*]], ![[RAW_FUNC_QUAL_T2:[0-9]*]], ![[RAW_FUNC_QUAL_T3:[0-9]*]], ![[RAW_FUNC_QUAL_T4:[0-9]*]]}
228228
// CHECK: ![[RAW_FUNC_QUAL_T1]] = !DITemplateTypeParameter(name: "T1", type: ![[RAW_FUNC_QUAL_VOL:[0-9]*]])
@@ -254,7 +254,7 @@ inline namespace inl {
254254
template<template<typename> class> void f1() { }
255255
template void f1<t1>();
256256
// CHECK: !DISubprogram(name: "f1<TemplateTemplateParamInlineNamespace::inl::t1>",
257-
// CHECK-SAME: templateParams: ![[TEMP_TEMP_INL_ARGS:[0-9]*]],
257+
// CHECK-SAME: templateParams: ![[TEMP_TEMP_INL_ARGS:[0-9]*]]
258258
// CHECK: ![[TEMP_TEMP_INL_ARGS]] = !{![[TEMP_TEMP_INL_ARGS_T:[0-9]*]]}
259259
// CHECK: ![[TEMP_TEMP_INL_ARGS_T]] = !DITemplateValueParameter(tag: DW_TAG_GNU_template_template_param, value: !"TemplateTemplateParamInlineNamespace::inl::t1")
260260
} // namespace TemplateTemplateParamInlineNamespace

clang/test/CodeGenObjC/debug-info-category.m

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,10 @@ - (id)add:(Foo *)addend {
3737
// CHECK: ![[STRUCT:.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Foo"
3838

3939
// Verify "not a definition" by showing spFlags doesn't have DISPFlagDefinition.
40-
// DWARF5: !DISubprogram(name: "-[Foo integer]", scope: ![[STRUCT]], {{.*}} spFlags: DISPFlagLocalToUnit,
41-
// DWARF5: !DISubprogram(name: "-[Foo integer:]", scope: ![[STRUCT]], {{.*}} spFlags: DISPFlagLocalToUnit,
42-
// DWARF5: !DISubprogram(name: "+[Foo(Bar) zero:]", scope: ![[STRUCT]], {{.*}} spFlags: DISPFlagLocalToUnit,
43-
// DWARF5: !DISubprogram(name: "-[Foo(Bar) add:]", scope: ![[STRUCT]], {{.*}} spFlags: DISPFlagLocalToUnit,
40+
// DWARF5: !DISubprogram(name: "-[Foo integer]", scope: ![[STRUCT]], {{.*}} spFlags: DISPFlagLocalToUnit)
41+
// DWARF5: !DISubprogram(name: "-[Foo integer:]", scope: ![[STRUCT]], {{.*}} spFlags: DISPFlagLocalToUnit)
42+
// DWARF5: !DISubprogram(name: "+[Foo(Bar) zero:]", scope: ![[STRUCT]], {{.*}} spFlags: DISPFlagLocalToUnit)
43+
// DWARF5: !DISubprogram(name: "-[Foo(Bar) add:]", scope: ![[STRUCT]], {{.*}} spFlags: DISPFlagLocalToUnit)
4444

4545
// DWARF4-NOT: !DISubprogram(name: "-[Foo integer]", scope: ![[STRUCT]], {{.*}} spFlags: DISPFlagLocalToUnit,
4646
// DWARF4-NOT: !DISubprogram(name: "-[Foo integer:]", scope: ![[STRUCT]], {{.*}} spFlags: DISPFlagLocalToUnit,

llvm/include/llvm/IR/DIBuilder.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,15 +64,18 @@ namespace llvm {
6464
SmallVector<TrackingMDNodeRef, 4> UnresolvedNodes;
6565
bool AllowUnresolvedNodes;
6666

67-
/// Each subprogram's preserved local variables.
67+
/// Each subprogram's preserved local variables and labels.
6868
///
6969
/// Do not use a std::vector. Some versions of libc++ apparently copy
7070
/// instead of move on grow operations, and TrackingMDRef is expensive to
7171
/// copy.
72-
DenseMap<MDNode *, SmallVector<TrackingMDNodeRef, 1>> PreservedVariables;
72+
DenseMap<DISubprogram *, SmallVector<TrackingMDNodeRef, 4>>
73+
SubprogramTrackedNodes;
7374

74-
/// Each subprogram's preserved labels.
75-
DenseMap<MDNode *, SmallVector<TrackingMDNodeRef, 1>> PreservedLabels;
75+
SmallVectorImpl<TrackingMDNodeRef> &
76+
getSubprogramNodesTrackingVector(const DIScope *S) {
77+
return SubprogramTrackedNodes[cast<DILocalScope>(S)->getSubprogram()];
78+
}
7679

7780
/// Create a temporary.
7881
///

llvm/include/llvm/IR/DebugInfoMetadata.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1856,6 +1856,9 @@ class DISubprogram : public DILocalScope {
18561856
void replaceRawLinkageName(MDString *LinkageName) {
18571857
replaceOperandWith(3, LinkageName);
18581858
}
1859+
void replaceRetainedNodes(DINodeArray N) {
1860+
replaceOperandWith(7, N.get());
1861+
}
18591862

18601863
/// Check if this subprogram describes the given function.
18611864
///

llvm/lib/IR/DIBuilder.cpp

Lines changed: 28 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -52,23 +52,11 @@ void DIBuilder::trackIfUnresolved(MDNode *N) {
5252
}
5353

5454
void DIBuilder::finalizeSubprogram(DISubprogram *SP) {
55-
MDTuple *Temp = SP->getRetainedNodes().get();
56-
if (!Temp || !Temp->isTemporary())
57-
return;
58-
59-
SmallVector<Metadata *, 16> RetainedNodes;
60-
61-
auto PV = PreservedVariables.find(SP);
62-
if (PV != PreservedVariables.end())
63-
RetainedNodes.append(PV->second.begin(), PV->second.end());
64-
65-
auto PL = PreservedLabels.find(SP);
66-
if (PL != PreservedLabels.end())
67-
RetainedNodes.append(PL->second.begin(), PL->second.end());
68-
69-
DINodeArray Node = getOrCreateArray(RetainedNodes);
70-
71-
TempMDTuple(Temp)->replaceAllUsesWith(Node.get());
55+
auto PN = SubprogramTrackedNodes.find(SP);
56+
if (PN != SubprogramTrackedNodes.end())
57+
SP->replaceRetainedNodes(
58+
MDTuple::get(VMContext, SmallVector<Metadata *, 16>(PN->second.begin(),
59+
PN->second.end())));
7260
}
7361

7462
void DIBuilder::finalize() {
@@ -766,26 +754,20 @@ DIGlobalVariable *DIBuilder::createTempGlobalVariableFwdDecl(
766754

767755
static DILocalVariable *createLocalVariable(
768756
LLVMContext &VMContext,
769-
DenseMap<MDNode *, SmallVector<TrackingMDNodeRef, 1>> &PreservedVariables,
770-
DIScope *Scope, StringRef Name, unsigned ArgNo, DIFile *File,
757+
SmallVectorImpl<TrackingMDNodeRef> &PreservedNodes,
758+
DIScope *Context, StringRef Name, unsigned ArgNo, DIFile *File,
771759
unsigned LineNo, DIType *Ty, bool AlwaysPreserve, DINode::DIFlags Flags,
772760
uint32_t AlignInBits, DINodeArray Annotations = nullptr) {
773-
// FIXME: Why getNonCompileUnitScope()?
774-
// FIXME: Why is "!Context" okay here?
775761
// FIXME: Why doesn't this check for a subprogram or lexical block (AFAICT
776762
// the only valid scopes)?
777-
DIScope *Context = getNonCompileUnitScope(Scope);
778-
779-
auto *Node = DILocalVariable::get(
780-
VMContext, cast_or_null<DILocalScope>(Context), Name, File, LineNo, Ty,
781-
ArgNo, Flags, AlignInBits, Annotations);
763+
auto *Scope = cast<DILocalScope>(Context);
764+
auto *Node = DILocalVariable::get(VMContext, Scope, Name, File, LineNo, Ty,
765+
ArgNo, Flags, AlignInBits, Annotations);
782766
if (AlwaysPreserve) {
783767
// The optimizer may remove local variables. If there is an interest
784768
// to preserve variable info in such situation then stash it in a
785769
// named mdnode.
786-
DISubprogram *Fn = getDISubprogram(Scope);
787-
assert(Fn && "Missing subprogram for local variable");
788-
PreservedVariables[Fn].emplace_back(Node);
770+
PreservedNodes.emplace_back(Node);
789771
}
790772
return Node;
791773
}
@@ -795,35 +777,35 @@ DILocalVariable *DIBuilder::createAutoVariable(DIScope *Scope, StringRef Name,
795777
DIType *Ty, bool AlwaysPreserve,
796778
DINode::DIFlags Flags,
797779
uint32_t AlignInBits) {
798-
return createLocalVariable(VMContext, PreservedVariables, Scope, Name,
799-
/* ArgNo */ 0, File, LineNo, Ty, AlwaysPreserve,
800-
Flags, AlignInBits);
780+
assert(Scope && isa<DILocalScope>(Scope) &&
781+
"Unexpected scope for a local variable.");
782+
return createLocalVariable(
783+
VMContext, getSubprogramNodesTrackingVector(Scope), Scope, Name,
784+
/* ArgNo */ 0, File, LineNo, Ty, AlwaysPreserve, Flags, AlignInBits);
801785
}
802786

803787
DILocalVariable *DIBuilder::createParameterVariable(
804788
DIScope *Scope, StringRef Name, unsigned ArgNo, DIFile *File,
805789
unsigned LineNo, DIType *Ty, bool AlwaysPreserve, DINode::DIFlags Flags,
806790
DINodeArray Annotations) {
807791
assert(ArgNo && "Expected non-zero argument number for parameter");
808-
return createLocalVariable(VMContext, PreservedVariables, Scope, Name, ArgNo,
809-
File, LineNo, Ty, AlwaysPreserve, Flags,
810-
/*AlignInBits=*/0, Annotations);
792+
assert(Scope && isa<DILocalScope>(Scope) &&
793+
"Unexpected scope for a local variable.");
794+
return createLocalVariable(
795+
VMContext, getSubprogramNodesTrackingVector(Scope), Scope, Name, ArgNo,
796+
File, LineNo, Ty, AlwaysPreserve, Flags, /*AlignInBits=*/0, Annotations);
811797
}
812798

813-
DILabel *DIBuilder::createLabel(DIScope *Scope, StringRef Name, DIFile *File,
814-
unsigned LineNo, bool AlwaysPreserve) {
815-
DIScope *Context = getNonCompileUnitScope(Scope);
816-
817-
auto *Node = DILabel::get(VMContext, cast_or_null<DILocalScope>(Context),
818-
Name, File, LineNo);
799+
DILabel *DIBuilder::createLabel(DIScope *Context, StringRef Name, DIFile *File,
800+
unsigned LineNo, bool AlwaysPreserve) {
801+
auto *Scope = cast<DILocalScope>(Context);
802+
auto *Node = DILabel::get(VMContext, Scope, Name, File, LineNo);
819803

820804
if (AlwaysPreserve) {
821805
/// The optimizer may remove labels. If there is an interest
822806
/// to preserve label info in such situation then append it to
823807
/// the list of retained nodes of the DISubprogram.
824-
DISubprogram *Fn = getDISubprogram(Scope);
825-
assert(Fn && "Missing subprogram for label");
826-
PreservedLabels[Fn].emplace_back(Node);
808+
getSubprogramNodesTrackingVector(Scope).emplace_back(Node);
827809
}
828810
return Node;
829811
}
@@ -850,9 +832,8 @@ DISubprogram *DIBuilder::createFunction(
850832
auto *Node = getSubprogram(
851833
/*IsDistinct=*/IsDefinition, VMContext, getNonCompileUnitScope(Context),
852834
Name, LinkageName, File, LineNo, Ty, ScopeLine, nullptr, 0, 0, Flags,
853-
SPFlags, IsDefinition ? CUNode : nullptr, TParams, Decl,
854-
MDTuple::getTemporary(VMContext, std::nullopt).release(), ThrownTypes,
855-
Annotations, TargetFuncName);
835+
SPFlags, IsDefinition ? CUNode : nullptr, TParams, Decl, nullptr,
836+
ThrownTypes, Annotations, TargetFuncName);
856837

857838
if (IsDefinition)
858839
AllSubprograms.push_back(Node);

0 commit comments

Comments
 (0)