Skip to content

Commit 89aa335

Browse files
authored
[RemoveDIs][DebugInfo] Remove redundant DPVAssigns (#78574)
DPValues are already supported by most of the utilities that remove redundant debug info after certain passes; the exception to this is `removeUndefDbgAssignsFromEntryBlock`, which applies only to llvm.dbg.assigns which were previously unimplemented for DPValues. Now that DPVAssigns exist, we have to support removing redundant instances in the same way, which this patch implements.
1 parent 0fe20aa commit 89aa335

File tree

5 files changed

+76
-7
lines changed

5 files changed

+76
-7
lines changed

llvm/include/llvm/IR/DebugInfo.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,12 @@ inline AssignmentInstRange getAssignmentInsts(const DbgAssignIntrinsic *DAI) {
193193
return getAssignmentInsts(DAI->getAssignID());
194194
}
195195

196+
inline AssignmentInstRange getAssignmentInsts(const DPValue *DPV) {
197+
assert(DPV->isDbgAssign() &&
198+
"Can't get assignment instructions for non-assign DPV!");
199+
return getAssignmentInsts(DPV->getAssignID());
200+
}
201+
196202
//
197203
// Utilities for enumerating llvm.dbg.assign intrinsic from an assignment ID.
198204
//

llvm/lib/Transforms/Utils/BasicBlockUtils.cpp

Lines changed: 64 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -405,10 +405,17 @@ static bool DPValuesRemoveRedundantDbgInstrsUsingBackwardScan(BasicBlock *BB) {
405405
// If the same variable fragment is described more than once it is enough
406406
// to keep the last one (i.e. the first found since we for reverse
407407
// iteration).
408-
// FIXME: add assignment tracking support (see parallel implementation
409-
// below).
410-
if (!R.second)
411-
ToBeRemoved.push_back(&DPV);
408+
if (R.second)
409+
continue;
410+
411+
if (DPV.isDbgAssign()) {
412+
// Don't delete dbg.assign intrinsics that are linked to instructions.
413+
if (!at::getAssignmentInsts(&DPV).empty())
414+
continue;
415+
// Unlinked dbg.assign intrinsics can be treated like dbg.values.
416+
}
417+
418+
ToBeRemoved.push_back(&DPV);
412419
continue;
413420
}
414421
// Sequence with consecutive dbg.value instrs ended. Clear the map to
@@ -495,14 +502,25 @@ static bool DPValuesRemoveRedundantDbgInstrsUsingForwardScan(BasicBlock *BB) {
495502
DebugVariable Key(DPV.getVariable(), std::nullopt,
496503
DPV.getDebugLoc()->getInlinedAt());
497504
auto VMI = VariableMap.find(Key);
505+
// A dbg.assign with no linked instructions can be treated like a
506+
// dbg.value (i.e. can be deleted).
507+
bool IsDbgValueKind =
508+
(!DPV.isDbgAssign() || at::getAssignmentInsts(&DPV).empty());
509+
498510
// Update the map if we found a new value/expression describing the
499511
// variable, or if the variable wasn't mapped already.
500512
SmallVector<Value *, 4> Values(DPV.location_ops());
501513
if (VMI == VariableMap.end() || VMI->second.first != Values ||
502514
VMI->second.second != DPV.getExpression()) {
503-
VariableMap[Key] = {Values, DPV.getExpression()};
515+
if (IsDbgValueKind)
516+
VariableMap[Key] = {Values, DPV.getExpression()};
517+
else
518+
VariableMap[Key] = {Values, nullptr};
504519
continue;
505520
}
521+
// Don't delete dbg.assign intrinsics that are linked to instructions.
522+
if (!IsDbgValueKind)
523+
continue;
506524
// Found an identical mapping. Remember the instruction for later removal.
507525
ToBeRemoved.push_back(&DPV);
508526
}
@@ -514,6 +532,42 @@ static bool DPValuesRemoveRedundantDbgInstrsUsingForwardScan(BasicBlock *BB) {
514532
return !ToBeRemoved.empty();
515533
}
516534

535+
static bool DPValuesRemoveUndefDbgAssignsFromEntryBlock(BasicBlock *BB) {
536+
assert(BB->isEntryBlock() && "expected entry block");
537+
SmallVector<DPValue *, 8> ToBeRemoved;
538+
DenseSet<DebugVariable> SeenDefForAggregate;
539+
// Returns the DebugVariable for DVI with no fragment info.
540+
auto GetAggregateVariable = [](const DPValue &DPV) {
541+
return DebugVariable(DPV.getVariable(), std::nullopt,
542+
DPV.getDebugLoc().getInlinedAt());
543+
};
544+
545+
// Remove undef dbg.assign intrinsics that are encountered before
546+
// any non-undef intrinsics from the entry block.
547+
for (auto &I : *BB) {
548+
for (DPValue &DPV : I.getDbgValueRange()) {
549+
if (!DPV.isDbgValue() && !DPV.isDbgAssign())
550+
continue;
551+
bool IsDbgValueKind =
552+
(DPV.isDbgValue() || at::getAssignmentInsts(&DPV).empty());
553+
DebugVariable Aggregate = GetAggregateVariable(DPV);
554+
if (!SeenDefForAggregate.contains(Aggregate)) {
555+
bool IsKill = DPV.isKillLocation() && IsDbgValueKind;
556+
if (!IsKill) {
557+
SeenDefForAggregate.insert(Aggregate);
558+
} else if (DPV.isDbgAssign()) {
559+
ToBeRemoved.push_back(&DPV);
560+
}
561+
}
562+
}
563+
}
564+
565+
for (DPValue *DPV : ToBeRemoved)
566+
DPV->eraseFromParent();
567+
568+
return !ToBeRemoved.empty();
569+
}
570+
517571
static bool removeRedundantDbgInstrsUsingForwardScan(BasicBlock *BB) {
518572
if (BB->IsNewDbgInfoFormat)
519573
return DPValuesRemoveRedundantDbgInstrsUsingForwardScan(BB);
@@ -578,7 +632,10 @@ static bool removeRedundantDbgInstrsUsingForwardScan(BasicBlock *BB) {
578632
/// then (only) the instruction marked with (*) can be removed.
579633
/// Possible improvements:
580634
/// - Keep track of non-overlapping fragments.
581-
static bool remomveUndefDbgAssignsFromEntryBlock(BasicBlock *BB) {
635+
static bool removeUndefDbgAssignsFromEntryBlock(BasicBlock *BB) {
636+
if (BB->IsNewDbgInfoFormat)
637+
return DPValuesRemoveUndefDbgAssignsFromEntryBlock(BB);
638+
582639
assert(BB->isEntryBlock() && "expected entry block");
583640
SmallVector<DbgAssignIntrinsic *, 8> ToBeRemoved;
584641
DenseSet<DebugVariable> SeenDefForAggregate;
@@ -629,7 +686,7 @@ bool llvm::RemoveRedundantDbgInstrs(BasicBlock *BB) {
629686
MadeChanges |= removeRedundantDbgInstrsUsingBackwardScan(BB);
630687
if (BB->isEntryBlock() &&
631688
isAssignmentTrackingEnabled(*BB->getParent()->getParent()))
632-
MadeChanges |= remomveUndefDbgAssignsFromEntryBlock(BB);
689+
MadeChanges |= removeUndefDbgAssignsFromEntryBlock(BB);
633690
MadeChanges |= removeRedundantDbgInstrsUsingForwardScan(BB);
634691

635692
if (MadeChanges)

llvm/test/DebugInfo/Generic/assignment-tracking/instcombine/remove-redundant-dbg.ll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
; RUN: opt -passes=sroa -S %s -o - \
22
; RUN: | FileCheck %s --implicit-check-not="call void @llvm.dbg"
3+
; RUN: opt --try-experimental-debuginfo-iterators -passes=sroa -S %s -o - \
4+
; RUN: | FileCheck %s --implicit-check-not="call void @llvm.dbg"
35

46
;; Check that sroa removes redundant debug intrinsics after it makes a
57
;; change. This has a significant positive impact on peak memory and compiler

llvm/test/DebugInfo/Generic/assignment-tracking/remove-redundant.ll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
; RUN: opt -passes=redundant-dbg-inst-elim -S %s -o - \
22
; RUN: | FileCheck %s --implicit-check-not="call void @llvm.dbg"
3+
; RUN: opt --try-experimental-debuginfo-iterators -passes=redundant-dbg-inst-elim -S %s -o - \
4+
; RUN: | FileCheck %s --implicit-check-not="call void @llvm.dbg"
35

46
;; Hand-written. Test how RemoveRedundantDbgInstrs interacts with dbg.assign
57
;; intrinsics. FileCehck directives are inline.

llvm/test/DebugInfo/Generic/assignment-tracking/sroa/remove-redundant-dbg.ll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
; RUN: opt -passes=sroa -S %s -o - \
22
; RUN: | FileCheck %s --implicit-check-not="call void @llvm.dbg"
3+
; RUN: opt --try-experimental-debuginfo-iterators -passes=sroa -S %s -o - \
4+
; RUN: | FileCheck %s --implicit-check-not="call void @llvm.dbg"
35

46
;; Check that sroa removes redundant debug intrinsics after it makes a
57
;; change. This has a significant positive impact on peak memory and compiler

0 commit comments

Comments
 (0)