20
20
#include " llvm/IR/BasicBlock.h"
21
21
#include " llvm/IR/DataLayout.h"
22
22
#include " llvm/IR/DebugInfo.h"
23
+ #include " llvm/IR/DebugProgramInstruction.h"
23
24
#include " llvm/IR/Function.h"
24
25
#include " llvm/IR/Instruction.h"
25
26
#include " llvm/IR/IntrinsicInst.h"
@@ -81,6 +82,19 @@ template <> struct llvm::DenseMapInfo<VariableID> {
81
82
}
82
83
};
83
84
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
+
84
98
// / Helper class to build FunctionVarLocs, since that class isn't easy to
85
99
// / modify. TODO: There's not a great deal of value in the split, it could be
86
100
// / worth merging the two classes.
@@ -89,8 +103,7 @@ class FunctionVarLocsBuilder {
89
103
UniqueVector<DebugVariable> Variables;
90
104
// Use an unordered_map so we don't invalidate iterators after
91
105
// insert/modifications.
92
- std::unordered_map<const Instruction *, SmallVector<VarLocInfo>>
93
- VarLocsBeforeInst;
106
+ std::unordered_map<VarLocInsertPt, SmallVector<VarLocInfo>> VarLocsBeforeInst;
94
107
95
108
SmallVector<VarLocInfo> SingleLocVars;
96
109
@@ -109,15 +122,15 @@ class FunctionVarLocsBuilder {
109
122
110
123
// / Return ptr to wedge of defs or nullptr if no defs come just before /p
111
124
// / Before.
112
- const SmallVectorImpl<VarLocInfo> *getWedge (const Instruction * Before) const {
125
+ const SmallVectorImpl<VarLocInfo> *getWedge (VarLocInsertPt Before) const {
113
126
auto R = VarLocsBeforeInst.find (Before);
114
127
if (R == VarLocsBeforeInst.end ())
115
128
return nullptr ;
116
129
return &R->second ;
117
130
}
118
131
119
132
// / 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) {
121
134
VarLocsBeforeInst[Before] = std::move (Wedge);
122
135
}
123
136
@@ -133,7 +146,7 @@ class FunctionVarLocsBuilder {
133
146
}
134
147
135
148
// / 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,
137
150
DebugLoc DL, RawLocationWrapper R) {
138
151
VarLocInfo VarLoc;
139
152
VarLoc.VariableID = insertVariable (Var);
@@ -201,15 +214,31 @@ void FunctionVarLocs::init(FunctionVarLocsBuilder &Builder) {
201
214
SingleVarLocEnd = VarLocRecords.size ();
202
215
203
216
// 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.
205
219
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 );
206
224
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
+ }
207
236
for (const VarLocInfo &VarLoc : P.second )
208
237
VarLocRecords.emplace_back (VarLoc);
209
238
unsigned BlockEnd = VarLocRecords.size ();
210
239
// Record the start and end indices.
211
240
if (BlockEnd != BlockStart)
212
- VarLocsBeforeInst[P. first ] = {BlockStart, BlockEnd};
241
+ VarLocsBeforeInst[I ] = {BlockStart, BlockEnd};
213
242
}
214
243
215
244
// Copy the Variables vector from the builder's UniqueVector.
@@ -370,7 +399,7 @@ class MemLocFragmentFill {
370
399
unsigned SizeInBits;
371
400
DebugLoc DL;
372
401
};
373
- using InsertMap = MapVector<Instruction * , SmallVector<FragMemLoc>>;
402
+ using InsertMap = MapVector<VarLocInsertPt , SmallVector<FragMemLoc>>;
374
403
375
404
// / BBInsertBeforeMap holds a description for the set of location defs to be
376
405
// / inserted after the analysis is complete. It is updated during the dataflow
@@ -590,7 +619,7 @@ class MemLocFragmentFill {
590
619
return /* Changed=*/ false ;
591
620
}
592
621
593
- void insertMemLoc (BasicBlock &BB, Instruction & Before, unsigned Var,
622
+ void insertMemLoc (BasicBlock &BB, VarLocInsertPt Before, unsigned Var,
594
623
unsigned StartBit, unsigned EndBit, unsigned Base,
595
624
DebugLoc DL) {
596
625
assert (StartBit < EndBit && " Cannot create fragment of size <= 0" );
@@ -603,7 +632,7 @@ class MemLocFragmentFill {
603
632
assert (Base && " Expected a non-zero ID for Base address" );
604
633
Loc.Base = Base;
605
634
Loc.DL = DL;
606
- BBInsertBeforeMap[&BB][& Before].push_back (Loc);
635
+ BBInsertBeforeMap[&BB][Before].push_back (Loc);
607
636
LLVM_DEBUG (dbgs () << " Add mem def for " << Aggregates[Var].first ->getName ()
608
637
<< " bits [" << StartBit << " , " << EndBit << " )\n " );
609
638
}
@@ -612,7 +641,7 @@ class MemLocFragmentFill {
612
641
// / in \p FragMap starts before \p StartBit or ends after \p EndBit (which
613
642
// / indicates - assuming StartBit->EndBit has just been inserted - that the
614
643
// / 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,
616
645
unsigned StartBit, unsigned EndBit, unsigned Base,
617
646
DebugLoc DL, const FragsInMemMap &FragMap) {
618
647
if (!CoalesceAdjacentFragments)
@@ -633,7 +662,7 @@ class MemLocFragmentFill {
633
662
Base, DL);
634
663
}
635
664
636
- void addDef (const VarLocInfo &VarLoc, Instruction & Before, BasicBlock &BB,
665
+ void addDef (const VarLocInfo &VarLoc, VarLocInsertPt Before, BasicBlock &BB,
637
666
VarFragMap &LiveSet) {
638
667
DebugVariable DbgVar = FnVarLocs->getVariable (VarLoc.VariableID );
639
668
if (skipVariable (DbgVar.getVariable ()))
@@ -802,7 +831,7 @@ class MemLocFragmentFill {
802
831
for (auto &I : BB) {
803
832
if (const auto *Locs = FnVarLocs->getWedge (&I)) {
804
833
for (const VarLocInfo &Loc : *Locs) {
805
- addDef (Loc, I, *I.getParent (), LiveSet);
834
+ addDef (Loc, & I, *I.getParent (), LiveSet);
806
835
}
807
836
}
808
837
}
@@ -923,7 +952,7 @@ class MemLocFragmentFill {
923
952
for (auto &Pair : BBInsertBeforeMap) {
924
953
InsertMap &Map = Pair.second ;
925
954
for (auto &Pair : Map) {
926
- Instruction * InsertBefore = Pair.first ;
955
+ auto InsertBefore = Pair.first ;
927
956
assert (InsertBefore && " should never be null" );
928
957
auto FragMemLocs = Pair.second ;
929
958
auto &Ctx = Fn.getContext ();
@@ -1056,11 +1085,12 @@ class AssignmentTrackingLowering {
1056
1085
UntaggedStoreAssignmentMap UntaggedStoreVars;
1057
1086
1058
1087
// 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;
1061
1090
// / Clear the location definitions currently cached for insertion after /p
1062
1091
// / After.
1063
1092
void resetInsertionPoint (Instruction &After);
1093
+ void resetInsertionPoint (DPValue &After);
1064
1094
void emitDbgValue (LocKind Kind, const DbgVariableIntrinsic *Source,
1065
1095
Instruction *After);
1066
1096
@@ -1418,6 +1448,24 @@ const char *locStr(AssignmentTrackingLowering::LocKind Loc) {
1418
1448
}
1419
1449
#endif
1420
1450
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
+
1421
1469
void AssignmentTrackingLowering::emitDbgValue (
1422
1470
AssignmentTrackingLowering::LocKind Kind,
1423
1471
const DbgVariableIntrinsic *Source, Instruction *After) {
@@ -1430,7 +1478,7 @@ void AssignmentTrackingLowering::emitDbgValue(
1430
1478
PoisonValue::get (Type::getInt1Ty (Source->getContext ())));
1431
1479
1432
1480
// Find a suitable insert point.
1433
- Instruction * InsertBefore = After-> getNextNode ();
1481
+ auto InsertBefore = getNextNode (After );
1434
1482
assert (InsertBefore && " Shouldn't be inserting after a terminator" );
1435
1483
1436
1484
VariableID Var = getVariableID (DebugVariable (Source));
@@ -1538,8 +1586,9 @@ void AssignmentTrackingLowering::processUntaggedInstruction(
1538
1586
Ops.push_back (dwarf::DW_OP_deref);
1539
1587
DIE = DIExpression::prependOpcodes (DIE, Ops, /* StackValue=*/ false ,
1540
1588
/* 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);
1543
1592
assert (InsertBefore && " Shouldn't be inserting after a terminator" );
1544
1593
1545
1594
// Get DILocation for this unrecorded assignment.
@@ -1710,8 +1759,8 @@ void AssignmentTrackingLowering::processDbgValue(DbgValueInst &DVI,
1710
1759
emitDbgValue (LocKind::Val, &DVI, &DVI);
1711
1760
}
1712
1761
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 ())
1715
1764
return F->SizeInBits == 0 ;
1716
1765
return false ;
1717
1766
}
0 commit comments