[llvm] 0eee844 - [DebugInfo][InstrRef] Terminate overlapping variable fragments
Jeremy Morse via llvm-commits
llvm-commits at lists.llvm.org
Mon Nov 29 15:37:49 PST 2021
Author: Jeremy Morse
Date: 2021-11-29T23:37:20Z
New Revision: 0eee844539e406dfa8010a129ea3655d2298ac10
URL: https://github.com/llvm/llvm-project/commit/0eee844539e406dfa8010a129ea3655d2298ac10
DIFF: https://github.com/llvm/llvm-project/commit/0eee844539e406dfa8010a129ea3655d2298ac10.diff
LOG: [DebugInfo][InstrRef] Terminate overlapping variable fragments
If we have a variable where its fragments are split into overlapping
segments:
DBG_VALUE $ax, $noreg, !123, !DIExpression(DW_OP_LLVM_fragment_0, 16)
...
DBG_VALUE $eax, $noreg, !123, !DIExpression(DW_OP_LLVM_fragment_0, 32)
we should only propagate the most recently assigned fragment out of a
block. LiveDebugValues only deals with live-in variable locations, as
overlaps within blocks is DbgEntityHistoryCalculators domain.
InstrRefBasedLDV has kept the accumulateFragmentMap method from
VarLocBasedLDV, we just need it to recognise DBG_INSTR_REFs. Once it's
produced a mapping of variable / fragments to the overlapped variable /
fragments, VLocTracker uses it to identify when a debug instruction needs
to terminate the other parts it overlaps with. The test is updated for
some standard "InstrRef picks different registers" variation, and the
order of some unrelated DBG_VALUEs changes.
Differential Revision: https://reviews.llvm.org/D114603
Added:
Modified:
llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp
llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.h
llvm/test/DebugInfo/MIR/X86/live-debug-values-fragments.mir
llvm/unittests/CodeGen/InstrRefLDVTest.cpp
Removed:
################################################################################
diff --git a/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp b/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp
index 40537b786233a..377fd57c17674 100644
--- a/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp
+++ b/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp
@@ -1657,9 +1657,10 @@ bool InstrRefBasedLDV::transferRegisterCopy(MachineInstr &MI) {
/// fragments of that DILocalVariable which overlap. This reduces work during
/// the data-flow stage from "Find any overlapping fragments" to "Check if the
/// known-to-overlap fragments are present".
-/// \param MI A previously unprocessed DEBUG_VALUE instruction to analyze for
+/// \param MI A previously unprocessed debug instruction to analyze for
/// fragment usage.
void InstrRefBasedLDV::accumulateFragmentMap(MachineInstr &MI) {
+ assert(MI.isDebugValue() || MI.isDebugRef());
DebugVariable MIVar(MI.getDebugVariable(), MI.getDebugExpression(),
MI.getDebugLoc()->getInlinedAt());
FragmentInfo ThisFragment = MIVar.getFragmentOrDefault();
@@ -1761,7 +1762,7 @@ void InstrRefBasedLDV::produceMLocTransferFunction(
for (auto &MI : MBB) {
process(MI);
// Also accumulate fragment map.
- if (MI.isDebugValue())
+ if (MI.isDebugValue() || MI.isDebugRef())
accumulateFragmentMap(MI);
// Create a map from the instruction number (if present) to the
@@ -2929,7 +2930,7 @@ bool InstrRefBasedLDV::ExtendRanges(MachineFunction &MF,
++MaxNumBlocks;
MLocTransfer.resize(MaxNumBlocks);
- vlocs.resize(MaxNumBlocks);
+ vlocs.resize(MaxNumBlocks, VLocTracker(OverlapFragments, EmptyExpr));
SavedLiveIns.resize(MaxNumBlocks);
initialSetup(MF);
@@ -3074,6 +3075,8 @@ bool InstrRefBasedLDV::ExtendRanges(MachineFunction &MF,
BBNumToRPO.clear();
DebugInstrNumToInstr.clear();
DebugPHINumToValue.clear();
+ OverlapFragments.clear();
+ SeenFragments.clear();
return Changed;
}
diff --git a/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.h b/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.h
index 81005e291635f..13ef84d44aa6a 100644
--- a/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.h
+++ b/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.h
@@ -655,6 +655,14 @@ class MLocTracker {
const DbgValueProperties &Properties);
};
+/// Types for recording sets of variable fragments that overlap. For a given
+/// local variable, we record all other fragments of that variable that could
+/// overlap it, to reduce search time.
+using FragmentOfVar =
+ std::pair<const DILocalVariable *, DIExpression::FragmentInfo>;
+using OverlapMap =
+ DenseMap<FragmentOfVar, SmallVector<DIExpression::FragmentInfo, 1>>;
+
/// Collection of DBG_VALUEs observed when traversing a block. Records each
/// variable and the value the DBG_VALUE refers to. Requires the machine value
/// location dataflow algorithm to have run already, so that values can be
@@ -672,9 +680,12 @@ class VLocTracker {
MapVector<DebugVariable, DbgValue> Vars;
DenseMap<DebugVariable, const DILocation *> Scopes;
MachineBasicBlock *MBB = nullptr;
+ const OverlapMap &OverlappingFragments;
+ DbgValueProperties EmptyProperties;
public:
- VLocTracker() {}
+ VLocTracker(const OverlapMap &O, const DIExpression *EmptyExpr)
+ : OverlappingFragments(O), EmptyProperties(EmptyExpr, false) {}
void defVar(const MachineInstr &MI, const DbgValueProperties &Properties,
Optional<ValueIDNum> ID) {
@@ -689,6 +700,8 @@ class VLocTracker {
if (!Result.second)
Result.first->second = Rec;
Scopes[Var] = MI.getDebugLoc().get();
+
+ considerOverlaps(Var, MI.getDebugLoc().get());
}
void defVar(const MachineInstr &MI, const MachineOperand &MO) {
@@ -704,16 +717,37 @@ class VLocTracker {
if (!Result.second)
Result.first->second = Rec;
Scopes[Var] = MI.getDebugLoc().get();
+
+ considerOverlaps(Var, MI.getDebugLoc().get());
}
-};
-/// Types for recording sets of variable fragments that overlap. For a given
-/// local variable, we record all other fragments of that variable that could
-/// overlap it, to reduce search time.
-using FragmentOfVar =
- std::pair<const DILocalVariable *, DIExpression::FragmentInfo>;
-using OverlapMap =
- DenseMap<FragmentOfVar, SmallVector<DIExpression::FragmentInfo, 1>>;
+ void considerOverlaps(const DebugVariable &Var, const DILocation *Loc) {
+ auto Overlaps = OverlappingFragments.find(
+ {Var.getVariable(), Var.getFragmentOrDefault()});
+ if (Overlaps == OverlappingFragments.end())
+ return;
+
+ // Otherwise: terminate any overlapped variable locations.
+ for (auto FragmentInfo : Overlaps->second) {
+ // The "empty" fragment is stored as DebugVariable::DefaultFragment, so
+ // that it overlaps with everything, however its cannonical representation
+ // in a DebugVariable is as "None".
+ Optional<DIExpression::FragmentInfo> OptFragmentInfo = FragmentInfo;
+ if (DebugVariable::isDefaultFragment(FragmentInfo))
+ OptFragmentInfo = None;
+
+ DebugVariable Overlapped(Var.getVariable(), OptFragmentInfo,
+ Var.getInlinedAt());
+ DbgValue Rec = DbgValue(EmptyProperties, DbgValue::Undef);
+
+ // Attempt insertion; overwrite if it's already mapped.
+ auto Result = Vars.insert(std::make_pair(Overlapped, Rec));
+ if (!Result.second)
+ Result.first->second = Rec;
+ Scopes[Overlapped] = Loc;
+ }
+ }
+};
// XXX XXX docs
class InstrRefBasedLDV : public LDVImpl {
diff --git a/llvm/test/DebugInfo/MIR/X86/live-debug-values-fragments.mir b/llvm/test/DebugInfo/MIR/X86/live-debug-values-fragments.mir
index 34317d71ead74..eef53c0a466cc 100644
--- a/llvm/test/DebugInfo/MIR/X86/live-debug-values-fragments.mir
+++ b/llvm/test/DebugInfo/MIR/X86/live-debug-values-fragments.mir
@@ -1,4 +1,4 @@
-# RUN: llc %s -o - -run-pass=livedebugvalues -experimental-debug-variable-locations=false | FileCheck %s
+# RUN: llc %s -o - -run-pass=livedebugvalues -experimental-debug-variable-locations=true | FileCheck %s
#
# The first func tests that, for two independent variable fragments defined in
# blocks 1 and 2, _both_ their locations are propagated into the exit block.
@@ -15,10 +15,10 @@
#
# CHECK-LABEL: foo
# CHECK-LABEL: bb.3.bb3:
-# CHECK: DBG_VALUE $ebx, $noreg, !{{[0-9]+}},
-# CHECK-SAME: !DIExpression(DW_OP_LLVM_fragment, 32, 32)
-# CHECK-NEXT: DBG_VALUE $eax, $noreg, !{{[0-9]+}},
+# CHECK: DBG_VALUE $ecx, $noreg, !{{[0-9]+}},
# CHECK-SAME: !DIExpression(DW_OP_LLVM_fragment, 0, 32)
+# CHECK-NEXT: DBG_VALUE $ebx, $noreg, !{{[0-9]+}},
+# CHECK-SAME: !DIExpression(DW_OP_LLVM_fragment, 32, 32)
# CHECK-NEXT: XOR32rr
# CHECK-NEXT: RET64
#
@@ -37,7 +37,7 @@
# CHECK-LABEL: bb.2.bb2:
# CHECK-NOT: DBG_VALUE
-# CHECK: DBG_VALUE $ax, $noreg, !{{[0-9]+}},
+# CHECK: DBG_VALUE $cx, $noreg, !{{[0-9]+}},
# CHECK-SAME: !DIExpression(DW_OP_LLVM_fragment, 8, 16)
# CHECK-NEXT: MOV32rr
# CHECK-NEXT: ADD32ri8
@@ -46,10 +46,10 @@
# CHECK-NEXT: JMP_1
# CHECK-LABEL: bb.3.bb3:
-# CHECK: DBG_VALUE $ebx, $noreg, !{{[0-9]+}},
-# CHECK-SAME: !DIExpression(DW_OP_LLVM_fragment, 32, 32)
-# CHECK-NEXT: DBG_VALUE $ax, $noreg, !{{[0-9]+}},
+# CHECK: DBG_VALUE $cx, $noreg, !{{[0-9]+}},
# CHECK-SAME: !DIExpression(DW_OP_LLVM_fragment, 8, 16)
+# CHECK-NEXT: DBG_VALUE $ebx, $noreg, !{{[0-9]+}},
+# CHECK-SAME: !DIExpression(DW_OP_LLVM_fragment, 32, 32)
# CHECK-NEXT: XOR32rr
# CHECK-NEXT: RET64
diff --git a/llvm/unittests/CodeGen/InstrRefLDVTest.cpp b/llvm/unittests/CodeGen/InstrRefLDVTest.cpp
index 866eef8f824ed..d093f283ac729 100644
--- a/llvm/unittests/CodeGen/InstrRefLDVTest.cpp
+++ b/llvm/unittests/CodeGen/InstrRefLDVTest.cpp
@@ -49,6 +49,7 @@ class InstrRefLDVTest : public testing::Test {
DILocalVariable *FuncVariable;
DIBasicType *LongInt;
DIExpression *EmptyExpr;
+ LiveDebugValues::OverlapMap Overlaps;
DebugLoc OutermostLoc, InBlockLoc, NotNestedBlockLoc, InlinedLoc;
@@ -169,7 +170,7 @@ class InstrRefLDVTest : public testing::Test {
void addVTracker() {
ASSERT_TRUE(LDV);
- VTracker = std::make_unique<VLocTracker>();
+ VTracker = std::make_unique<VLocTracker>(Overlaps, EmptyExpr);
LDV->VTracker = &*VTracker;
}
@@ -2515,7 +2516,7 @@ TEST_F(InstrRefLDVTest, VLocSingleBlock) {
AssignBlocks.insert(MBB0);
SmallVector<VLocTracker, 1> VLocs;
- VLocs.resize(1);
+ VLocs.resize(1, VLocTracker(Overlaps, EmptyExpr));
InstrRefBasedLDV::LiveInsT Output;
@@ -2579,7 +2580,7 @@ TEST_F(InstrRefLDVTest, VLocDiamondBlocks) {
AssignBlocks.insert(MBB3);
SmallVector<VLocTracker, 1> VLocs;
- VLocs.resize(4);
+ VLocs.resize(4, VLocTracker(Overlaps, EmptyExpr));
InstrRefBasedLDV::LiveInsT Output;
@@ -2792,7 +2793,7 @@ TEST_F(InstrRefLDVTest, VLocSimpleLoop) {
AssignBlocks.insert(MBB2);
SmallVector<VLocTracker, 3> VLocs;
- VLocs.resize(3);
+ VLocs.resize(3, VLocTracker(Overlaps, EmptyExpr));
InstrRefBasedLDV::LiveInsT Output;
@@ -3048,7 +3049,7 @@ TEST_F(InstrRefLDVTest, VLocNestedLoop) {
AssignBlocks.insert(MBB4);
SmallVector<VLocTracker, 5> VLocs;
- VLocs.resize(5);
+ VLocs.resize(5, VLocTracker(Overlaps, EmptyExpr));
InstrRefBasedLDV::LiveInsT Output;
More information about the llvm-commits
mailing list