Skip to content

Commit 30845e8

Browse files
authored
[RemoveDIs][DebugInfo] Handle DPVAssigns in Assignment Tracking excluding lowering (#78982)
This patch adds support for DPVAssigns across all of AssignmentTrackingAnalysis except for AssignmentTrackingLowering, which is implemented in a separate patch. This patch includes handling DPValues in MemLocFragFill, the removal of redundant DPValues as part of AssignmentTrackingAnalysis (which is different to the version in `BasicBlockUtils.cpp`), and preventing the DPVAssigns from being directly emitted in SelectionDAG (just as we don't emit llvm.dbg.assigns directly, but receive a set of locations from AssignmentTrackingAnalysis' output).
1 parent 818f13f commit 30845e8

38 files changed

+338
-127
lines changed

llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp

Lines changed: 153 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -829,6 +829,13 @@ class MemLocFragmentFill {
829829
void process(BasicBlock &BB, VarFragMap &LiveSet) {
830830
BBInsertBeforeMap[&BB].clear();
831831
for (auto &I : BB) {
832+
for (auto &DPV : I.getDbgValueRange()) {
833+
if (const auto *Locs = FnVarLocs->getWedge(&DPV)) {
834+
for (const VarLocInfo &Loc : *Locs) {
835+
addDef(Loc, &DPV, *I.getParent(), LiveSet);
836+
}
837+
}
838+
}
832839
if (const auto *Locs = FnVarLocs->getWedge(&I)) {
833840
for (const VarLocInfo &Loc : *Locs) {
834841
addDef(Loc, &I, *I.getParent(), LiveSet);
@@ -2487,73 +2494,78 @@ removeRedundantDbgLocsUsingBackwardScan(const BasicBlock *BB,
24872494
VariableDefinedBytes.clear();
24882495
}
24892496

2490-
// Get the location defs that start just before this instruction.
2491-
const auto *Locs = FnVarLocs.getWedge(&I);
2492-
if (!Locs)
2493-
continue;
2497+
auto HandleLocsForWedge = [&](auto *WedgePosition) {
2498+
// Get the location defs that start just before this instruction.
2499+
const auto *Locs = FnVarLocs.getWedge(WedgePosition);
2500+
if (!Locs)
2501+
return;
2502+
2503+
NumWedgesScanned++;
2504+
bool ChangedThisWedge = false;
2505+
// The new pruned set of defs, reversed because we're scanning backwards.
2506+
SmallVector<VarLocInfo> NewDefsReversed;
2507+
2508+
// Iterate over the existing defs in reverse.
2509+
for (auto RIt = Locs->rbegin(), REnd = Locs->rend(); RIt != REnd; ++RIt) {
2510+
NumDefsScanned++;
2511+
DebugAggregate Aggr =
2512+
getAggregate(FnVarLocs.getVariable(RIt->VariableID));
2513+
uint64_t SizeInBits = Aggr.first->getSizeInBits().value_or(0);
2514+
uint64_t SizeInBytes = divideCeil(SizeInBits, 8);
2515+
2516+
// Cutoff for large variables to prevent expensive bitvector operations.
2517+
const uint64_t MaxSizeBytes = 2048;
2518+
2519+
if (SizeInBytes == 0 || SizeInBytes > MaxSizeBytes) {
2520+
// If the size is unknown (0) then keep this location def to be safe.
2521+
// Do the same for defs of large variables, which would be expensive
2522+
// to represent with a BitVector.
2523+
NewDefsReversed.push_back(*RIt);
2524+
continue;
2525+
}
24942526

2495-
NumWedgesScanned++;
2496-
bool ChangedThisWedge = false;
2497-
// The new pruned set of defs, reversed because we're scanning backwards.
2498-
SmallVector<VarLocInfo> NewDefsReversed;
2499-
2500-
// Iterate over the existing defs in reverse.
2501-
for (auto RIt = Locs->rbegin(), REnd = Locs->rend(); RIt != REnd; ++RIt) {
2502-
NumDefsScanned++;
2503-
DebugAggregate Aggr =
2504-
getAggregate(FnVarLocs.getVariable(RIt->VariableID));
2505-
uint64_t SizeInBits = Aggr.first->getSizeInBits().value_or(0);
2506-
uint64_t SizeInBytes = divideCeil(SizeInBits, 8);
2507-
2508-
// Cutoff for large variables to prevent expensive bitvector operations.
2509-
const uint64_t MaxSizeBytes = 2048;
2510-
2511-
if (SizeInBytes == 0 || SizeInBytes > MaxSizeBytes) {
2512-
// If the size is unknown (0) then keep this location def to be safe.
2513-
// Do the same for defs of large variables, which would be expensive
2514-
// to represent with a BitVector.
2515-
NewDefsReversed.push_back(*RIt);
2516-
continue;
2517-
}
2527+
// Only keep this location definition if it is not fully eclipsed by
2528+
// other definitions in this wedge that come after it
2529+
2530+
// Inert the bytes the location definition defines.
2531+
auto InsertResult =
2532+
VariableDefinedBytes.try_emplace(Aggr, BitVector(SizeInBytes));
2533+
bool FirstDefinition = InsertResult.second;
2534+
BitVector &DefinedBytes = InsertResult.first->second;
2535+
2536+
DIExpression::FragmentInfo Fragment =
2537+
RIt->Expr->getFragmentInfo().value_or(
2538+
DIExpression::FragmentInfo(SizeInBits, 0));
2539+
bool InvalidFragment = Fragment.endInBits() > SizeInBits;
2540+
uint64_t StartInBytes = Fragment.startInBits() / 8;
2541+
uint64_t EndInBytes = divideCeil(Fragment.endInBits(), 8);
2542+
2543+
// If this defines any previously undefined bytes, keep it.
2544+
if (FirstDefinition || InvalidFragment ||
2545+
DefinedBytes.find_first_unset_in(StartInBytes, EndInBytes) != -1) {
2546+
if (!InvalidFragment)
2547+
DefinedBytes.set(StartInBytes, EndInBytes);
2548+
NewDefsReversed.push_back(*RIt);
2549+
continue;
2550+
}
25182551

2519-
// Only keep this location definition if it is not fully eclipsed by
2520-
// other definitions in this wedge that come after it
2521-
2522-
// Inert the bytes the location definition defines.
2523-
auto InsertResult =
2524-
VariableDefinedBytes.try_emplace(Aggr, BitVector(SizeInBytes));
2525-
bool FirstDefinition = InsertResult.second;
2526-
BitVector &DefinedBytes = InsertResult.first->second;
2527-
2528-
DIExpression::FragmentInfo Fragment =
2529-
RIt->Expr->getFragmentInfo().value_or(
2530-
DIExpression::FragmentInfo(SizeInBits, 0));
2531-
bool InvalidFragment = Fragment.endInBits() > SizeInBits;
2532-
uint64_t StartInBytes = Fragment.startInBits() / 8;
2533-
uint64_t EndInBytes = divideCeil(Fragment.endInBits(), 8);
2534-
2535-
// If this defines any previously undefined bytes, keep it.
2536-
if (FirstDefinition || InvalidFragment ||
2537-
DefinedBytes.find_first_unset_in(StartInBytes, EndInBytes) != -1) {
2538-
if (!InvalidFragment)
2539-
DefinedBytes.set(StartInBytes, EndInBytes);
2540-
NewDefsReversed.push_back(*RIt);
2541-
continue;
2552+
// Redundant def found: throw it away. Since the wedge of defs is being
2553+
// rebuilt, doing nothing is the same as deleting an entry.
2554+
ChangedThisWedge = true;
2555+
NumDefsRemoved++;
25422556
}
25432557

2544-
// Redundant def found: throw it away. Since the wedge of defs is being
2545-
// rebuilt, doing nothing is the same as deleting an entry.
2546-
ChangedThisWedge = true;
2547-
NumDefsRemoved++;
2548-
}
2549-
2550-
// Un-reverse the defs and replace the wedge with the pruned version.
2551-
if (ChangedThisWedge) {
2552-
std::reverse(NewDefsReversed.begin(), NewDefsReversed.end());
2553-
FnVarLocs.setWedge(&I, std::move(NewDefsReversed));
2554-
NumWedgesChanged++;
2555-
Changed = true;
2556-
}
2558+
// Un-reverse the defs and replace the wedge with the pruned version.
2559+
if (ChangedThisWedge) {
2560+
std::reverse(NewDefsReversed.begin(), NewDefsReversed.end());
2561+
FnVarLocs.setWedge(WedgePosition, std::move(NewDefsReversed));
2562+
NumWedgesChanged++;
2563+
Changed = true;
2564+
}
2565+
};
2566+
HandleLocsForWedge(&I);
2567+
for (DPValue &DPV : reverse(I.getDbgValueRange()))
2568+
HandleLocsForWedge(&DPV);
25572569
}
25582570

25592571
return Changed;
@@ -2578,42 +2590,48 @@ removeRedundantDbgLocsUsingForwardScan(const BasicBlock *BB,
25782590
// instructions.
25792591
for (const Instruction &I : *BB) {
25802592
// Get the defs that come just before this instruction.
2581-
const auto *Locs = FnVarLocs.getWedge(&I);
2582-
if (!Locs)
2583-
continue;
2584-
2585-
NumWedgesScanned++;
2586-
bool ChangedThisWedge = false;
2587-
// The new pruned set of defs.
2588-
SmallVector<VarLocInfo> NewDefs;
2593+
auto HandleLocsForWedge = [&](auto *WedgePosition) {
2594+
const auto *Locs = FnVarLocs.getWedge(WedgePosition);
2595+
if (!Locs)
2596+
return;
2597+
2598+
NumWedgesScanned++;
2599+
bool ChangedThisWedge = false;
2600+
// The new pruned set of defs.
2601+
SmallVector<VarLocInfo> NewDefs;
2602+
2603+
// Iterate over the existing defs.
2604+
for (const VarLocInfo &Loc : *Locs) {
2605+
NumDefsScanned++;
2606+
DebugVariable Key(FnVarLocs.getVariable(Loc.VariableID).getVariable(),
2607+
std::nullopt, Loc.DL.getInlinedAt());
2608+
auto VMI = VariableMap.find(Key);
2609+
2610+
// Update the map if we found a new value/expression describing the
2611+
// variable, or if the variable wasn't mapped already.
2612+
if (VMI == VariableMap.end() || VMI->second.first != Loc.Values ||
2613+
VMI->second.second != Loc.Expr) {
2614+
VariableMap[Key] = {Loc.Values, Loc.Expr};
2615+
NewDefs.push_back(Loc);
2616+
continue;
2617+
}
25892618

2590-
// Iterate over the existing defs.
2591-
for (const VarLocInfo &Loc : *Locs) {
2592-
NumDefsScanned++;
2593-
DebugVariable Key(FnVarLocs.getVariable(Loc.VariableID).getVariable(),
2594-
std::nullopt, Loc.DL.getInlinedAt());
2595-
auto VMI = VariableMap.find(Key);
2596-
2597-
// Update the map if we found a new value/expression describing the
2598-
// variable, or if the variable wasn't mapped already.
2599-
if (VMI == VariableMap.end() || VMI->second.first != Loc.Values ||
2600-
VMI->second.second != Loc.Expr) {
2601-
VariableMap[Key] = {Loc.Values, Loc.Expr};
2602-
NewDefs.push_back(Loc);
2603-
continue;
2619+
// Did not insert this Loc, which is the same as removing it.
2620+
ChangedThisWedge = true;
2621+
NumDefsRemoved++;
26042622
}
26052623

2606-
// Did not insert this Loc, which is the same as removing it.
2607-
ChangedThisWedge = true;
2608-
NumDefsRemoved++;
2609-
}
2624+
// Replace the existing wedge with the pruned version.
2625+
if (ChangedThisWedge) {
2626+
FnVarLocs.setWedge(WedgePosition, std::move(NewDefs));
2627+
NumWedgesChanged++;
2628+
Changed = true;
2629+
}
2630+
};
26102631

2611-
// Replace the existing wedge with the pruned version.
2612-
if (ChangedThisWedge) {
2613-
FnVarLocs.setWedge(&I, std::move(NewDefs));
2614-
NumWedgesChanged++;
2615-
Changed = true;
2616-
}
2632+
for (DPValue &DPV : I.getDbgValueRange())
2633+
HandleLocsForWedge(&DPV);
2634+
HandleLocsForWedge(&I);
26172635
}
26182636

26192637
return Changed;
@@ -2660,41 +2678,46 @@ removeUndefDbgLocsFromEntryBlock(const BasicBlock *BB,
26602678
// instructions.
26612679
for (const Instruction &I : *BB) {
26622680
// Get the defs that come just before this instruction.
2663-
const auto *Locs = FnVarLocs.getWedge(&I);
2664-
if (!Locs)
2665-
continue;
2666-
2667-
NumWedgesScanned++;
2668-
bool ChangedThisWedge = false;
2669-
// The new pruned set of defs.
2670-
SmallVector<VarLocInfo> NewDefs;
2671-
2672-
// Iterate over the existing defs.
2673-
for (const VarLocInfo &Loc : *Locs) {
2674-
NumDefsScanned++;
2675-
DebugAggregate Aggr{FnVarLocs.getVariable(Loc.VariableID).getVariable(),
2676-
Loc.DL.getInlinedAt()};
2677-
DebugVariable Var = FnVarLocs.getVariable(Loc.VariableID);
2681+
auto HandleLocsForWedge = [&](auto *WedgePosition) {
2682+
const auto *Locs = FnVarLocs.getWedge(WedgePosition);
2683+
if (!Locs)
2684+
return;
2685+
2686+
NumWedgesScanned++;
2687+
bool ChangedThisWedge = false;
2688+
// The new pruned set of defs.
2689+
SmallVector<VarLocInfo> NewDefs;
2690+
2691+
// Iterate over the existing defs.
2692+
for (const VarLocInfo &Loc : *Locs) {
2693+
NumDefsScanned++;
2694+
DebugAggregate Aggr{FnVarLocs.getVariable(Loc.VariableID).getVariable(),
2695+
Loc.DL.getInlinedAt()};
2696+
DebugVariable Var = FnVarLocs.getVariable(Loc.VariableID);
2697+
2698+
// Remove undef entries that are encountered before any non-undef
2699+
// intrinsics from the entry block.
2700+
if (Loc.Values.isKillLocation(Loc.Expr) && !HasDefinedBits(Aggr, Var)) {
2701+
// Did not insert this Loc, which is the same as removing it.
2702+
NumDefsRemoved++;
2703+
ChangedThisWedge = true;
2704+
continue;
2705+
}
26782706

2679-
// Remove undef entries that are encountered before any non-undef
2680-
// intrinsics from the entry block.
2681-
if (Loc.Values.isKillLocation(Loc.Expr) && !HasDefinedBits(Aggr, Var)) {
2682-
// Did not insert this Loc, which is the same as removing it.
2683-
NumDefsRemoved++;
2684-
ChangedThisWedge = true;
2685-
continue;
2707+
DefineBits(Aggr, Var);
2708+
NewDefs.push_back(Loc);
26862709
}
26872710

2688-
DefineBits(Aggr, Var);
2689-
NewDefs.push_back(Loc);
2690-
}
2691-
2692-
// Replace the existing wedge with the pruned version.
2693-
if (ChangedThisWedge) {
2694-
FnVarLocs.setWedge(&I, std::move(NewDefs));
2695-
NumWedgesChanged++;
2696-
Changed = true;
2697-
}
2711+
// Replace the existing wedge with the pruned version.
2712+
if (ChangedThisWedge) {
2713+
FnVarLocs.setWedge(WedgePosition, std::move(NewDefs));
2714+
NumWedgesChanged++;
2715+
Changed = true;
2716+
}
2717+
};
2718+
for (DPValue &DPV : I.getDbgValueRange())
2719+
HandleLocsForWedge(&DPV);
2720+
HandleLocsForWedge(&I);
26982721
}
26992722

27002723
return Changed;
@@ -2726,6 +2749,9 @@ static DenseSet<DebugAggregate> findVarsWithStackSlot(Function &Fn) {
27262749
for (DbgAssignIntrinsic *DAI : at::getAssignmentMarkers(&I)) {
27272750
Result.insert({DAI->getVariable(), DAI->getDebugLoc().getInlinedAt()});
27282751
}
2752+
for (DPValue *DPV : at::getDPVAssignmentMarkers(&I)) {
2753+
Result.insert({DPV->getVariable(), DPV->getDebugLoc().getInlinedAt()});
2754+
}
27292755
}
27302756
}
27312757
return Result;

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1241,6 +1241,11 @@ void SelectionDAGBuilder::visitDbgInfo(const Instruction &I) {
12411241
It->Expr, Vals.size() > 1, It->DL, SDNodeOrder);
12421242
}
12431243
}
1244+
// We must early-exit here to prevent any DPValues from being emitted below,
1245+
// as we have just emitted the debug values resulting from assignment
1246+
// tracking analysis, making any existing DPValues redundant (and probably
1247+
// less correct).
1248+
return;
12441249
}
12451250

12461251
// Is there is any debug-info attached to this instruction, in the form of

llvm/test/DebugInfo/assignment-tracking/AArch64/scalable-vectors.ll

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
; RUN: llc %s -stop-after=finalize-isel -o - | FileCheck %s
22

3+
4+
; RUN: llc --try-experimental-debuginfo-iterators %s -stop-after=finalize-isel -o - | FileCheck %s
5+
36
;; Hand written. Check AssignmentTrackingAnalysis doesn't try to get the size
47
;; of scalable vectors (which causes an assertion failure).
58

llvm/test/DebugInfo/assignment-tracking/X86/DSE.ll

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
; RUN: llc %s -stop-before=finalize-isel -o - \
22
; RUN: | FileCheck %s
33

4+
5+
; RUN: llc --try-experimental-debuginfo-iterators %s -stop-before=finalize-isel -o - \
6+
; RUN: | FileCheck %s
7+
48
; Check basic lowering behaviour of dbg.assign intrinsics. The first
59
; assignment to `local`, which has been DSE'd, should be represented with a
610
; constant value DBG_VALUE. The second assignment should have a DBG_VALUE

llvm/test/DebugInfo/assignment-tracking/X86/assignment-tracking-not-enabled.ll

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
; RUN: llc %s -stop-after=finalize-isel -o - \
22
; RUN: | FileCheck %s --implicit-check-not=DBG_
33

4+
5+
; RUN: llc --try-experimental-debuginfo-iterators %s -stop-after=finalize-isel -o - \
6+
; RUN: | FileCheck %s --implicit-check-not=DBG_
7+
48
;; Check that SelectionDAG downgrades dbg.assigns to dbg.values if assignment
59
;; tracking isn't enabled (e.g. if the module flag
610
;; "debug-info-assignment-tracking" is missing / false).

llvm/test/DebugInfo/assignment-tracking/X86/coalesce-cfg.ll

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
; RUN: llc %s -o - -stop-after=finalize-isel \
22
; RUN: | FileCheck %s --implicit-check-not=DBG_
33

4+
5+
; RUN: llc --try-experimental-debuginfo-iterators %s -o - -stop-after=finalize-isel \
6+
; RUN: | FileCheck %s --implicit-check-not=DBG_
7+
48
;; Test coalescing of contiguous fragments in adjacent location definitions.
59
;; Further details and check directives inline.
610

llvm/test/DebugInfo/assignment-tracking/X86/dbg-phi-produces-undef.ll

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
; RUN: llc %s -stop-after=finalize-isel -o - \
22
; RUN: | FileCheck %s
33

4+
5+
; RUN: llc --try-experimental-debuginfo-iterators %s -stop-after=finalize-isel -o - \
6+
; RUN: | FileCheck %s
7+
48
;; Hand written test because the scenario is unlikely. Check that the "value"
59
;; of a debug def PHIs is "undef" (because we don't actually track PHIs).
610
;;

0 commit comments

Comments
 (0)