23
23
#include " llvm/ADT/SparseBitVector.h"
24
24
#include " llvm/ADT/Statistic.h"
25
25
#include " llvm/ADT/UniqueVector.h"
26
+ #include " llvm/CodeGen/LexicalScopes.h"
26
27
#include " llvm/CodeGen/MachineFunction.h"
27
28
#include " llvm/CodeGen/MachineFunctionPass.h"
28
29
#include " llvm/CodeGen/MachineInstrBuilder.h"
@@ -60,6 +61,26 @@ class LiveDebugValues : public MachineFunctionPass {
60
61
private:
61
62
const TargetRegisterInfo *TRI;
62
63
const TargetInstrInfo *TII;
64
+ LexicalScopes LS;
65
+
66
+ // / Keeps track of lexical scopes associated with a user value's source
67
+ // / location.
68
+ class UserValueScopes {
69
+ DebugLoc DL;
70
+ LexicalScopes &LS;
71
+ SmallPtrSet<const MachineBasicBlock *, 4 > LBlocks;
72
+
73
+ public:
74
+ UserValueScopes (DebugLoc D, LexicalScopes &L) : DL(std::move(D)), LS(L) {}
75
+
76
+ // / Return true if current scope dominates at least one machine
77
+ // / instruction in a given machine basic block.
78
+ bool dominates (MachineBasicBlock *MBB) {
79
+ if (LBlocks.empty ())
80
+ LS.getMachineBasicBlocks (DL, LBlocks);
81
+ return LBlocks.count (MBB) != 0 || LS.dominates (DL, MBB);
82
+ }
83
+ };
63
84
64
85
// / Based on std::pair so it can be used as an index into a DenseMap.
65
86
typedef std::pair<const DILocalVariable *, const DILocation *>
@@ -83,7 +104,7 @@ class LiveDebugValues : public MachineFunctionPass {
83
104
struct VarLoc {
84
105
const DebugVariable Var;
85
106
const MachineInstr &MI; // /< Only used for cloning a new DBG_VALUE.
86
-
107
+ mutable UserValueScopes UVS;
87
108
enum { InvalidKind = 0 , RegisterKind } Kind;
88
109
89
110
// / The value location. Stored separately to avoid repeatedly
@@ -96,9 +117,9 @@ class LiveDebugValues : public MachineFunctionPass {
96
117
uint64_t Hash;
97
118
} Loc;
98
119
99
- VarLoc (const MachineInstr &MI)
120
+ VarLoc (const MachineInstr &MI, LexicalScopes &LS )
100
121
: Var(MI.getDebugVariable(), MI.getDebugLoc()->getInlinedAt ()), MI(MI),
101
- Kind(InvalidKind) {
122
+ UVS(MI.getDebugLoc(), LS), Kind(InvalidKind) {
102
123
static_assert ((sizeof (Loc) == sizeof (uint64_t )),
103
124
" hash does not cover all members of Loc" );
104
125
assert (MI.isDebugValue () && " not a DBG_VALUE" );
@@ -125,6 +146,10 @@ class LiveDebugValues : public MachineFunctionPass {
125
146
return 0 ;
126
147
}
127
148
149
+ // / Determine whether the lexical scope of this value's debug location
150
+ // / dominates MBB.
151
+ bool dominates (MachineBasicBlock &MBB) const { return UVS.dominates (&MBB); }
152
+
128
153
void dump () const { MI.dump (); }
129
154
130
155
bool operator ==(const VarLoc &Other) const {
@@ -201,7 +226,8 @@ class LiveDebugValues : public MachineFunctionPass {
201
226
VarLocInMBB &OutLocs, VarLocMap &VarLocIDs);
202
227
203
228
bool join (MachineBasicBlock &MBB, VarLocInMBB &OutLocs, VarLocInMBB &InLocs,
204
- const VarLocMap &VarLocIDs);
229
+ const VarLocMap &VarLocIDs,
230
+ SmallPtrSet<const MachineBasicBlock *, 16 > &Visited);
205
231
206
232
bool ExtendRanges (MachineFunction &MF);
207
233
@@ -228,6 +254,7 @@ class LiveDebugValues : public MachineFunctionPass {
228
254
// / Calculate the liveness information for the given machine function.
229
255
bool runOnMachineFunction (MachineFunction &MF) override ;
230
256
};
257
+
231
258
} // namespace
232
259
233
260
// ===----------------------------------------------------------------------===//
@@ -294,7 +321,7 @@ void LiveDebugValues::transferDebugValue(const MachineInstr &MI,
294
321
// Add the VarLoc to OpenRanges from this DBG_VALUE.
295
322
// TODO: Currently handles DBG_VALUE which has only reg as location.
296
323
if (isDbgValueDescribedByReg (MI)) {
297
- VarLoc VL (MI);
324
+ VarLoc VL (MI, LS );
298
325
unsigned ID = VarLocIDs.insert (VL);
299
326
OpenRanges.insert (ID, VL.Var );
300
327
}
@@ -368,29 +395,48 @@ bool LiveDebugValues::transfer(MachineInstr &MI, OpenRangesSet &OpenRanges,
368
395
// / inserting a new DBG_VALUE instruction at the start of the @MBB - if the same
369
396
// / source variable in all the predecessors of @MBB reside in the same location.
370
397
bool LiveDebugValues::join (MachineBasicBlock &MBB, VarLocInMBB &OutLocs,
371
- VarLocInMBB &InLocs, const VarLocMap &VarLocIDs) {
398
+ VarLocInMBB &InLocs, const VarLocMap &VarLocIDs,
399
+ SmallPtrSet<const MachineBasicBlock *, 16 > &Visited) {
372
400
DEBUG (dbgs () << " join MBB: " << MBB.getName () << " \n " );
373
401
bool Changed = false ;
374
402
375
403
VarLocSet InLocsT; // Temporary incoming locations.
376
404
377
405
// For all predecessors of this MBB, find the set of VarLocs that
378
406
// can be joined.
407
+ int NumVisited = 0 ;
379
408
for (auto p : MBB.predecessors ()) {
409
+ // Ignore unvisited predecessor blocks. As we are processing
410
+ // the blocks in reverse post-order any unvisited block can
411
+ // be considered to not remove any incoming values.
412
+ if (!Visited.count (p))
413
+ continue ;
380
414
auto OL = OutLocs.find (p);
381
415
// Join is null in case of empty OutLocs from any of the pred.
382
416
if (OL == OutLocs.end ())
383
417
return false ;
384
418
385
- // Just copy over the Out locs to incoming locs for the first predecessor.
386
- if (p == *MBB.pred_begin ()) {
419
+ // Just copy over the Out locs to incoming locs for the first visited
420
+ // predecessor, and for all other predecessors join the Out locs.
421
+ if (!NumVisited)
387
422
InLocsT = OL->second ;
388
- continue ;
389
- }
390
- // Join with this predecessor.
391
- InLocsT &= OL->second ;
423
+ else
424
+ InLocsT &= OL->second ;
425
+ NumVisited++;
392
426
}
393
427
428
+ // Filter out DBG_VALUES that are out of scope.
429
+ VarLocSet KillSet;
430
+ for (auto ID : InLocsT)
431
+ if (!VarLocIDs[ID].dominates (MBB))
432
+ KillSet.set (ID);
433
+ InLocsT.intersectWithComplement (KillSet);
434
+
435
+ // As we are processing blocks in reverse post-order we
436
+ // should have processed at least one predecessor, unless it
437
+ // is the entry block which has no predecessor.
438
+ assert ((NumVisited || MBB.pred_empty ()) &&
439
+ " Should have processed at least one predecessor" );
394
440
if (InLocsT.empty ())
395
441
return false ;
396
442
@@ -463,6 +509,7 @@ bool LiveDebugValues::ExtendRanges(MachineFunction &MF) {
463
509
// To solve it, we perform join() and transfer() using the two worklist method
464
510
// until the ranges converge.
465
511
// Ranges have converged when both worklists are empty.
512
+ SmallPtrSet<const MachineBasicBlock *, 16 > Visited;
466
513
while (!Worklist.empty () || !Pending.empty ()) {
467
514
// We track what is on the pending worklist to avoid inserting the same
468
515
// thing twice. We could avoid this with a custom priority queue, but this
@@ -471,8 +518,8 @@ bool LiveDebugValues::ExtendRanges(MachineFunction &MF) {
471
518
while (!Worklist.empty ()) {
472
519
MachineBasicBlock *MBB = OrderToBB[Worklist.top ()];
473
520
Worklist.pop ();
474
- MBBJoined = join (*MBB, OutLocs, InLocs, VarLocIDs);
475
-
521
+ MBBJoined = join (*MBB, OutLocs, InLocs, VarLocIDs, Visited );
522
+ Visited. insert (MBB);
476
523
if (MBBJoined) {
477
524
MBBJoined = false ;
478
525
Changed = true ;
@@ -505,12 +552,14 @@ bool LiveDebugValues::ExtendRanges(MachineFunction &MF) {
505
552
}
506
553
507
554
bool LiveDebugValues::runOnMachineFunction (MachineFunction &MF) {
555
+ if (!MF.getFunction ()->getSubprogram ())
556
+ // LiveDebugValues will already have removed all DBG_VALUEs.
557
+ return false ;
558
+
508
559
TRI = MF.getSubtarget ().getRegisterInfo ();
509
560
TII = MF.getSubtarget ().getInstrInfo ();
561
+ LS.initialize (MF);
510
562
511
- bool Changed = false ;
512
-
513
- Changed |= ExtendRanges (MF);
514
-
563
+ bool Changed = ExtendRanges (MF);
515
564
return Changed;
516
565
}
0 commit comments