Skip to content

Commit ea60ffc

Browse files
committed
[NFC] Return unique dbg intrinsics from findDbgValues and findDbgUsers
The out-param vector from findDbgValues and findDbgUsers should not include duplicates, which is possible if the debug intrinsic uses the value multiple times. This filter is already in place for multiple uses in a `DIArgLists`; extend it to cover dbg.assigns too because a Value may be used in both the address and value components. Additionally, refactor the duplicated functionality between findDbgValues and FindDbgUsers into a new function findDbgIntrinsics. Reviewed By: jmorse, StephenTozer Differential Revision: https://reviews.llvm.org/D148788
1 parent 029120c commit ea60ffc

File tree

2 files changed

+79
-37
lines changed

2 files changed

+79
-37
lines changed

llvm/lib/IR/DebugInfo.cpp

Lines changed: 25 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -64,57 +64,45 @@ TinyPtrVector<DbgDeclareInst *> llvm::FindDbgDeclareUses(Value *V) {
6464
return Declares;
6565
}
6666

67-
void llvm::findDbgValues(SmallVectorImpl<DbgValueInst *> &DbgValues, Value *V) {
67+
template <typename IntrinsicT>
68+
static void findDbgIntrinsics(SmallVectorImpl<IntrinsicT *> &Result, Value *V) {
6869
// This function is hot. Check whether the value has any metadata to avoid a
6970
// DenseMap lookup.
7071
if (!V->isUsedByMetadata())
7172
return;
73+
74+
LLVMContext &Ctx = V->getContext();
7275
// TODO: If this value appears multiple times in a DIArgList, we should still
7376
// only add the owning DbgValueInst once; use this set to track ArgListUsers.
7477
// This behaviour can be removed when we can automatically remove duplicates.
75-
SmallPtrSet<DbgValueInst *, 4> EncounteredDbgValues;
76-
if (auto *L = LocalAsMetadata::getIfExists(V)) {
77-
if (auto *MDV = MetadataAsValue::getIfExists(V->getContext(), L)) {
78+
// V will also appear twice in a dbg.assign if its used in the both the value
79+
// and address components.
80+
SmallPtrSet<IntrinsicT *, 4> EncounteredIntrinsics;
81+
82+
/// Append IntrinsicT users of MetadataAsValue(MD).
83+
auto AppendUsers = [&Ctx, &EncounteredIntrinsics, &Result](Metadata *MD) {
84+
if (auto *MDV = MetadataAsValue::getIfExists(Ctx, MD)) {
7885
for (User *U : MDV->users())
79-
if (DbgValueInst *DVI = dyn_cast<DbgValueInst>(U))
80-
DbgValues.push_back(DVI);
81-
}
82-
for (Metadata *AL : L->getAllArgListUsers()) {
83-
if (auto *MDV = MetadataAsValue::getIfExists(V->getContext(), AL)) {
84-
for (User *U : MDV->users())
85-
if (DbgValueInst *DVI = dyn_cast<DbgValueInst>(U))
86-
if (EncounteredDbgValues.insert(DVI).second)
87-
DbgValues.push_back(DVI);
88-
}
86+
if (IntrinsicT *DVI = dyn_cast<IntrinsicT>(U))
87+
if (EncounteredIntrinsics.insert(DVI).second)
88+
Result.push_back(DVI);
8989
}
90+
};
91+
92+
if (auto *L = LocalAsMetadata::getIfExists(V)) {
93+
AppendUsers(L);
94+
for (Metadata *AL : L->getAllArgListUsers())
95+
AppendUsers(AL);
9096
}
9197
}
9298

99+
void llvm::findDbgValues(SmallVectorImpl<DbgValueInst *> &DbgValues, Value *V) {
100+
findDbgIntrinsics<DbgValueInst>(DbgValues, V);
101+
}
102+
93103
void llvm::findDbgUsers(SmallVectorImpl<DbgVariableIntrinsic *> &DbgUsers,
94104
Value *V) {
95-
// This function is hot. Check whether the value has any metadata to avoid a
96-
// DenseMap lookup.
97-
if (!V->isUsedByMetadata())
98-
return;
99-
// TODO: If this value appears multiple times in a DIArgList, we should still
100-
// only add the owning DbgValueInst once; use this set to track ArgListUsers.
101-
// This behaviour can be removed when we can automatically remove duplicates.
102-
SmallPtrSet<DbgVariableIntrinsic *, 4> EncounteredDbgValues;
103-
if (auto *L = LocalAsMetadata::getIfExists(V)) {
104-
if (auto *MDV = MetadataAsValue::getIfExists(V->getContext(), L)) {
105-
for (User *U : MDV->users())
106-
if (DbgVariableIntrinsic *DII = dyn_cast<DbgVariableIntrinsic>(U))
107-
DbgUsers.push_back(DII);
108-
}
109-
for (Metadata *AL : L->getAllArgListUsers()) {
110-
if (auto *MDV = MetadataAsValue::getIfExists(V->getContext(), AL)) {
111-
for (User *U : MDV->users())
112-
if (DbgVariableIntrinsic *DII = dyn_cast<DbgVariableIntrinsic>(U))
113-
if (EncounteredDbgValues.insert(DII).second)
114-
DbgUsers.push_back(DII);
115-
}
116-
}
117-
}
105+
findDbgIntrinsics<DbgVariableIntrinsic>(DbgUsers, V);
118106
}
119107

120108
DISubprogram *llvm::getDISubprogram(const MDNode *Scope) {

llvm/unittests/Transforms/Utils/LocalTest.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,60 @@ TEST(Local, ChangeToUnreachable) {
651651
EXPECT_EQ(DLA, DLB);
652652
}
653653

654+
TEST(Local, FindDbgUsers) {
655+
LLVMContext Ctx;
656+
std::unique_ptr<Module> M = parseIR(Ctx,
657+
R"(
658+
define dso_local void @fun(ptr %a) #0 !dbg !11 {
659+
entry:
660+
call void @llvm.dbg.assign(metadata ptr %a, metadata !16, metadata !DIExpression(), metadata !15, metadata ptr %a, metadata !DIExpression()), !dbg !19
661+
ret void
662+
}
663+
664+
declare void @llvm.dbg.assign(metadata, metadata, metadata, metadata, metadata, metadata)
665+
666+
!llvm.dbg.cu = !{!0}
667+
!llvm.module.flags = !{!2, !3, !9}
668+
!llvm.ident = !{!10}
669+
670+
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 17.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
671+
!1 = !DIFile(filename: "test.cpp", directory: "/")
672+
!2 = !{i32 7, !"Dwarf Version", i32 5}
673+
!3 = !{i32 2, !"Debug Info Version", i32 3}
674+
!4 = !{i32 1, !"wchar_size", i32 4}
675+
!9 = !{i32 7, !"debug-info-assignment-tracking", i1 true}
676+
!10 = !{!"clang version 17.0.0"}
677+
!11 = distinct !DISubprogram(name: "fun", linkageName: "fun", scope: !1, file: !1, line: 1, type: !12, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !14)
678+
!12 = !DISubroutineType(types: !13)
679+
!13 = !{null}
680+
!14 = !{}
681+
!15 = distinct !DIAssignID()
682+
!16 = !DILocalVariable(name: "x", scope: !11, file: !1, line: 2, type: !17)
683+
!17 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !18, size: 64)
684+
!18 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
685+
!19 = !DILocation(line: 0, scope: !11)
686+
)");
687+
688+
bool BrokenDebugInfo = true;
689+
verifyModule(*M, &errs(), &BrokenDebugInfo);
690+
ASSERT_FALSE(BrokenDebugInfo);
691+
692+
Function &Fun = *cast<Function>(M->getNamedValue("fun"));
693+
Value *Arg = Fun.getArg(0);
694+
695+
SmallVector<DbgVariableIntrinsic *> Users;
696+
// Arg (%a) is used twice by a single dbg.assign. Check findDbgUsers returns
697+
// only 1 pointer to it rather than 2.
698+
findDbgUsers(Users, Arg);
699+
EXPECT_EQ(Users.size(), 1u);
700+
701+
SmallVector<DbgValueInst *> Vals;
702+
// Arg (%a) is used twice by a single dbg.assign. Check findDbgValues returns
703+
// only 1 pointer to it rather than 2.
704+
findDbgValues(Vals, Arg);
705+
EXPECT_EQ(Vals.size(), 1u);
706+
}
707+
654708
TEST(Local, ReplaceAllDbgUsesWith) {
655709
using namespace llvm::dwarf;
656710

0 commit comments

Comments
 (0)