Skip to content

Commit 6aeb7a7

Browse files
authored
[RemoveDIs][DebugInfo] Add interface changes for AT analysis (#78460)
This patch adds the preliminary changes for handling DPValues in AssignmentTrackingAnalysis - very few functional changes are included, but internal data structures have been changed to operate with DPValues as well as Instructions, allowing future patches to process DPValues correctly.
1 parent c4fc563 commit 6aeb7a7

File tree

4 files changed

+172
-57
lines changed

4 files changed

+172
-57
lines changed

llvm/include/llvm/IR/DebugInfo.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ DISubprogram *getDISubprogram(const MDNode *Scope);
5858
/// Produce a DebugLoc to use for each dbg.declare that is promoted to a
5959
/// dbg.value.
6060
DebugLoc getDebugValueLoc(DbgVariableIntrinsic *DII);
61+
DebugLoc getDebugValueLoc(DPValue *DPV);
6162

6263
/// Strip debug info in the module if it exists.
6364
///
@@ -223,6 +224,11 @@ inline AssignmentMarkerRange getAssignmentMarkers(const Instruction *Inst) {
223224
else
224225
return make_range(Value::user_iterator(), Value::user_iterator());
225226
}
227+
inline SmallVector<DPValue *> getDPVAssignmentMarkers(const Instruction *Inst) {
228+
if (auto *ID = Inst->getMetadata(LLVMContext::MD_DIAssignID))
229+
return cast<DIAssignID>(ID)->getAllDPValueUsers();
230+
return {};
231+
}
226232

227233
/// Delete the llvm.dbg.assign intrinsics linked to \p Inst.
228234
void deleteAssignmentMarkers(const Instruction *Inst);
@@ -244,7 +250,11 @@ void deleteAll(Function *F);
244250
/// Result contains a zero-sized fragment if there's no intersect.
245251
bool calculateFragmentIntersect(
246252
const DataLayout &DL, const Value *Dest, uint64_t SliceOffsetInBits,
247-
uint64_t SliceSizeInBits, const DbgAssignIntrinsic *DAI,
253+
uint64_t SliceSizeInBits, const DbgAssignIntrinsic *DbgAssign,
254+
std::optional<DIExpression::FragmentInfo> &Result);
255+
bool calculateFragmentIntersect(
256+
const DataLayout &DL, const Value *Dest, uint64_t SliceOffsetInBits,
257+
uint64_t SliceSizeInBits, const DPValue *DPVAssign,
248258
std::optional<DIExpression::FragmentInfo> &Result);
249259

250260
/// Helper struct for trackAssignments, below. We don't use the similar
@@ -259,6 +269,8 @@ struct VarRecord {
259269

260270
VarRecord(DbgVariableIntrinsic *DVI)
261271
: Var(DVI->getVariable()), DL(getDebugValueLoc(DVI)) {}
272+
VarRecord(DPValue *DPV)
273+
: Var(DPV->getVariable()), DL(getDebugValueLoc(DPV)) {}
262274
VarRecord(DILocalVariable *Var, DILocation *DL) : Var(Var), DL(DL) {}
263275
friend bool operator<(const VarRecord &LHS, const VarRecord &RHS) {
264276
return std::tie(LHS.Var, LHS.DL) < std::tie(RHS.Var, RHS.DL);

llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp

Lines changed: 70 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "llvm/IR/BasicBlock.h"
2121
#include "llvm/IR/DataLayout.h"
2222
#include "llvm/IR/DebugInfo.h"
23+
#include "llvm/IR/DebugProgramInstruction.h"
2324
#include "llvm/IR/Function.h"
2425
#include "llvm/IR/Instruction.h"
2526
#include "llvm/IR/IntrinsicInst.h"
@@ -81,6 +82,19 @@ template <> struct llvm::DenseMapInfo<VariableID> {
8182
}
8283
};
8384

85+
using VarLocInsertPt = PointerUnion<const Instruction *, const DPValue *>;
86+
87+
namespace std {
88+
template <> struct hash<VarLocInsertPt> {
89+
using argument_type = VarLocInsertPt;
90+
using result_type = std::size_t;
91+
92+
result_type operator()(const argument_type &Arg) const {
93+
return std::hash<void *>()(Arg.getOpaqueValue());
94+
}
95+
};
96+
} // namespace std
97+
8498
/// Helper class to build FunctionVarLocs, since that class isn't easy to
8599
/// modify. TODO: There's not a great deal of value in the split, it could be
86100
/// worth merging the two classes.
@@ -89,8 +103,7 @@ class FunctionVarLocsBuilder {
89103
UniqueVector<DebugVariable> Variables;
90104
// Use an unordered_map so we don't invalidate iterators after
91105
// insert/modifications.
92-
std::unordered_map<const Instruction *, SmallVector<VarLocInfo>>
93-
VarLocsBeforeInst;
106+
std::unordered_map<VarLocInsertPt, SmallVector<VarLocInfo>> VarLocsBeforeInst;
94107

95108
SmallVector<VarLocInfo> SingleLocVars;
96109

@@ -109,15 +122,15 @@ class FunctionVarLocsBuilder {
109122

110123
/// Return ptr to wedge of defs or nullptr if no defs come just before /p
111124
/// Before.
112-
const SmallVectorImpl<VarLocInfo> *getWedge(const Instruction *Before) const {
125+
const SmallVectorImpl<VarLocInfo> *getWedge(VarLocInsertPt Before) const {
113126
auto R = VarLocsBeforeInst.find(Before);
114127
if (R == VarLocsBeforeInst.end())
115128
return nullptr;
116129
return &R->second;
117130
}
118131

119132
/// Replace the defs that come just before /p Before with /p Wedge.
120-
void setWedge(const Instruction *Before, SmallVector<VarLocInfo> &&Wedge) {
133+
void setWedge(VarLocInsertPt Before, SmallVector<VarLocInfo> &&Wedge) {
121134
VarLocsBeforeInst[Before] = std::move(Wedge);
122135
}
123136

@@ -133,7 +146,7 @@ class FunctionVarLocsBuilder {
133146
}
134147

135148
/// Add a def to the wedge of defs just before /p Before.
136-
void addVarLoc(Instruction *Before, DebugVariable Var, DIExpression *Expr,
149+
void addVarLoc(VarLocInsertPt Before, DebugVariable Var, DIExpression *Expr,
137150
DebugLoc DL, RawLocationWrapper R) {
138151
VarLocInfo VarLoc;
139152
VarLoc.VariableID = insertVariable(Var);
@@ -201,15 +214,31 @@ void FunctionVarLocs::init(FunctionVarLocsBuilder &Builder) {
201214
SingleVarLocEnd = VarLocRecords.size();
202215

203216
// Insert a contiguous block of VarLocInfos for each instruction, mapping it
204-
// to the start and end position in the vector with VarLocsBeforeInst.
217+
// to the start and end position in the vector with VarLocsBeforeInst. This
218+
// block includes VarLocs for any DPValues attached to that instruction.
205219
for (auto &P : Builder.VarLocsBeforeInst) {
220+
// Process VarLocs attached to a DPValue alongside their marker Instruction.
221+
if (isa<const DPValue *>(P.first))
222+
continue;
223+
const Instruction *I = cast<const Instruction *>(P.first);
206224
unsigned BlockStart = VarLocRecords.size();
225+
// Any VarLocInfos attached to a DPValue should now be remapped to their
226+
// marker Instruction, in order of DPValue appearance and prior to any
227+
// VarLocInfos attached directly to that instruction.
228+
for (const DPValue &DPV : I->getDbgValueRange()) {
229+
// Even though DPV defines a variable location, VarLocsBeforeInst can
230+
// still be empty if that VarLoc was redundant.
231+
if (!Builder.VarLocsBeforeInst.count(&DPV))
232+
continue;
233+
for (const VarLocInfo &VarLoc : Builder.VarLocsBeforeInst[&DPV])
234+
VarLocRecords.emplace_back(VarLoc);
235+
}
207236
for (const VarLocInfo &VarLoc : P.second)
208237
VarLocRecords.emplace_back(VarLoc);
209238
unsigned BlockEnd = VarLocRecords.size();
210239
// Record the start and end indices.
211240
if (BlockEnd != BlockStart)
212-
VarLocsBeforeInst[P.first] = {BlockStart, BlockEnd};
241+
VarLocsBeforeInst[I] = {BlockStart, BlockEnd};
213242
}
214243

215244
// Copy the Variables vector from the builder's UniqueVector.
@@ -370,7 +399,7 @@ class MemLocFragmentFill {
370399
unsigned SizeInBits;
371400
DebugLoc DL;
372401
};
373-
using InsertMap = MapVector<Instruction *, SmallVector<FragMemLoc>>;
402+
using InsertMap = MapVector<VarLocInsertPt, SmallVector<FragMemLoc>>;
374403

375404
/// BBInsertBeforeMap holds a description for the set of location defs to be
376405
/// inserted after the analysis is complete. It is updated during the dataflow
@@ -590,7 +619,7 @@ class MemLocFragmentFill {
590619
return /*Changed=*/false;
591620
}
592621

593-
void insertMemLoc(BasicBlock &BB, Instruction &Before, unsigned Var,
622+
void insertMemLoc(BasicBlock &BB, VarLocInsertPt Before, unsigned Var,
594623
unsigned StartBit, unsigned EndBit, unsigned Base,
595624
DebugLoc DL) {
596625
assert(StartBit < EndBit && "Cannot create fragment of size <= 0");
@@ -603,7 +632,7 @@ class MemLocFragmentFill {
603632
assert(Base && "Expected a non-zero ID for Base address");
604633
Loc.Base = Base;
605634
Loc.DL = DL;
606-
BBInsertBeforeMap[&BB][&Before].push_back(Loc);
635+
BBInsertBeforeMap[&BB][Before].push_back(Loc);
607636
LLVM_DEBUG(dbgs() << "Add mem def for " << Aggregates[Var].first->getName()
608637
<< " bits [" << StartBit << ", " << EndBit << ")\n");
609638
}
@@ -612,7 +641,7 @@ class MemLocFragmentFill {
612641
/// in \p FragMap starts before \p StartBit or ends after \p EndBit (which
613642
/// indicates - assuming StartBit->EndBit has just been inserted - that the
614643
/// slice has been coalesced in the map).
615-
void coalesceFragments(BasicBlock &BB, Instruction &Before, unsigned Var,
644+
void coalesceFragments(BasicBlock &BB, VarLocInsertPt Before, unsigned Var,
616645
unsigned StartBit, unsigned EndBit, unsigned Base,
617646
DebugLoc DL, const FragsInMemMap &FragMap) {
618647
if (!CoalesceAdjacentFragments)
@@ -633,7 +662,7 @@ class MemLocFragmentFill {
633662
Base, DL);
634663
}
635664

636-
void addDef(const VarLocInfo &VarLoc, Instruction &Before, BasicBlock &BB,
665+
void addDef(const VarLocInfo &VarLoc, VarLocInsertPt Before, BasicBlock &BB,
637666
VarFragMap &LiveSet) {
638667
DebugVariable DbgVar = FnVarLocs->getVariable(VarLoc.VariableID);
639668
if (skipVariable(DbgVar.getVariable()))
@@ -802,7 +831,7 @@ class MemLocFragmentFill {
802831
for (auto &I : BB) {
803832
if (const auto *Locs = FnVarLocs->getWedge(&I)) {
804833
for (const VarLocInfo &Loc : *Locs) {
805-
addDef(Loc, I, *I.getParent(), LiveSet);
834+
addDef(Loc, &I, *I.getParent(), LiveSet);
806835
}
807836
}
808837
}
@@ -923,7 +952,7 @@ class MemLocFragmentFill {
923952
for (auto &Pair : BBInsertBeforeMap) {
924953
InsertMap &Map = Pair.second;
925954
for (auto &Pair : Map) {
926-
Instruction *InsertBefore = Pair.first;
955+
auto InsertBefore = Pair.first;
927956
assert(InsertBefore && "should never be null");
928957
auto FragMemLocs = Pair.second;
929958
auto &Ctx = Fn.getContext();
@@ -1056,11 +1085,12 @@ class AssignmentTrackingLowering {
10561085
UntaggedStoreAssignmentMap UntaggedStoreVars;
10571086

10581087
// Machinery to defer inserting dbg.values.
1059-
using InsertMap = MapVector<Instruction *, SmallVector<VarLocInfo>>;
1060-
InsertMap InsertBeforeMap;
1088+
using InstInsertMap = MapVector<VarLocInsertPt, SmallVector<VarLocInfo>>;
1089+
InstInsertMap InsertBeforeMap;
10611090
/// Clear the location definitions currently cached for insertion after /p
10621091
/// After.
10631092
void resetInsertionPoint(Instruction &After);
1093+
void resetInsertionPoint(DPValue &After);
10641094
void emitDbgValue(LocKind Kind, const DbgVariableIntrinsic *Source,
10651095
Instruction *After);
10661096

@@ -1418,6 +1448,24 @@ const char *locStr(AssignmentTrackingLowering::LocKind Loc) {
14181448
}
14191449
#endif
14201450

1451+
VarLocInsertPt getNextNode(const DPValue *DPV) {
1452+
auto NextIt = ++(DPV->getIterator());
1453+
if (NextIt == DPV->getMarker()->getDbgValueRange().end())
1454+
return DPV->getMarker()->MarkedInstr;
1455+
return &*NextIt;
1456+
}
1457+
VarLocInsertPt getNextNode(const Instruction *Inst) {
1458+
const Instruction *Next = Inst->getNextNode();
1459+
if (!Next->hasDbgValues())
1460+
return Next;
1461+
return &*Next->getDbgValueRange().begin();
1462+
}
1463+
VarLocInsertPt getNextNode(VarLocInsertPt InsertPt) {
1464+
if (isa<const Instruction *>(InsertPt))
1465+
return getNextNode(cast<const Instruction *>(InsertPt));
1466+
return getNextNode(cast<const DPValue *>(InsertPt));
1467+
}
1468+
14211469
void AssignmentTrackingLowering::emitDbgValue(
14221470
AssignmentTrackingLowering::LocKind Kind,
14231471
const DbgVariableIntrinsic *Source, Instruction *After) {
@@ -1430,7 +1478,7 @@ void AssignmentTrackingLowering::emitDbgValue(
14301478
PoisonValue::get(Type::getInt1Ty(Source->getContext())));
14311479

14321480
// Find a suitable insert point.
1433-
Instruction *InsertBefore = After->getNextNode();
1481+
auto InsertBefore = getNextNode(After);
14341482
assert(InsertBefore && "Shouldn't be inserting after a terminator");
14351483

14361484
VariableID Var = getVariableID(DebugVariable(Source));
@@ -1538,8 +1586,9 @@ void AssignmentTrackingLowering::processUntaggedInstruction(
15381586
Ops.push_back(dwarf::DW_OP_deref);
15391587
DIE = DIExpression::prependOpcodes(DIE, Ops, /*StackValue=*/false,
15401588
/*EntryValue=*/false);
1541-
// Find a suitable insert point.
1542-
Instruction *InsertBefore = I.getNextNode();
1589+
// Find a suitable insert point, before the next instruction or DPValue
1590+
// after I.
1591+
auto InsertBefore = getNextNode(&I);
15431592
assert(InsertBefore && "Shouldn't be inserting after a terminator");
15441593

15451594
// Get DILocation for this unrecorded assignment.
@@ -1710,8 +1759,8 @@ void AssignmentTrackingLowering::processDbgValue(DbgValueInst &DVI,
17101759
emitDbgValue(LocKind::Val, &DVI, &DVI);
17111760
}
17121761

1713-
static bool hasZeroSizedFragment(DbgVariableIntrinsic &DVI) {
1714-
if (auto F = DVI.getExpression()->getFragmentInfo())
1762+
template <typename T> static bool hasZeroSizedFragment(T &DbgValue) {
1763+
if (auto F = DbgValue.getExpression()->getFragmentInfo())
17151764
return F->SizeInBits == 0;
17161765
return false;
17171766
}

0 commit comments

Comments
 (0)