forked from llvm/llvm-project
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLiveDebugVariables.cpp
1955 lines (1731 loc) · 73.2 KB
/
LiveDebugVariables.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
//===- LiveDebugVariables.cpp - Tracking debug info variables -------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements the LiveDebugVariables analysis.
//
// Remove all DBG_VALUE instructions referencing virtual registers and replace
// them with a data structure tracking where live user variables are kept - in a
// virtual register or in a stack slot.
//
// Allow the data structure to be updated during register allocation when values
// are moved between registers and stack slots. Finally emit new DBG_VALUE
// instructions after register allocation is complete.
//
//===----------------------------------------------------------------------===//
#include "LiveDebugVariables.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IntervalMap.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/CodeGen/LexicalScopes.h"
#include "llvm/CodeGen/LiveInterval.h"
#include "llvm/CodeGen/LiveIntervals.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/SlotIndexes.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/CodeGen/TargetOpcodes.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/CodeGen/VirtRegMap.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Metadata.h"
#include "llvm/InitializePasses.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Pass.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
#include <algorithm>
#include <cassert>
#include <iterator>
#include <memory>
#include <utility>
using namespace llvm;
#define DEBUG_TYPE "livedebugvars"
static cl::opt<bool>
EnableLDV("live-debug-variables", cl::init(true),
cl::desc("Enable the live debug variables pass"), cl::Hidden);
STATISTIC(NumInsertedDebugValues, "Number of DBG_VALUEs inserted");
STATISTIC(NumInsertedDebugLabels, "Number of DBG_LABELs inserted");
char LiveDebugVariables::ID = 0;
INITIALIZE_PASS_BEGIN(LiveDebugVariables, DEBUG_TYPE,
"Debug Variable Analysis", false, false)
INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
INITIALIZE_PASS_END(LiveDebugVariables, DEBUG_TYPE,
"Debug Variable Analysis", false, false)
void LiveDebugVariables::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<MachineDominatorTree>();
AU.addRequiredTransitive<LiveIntervals>();
AU.setPreservesAll();
MachineFunctionPass::getAnalysisUsage(AU);
}
LiveDebugVariables::LiveDebugVariables() : MachineFunctionPass(ID) {
initializeLiveDebugVariablesPass(*PassRegistry::getPassRegistry());
}
enum : unsigned { UndefLocNo = ~0U };
namespace {
/// Describes a debug variable value by location number and expression along
/// with some flags about the original usage of the location.
class DbgVariableValue {
public:
DbgVariableValue(ArrayRef<unsigned> NewLocs, bool WasIndirect, bool WasList,
const DIExpression &Expr)
: WasIndirect(WasIndirect), WasList(WasList), Expression(&Expr) {
assert(!(WasIndirect && WasList) &&
"DBG_VALUE_LISTs should not be indirect.");
SmallVector<unsigned> LocNoVec;
for (unsigned LocNo : NewLocs) {
auto It = find(LocNoVec, LocNo);
if (It == LocNoVec.end())
LocNoVec.push_back(LocNo);
else {
// Loc duplicates an element in LocNos; replace references to Op
// with references to the duplicating element.
unsigned OpIdx = LocNoVec.size();
unsigned DuplicatingIdx = std::distance(LocNoVec.begin(), It);
Expression =
DIExpression::replaceArg(Expression, OpIdx, DuplicatingIdx);
}
}
// FIXME: Debug values referencing 64+ unique machine locations are rare and
// currently unsupported for performance reasons. If we can verify that
// performance is acceptable for such debug values, we can increase the
// bit-width of LocNoCount to 14 to enable up to 16384 unique machine
// locations. We will also need to verify that this does not cause issues
// with LiveDebugVariables' use of IntervalMap.
if (LocNoVec.size() < 64) {
LocNoCount = LocNoVec.size();
if (LocNoCount > 0) {
LocNos = std::make_unique<unsigned[]>(LocNoCount);
std::copy(LocNoVec.begin(), LocNoVec.end(), loc_nos_begin());
}
} else {
LLVM_DEBUG(dbgs() << "Found debug value with 64+ unique machine "
"locations, dropping...\n");
LocNoCount = 1;
// Turn this into an undef debug value list; right now, the simplest form
// of this is an expression with one arg, and an undef debug operand.
Expression =
DIExpression::get(Expr.getContext(), {dwarf::DW_OP_LLVM_arg, 0,
dwarf::DW_OP_stack_value});
if (auto FragmentInfoOpt = Expr.getFragmentInfo())
Expression = *DIExpression::createFragmentExpression(
Expression, FragmentInfoOpt->OffsetInBits,
FragmentInfoOpt->SizeInBits);
LocNos = std::make_unique<unsigned[]>(LocNoCount);
LocNos[0] = UndefLocNo;
}
}
DbgVariableValue() : LocNoCount(0), WasIndirect(false), WasList(false) {}
DbgVariableValue(const DbgVariableValue &Other)
: LocNoCount(Other.LocNoCount), WasIndirect(Other.getWasIndirect()),
WasList(Other.getWasList()), Expression(Other.getExpression()) {
if (Other.getLocNoCount()) {
LocNos.reset(new unsigned[Other.getLocNoCount()]);
std::copy(Other.loc_nos_begin(), Other.loc_nos_end(), loc_nos_begin());
}
}
DbgVariableValue &operator=(const DbgVariableValue &Other) {
if (this == &Other)
return *this;
if (Other.getLocNoCount()) {
LocNos.reset(new unsigned[Other.getLocNoCount()]);
std::copy(Other.loc_nos_begin(), Other.loc_nos_end(), loc_nos_begin());
} else {
LocNos.release();
}
LocNoCount = Other.getLocNoCount();
WasIndirect = Other.getWasIndirect();
WasList = Other.getWasList();
Expression = Other.getExpression();
return *this;
}
const DIExpression *getExpression() const { return Expression; }
uint8_t getLocNoCount() const { return LocNoCount; }
bool containsLocNo(unsigned LocNo) const {
return is_contained(loc_nos(), LocNo);
}
bool getWasIndirect() const { return WasIndirect; }
bool getWasList() const { return WasList; }
bool isUndef() const { return LocNoCount == 0 || containsLocNo(UndefLocNo); }
DbgVariableValue decrementLocNosAfterPivot(unsigned Pivot) const {
SmallVector<unsigned, 4> NewLocNos;
for (unsigned LocNo : loc_nos())
NewLocNos.push_back(LocNo != UndefLocNo && LocNo > Pivot ? LocNo - 1
: LocNo);
return DbgVariableValue(NewLocNos, WasIndirect, WasList, *Expression);
}
DbgVariableValue remapLocNos(ArrayRef<unsigned> LocNoMap) const {
SmallVector<unsigned> NewLocNos;
for (unsigned LocNo : loc_nos())
// Undef values don't exist in locations (and thus not in LocNoMap
// either) so skip over them. See getLocationNo().
NewLocNos.push_back(LocNo == UndefLocNo ? UndefLocNo : LocNoMap[LocNo]);
return DbgVariableValue(NewLocNos, WasIndirect, WasList, *Expression);
}
DbgVariableValue changeLocNo(unsigned OldLocNo, unsigned NewLocNo) const {
SmallVector<unsigned> NewLocNos;
NewLocNos.assign(loc_nos_begin(), loc_nos_end());
auto OldLocIt = find(NewLocNos, OldLocNo);
assert(OldLocIt != NewLocNos.end() && "Old location must be present.");
*OldLocIt = NewLocNo;
return DbgVariableValue(NewLocNos, WasIndirect, WasList, *Expression);
}
bool hasLocNoGreaterThan(unsigned LocNo) const {
return any_of(loc_nos(),
[LocNo](unsigned ThisLocNo) { return ThisLocNo > LocNo; });
}
void printLocNos(llvm::raw_ostream &OS) const {
for (const unsigned &Loc : loc_nos())
OS << (&Loc == loc_nos_begin() ? " " : ", ") << Loc;
}
friend inline bool operator==(const DbgVariableValue &LHS,
const DbgVariableValue &RHS) {
if (std::tie(LHS.LocNoCount, LHS.WasIndirect, LHS.WasList,
LHS.Expression) !=
std::tie(RHS.LocNoCount, RHS.WasIndirect, RHS.WasList, RHS.Expression))
return false;
return std::equal(LHS.loc_nos_begin(), LHS.loc_nos_end(),
RHS.loc_nos_begin());
}
friend inline bool operator!=(const DbgVariableValue &LHS,
const DbgVariableValue &RHS) {
return !(LHS == RHS);
}
unsigned *loc_nos_begin() { return LocNos.get(); }
const unsigned *loc_nos_begin() const { return LocNos.get(); }
unsigned *loc_nos_end() { return LocNos.get() + LocNoCount; }
const unsigned *loc_nos_end() const { return LocNos.get() + LocNoCount; }
ArrayRef<unsigned> loc_nos() const {
return ArrayRef<unsigned>(LocNos.get(), LocNoCount);
}
private:
// IntervalMap requires the value object to be very small, to the extent
// that we do not have enough room for an std::vector. Using a C-style array
// (with a unique_ptr wrapper for convenience) allows us to optimize for this
// specific case by packing the array size into only 6 bits (it is highly
// unlikely that any debug value will need 64+ locations).
std::unique_ptr<unsigned[]> LocNos;
uint8_t LocNoCount : 6;
bool WasIndirect : 1;
bool WasList : 1;
const DIExpression *Expression = nullptr;
};
} // namespace
/// Map of where a user value is live to that value.
using LocMap = IntervalMap<SlotIndex, DbgVariableValue, 4>;
/// Map of stack slot offsets for spilled locations.
/// Non-spilled locations are not added to the map.
using SpillOffsetMap = DenseMap<unsigned, unsigned>;
/// Cache to save the location where it can be used as the starting
/// position as input for calling MachineBasicBlock::SkipPHIsLabelsAndDebug.
/// This is to prevent MachineBasicBlock::SkipPHIsLabelsAndDebug from
/// repeatedly searching the same set of PHIs/Labels/Debug instructions
/// if it is called many times for the same block.
using BlockSkipInstsMap =
DenseMap<MachineBasicBlock *, MachineBasicBlock::iterator>;
namespace {
class LDVImpl;
/// A user value is a part of a debug info user variable.
///
/// A DBG_VALUE instruction notes that (a sub-register of) a virtual register
/// holds part of a user variable. The part is identified by a byte offset.
///
/// UserValues are grouped into equivalence classes for easier searching. Two
/// user values are related if they are held by the same virtual register. The
/// equivalence class is the transitive closure of that relation.
class UserValue {
const DILocalVariable *Variable; ///< The debug info variable we are part of.
/// The part of the variable we describe.
const Optional<DIExpression::FragmentInfo> Fragment;
DebugLoc dl; ///< The debug location for the variable. This is
///< used by dwarf writer to find lexical scope.
UserValue *leader; ///< Equivalence class leader.
UserValue *next = nullptr; ///< Next value in equivalence class, or null.
/// Numbered locations referenced by locmap.
SmallVector<MachineOperand, 4> locations;
/// Map of slot indices where this value is live.
LocMap locInts;
/// Set of interval start indexes that have been trimmed to the
/// lexical scope.
SmallSet<SlotIndex, 2> trimmedDefs;
/// Insert a DBG_VALUE into MBB at Idx for DbgValue.
void insertDebugValue(MachineBasicBlock *MBB, SlotIndex StartIdx,
SlotIndex StopIdx, DbgVariableValue DbgValue,
ArrayRef<bool> LocSpills,
ArrayRef<unsigned> SpillOffsets, LiveIntervals &LIS,
const TargetInstrInfo &TII,
const TargetRegisterInfo &TRI,
BlockSkipInstsMap &BBSkipInstsMap);
/// Replace OldLocNo ranges with NewRegs ranges where NewRegs
/// is live. Returns true if any changes were made.
bool splitLocation(unsigned OldLocNo, ArrayRef<Register> NewRegs,
LiveIntervals &LIS);
public:
/// Create a new UserValue.
UserValue(const DILocalVariable *var,
Optional<DIExpression::FragmentInfo> Fragment, DebugLoc L,
LocMap::Allocator &alloc)
: Variable(var), Fragment(Fragment), dl(std::move(L)), leader(this),
locInts(alloc) {}
/// Get the leader of this value's equivalence class.
UserValue *getLeader() {
UserValue *l = leader;
while (l != l->leader)
l = l->leader;
return leader = l;
}
/// Return the next UserValue in the equivalence class.
UserValue *getNext() const { return next; }
/// Merge equivalence classes.
static UserValue *merge(UserValue *L1, UserValue *L2) {
L2 = L2->getLeader();
if (!L1)
return L2;
L1 = L1->getLeader();
if (L1 == L2)
return L1;
// Splice L2 before L1's members.
UserValue *End = L2;
while (End->next) {
End->leader = L1;
End = End->next;
}
End->leader = L1;
End->next = L1->next;
L1->next = L2;
return L1;
}
/// Return the location number that matches Loc.
///
/// For undef values we always return location number UndefLocNo without
/// inserting anything in locations. Since locations is a vector and the
/// location number is the position in the vector and UndefLocNo is ~0,
/// we would need a very big vector to put the value at the right position.
unsigned getLocationNo(const MachineOperand &LocMO) {
if (LocMO.isReg()) {
if (LocMO.getReg() == 0)
return UndefLocNo;
// For register locations we dont care about use/def and other flags.
for (unsigned i = 0, e = locations.size(); i != e; ++i)
if (locations[i].isReg() &&
locations[i].getReg() == LocMO.getReg() &&
locations[i].getSubReg() == LocMO.getSubReg())
return i;
} else
for (unsigned i = 0, e = locations.size(); i != e; ++i)
if (LocMO.isIdenticalTo(locations[i]))
return i;
locations.push_back(LocMO);
// We are storing a MachineOperand outside a MachineInstr.
locations.back().clearParent();
// Don't store def operands.
if (locations.back().isReg()) {
if (locations.back().isDef())
locations.back().setIsDead(false);
locations.back().setIsUse();
}
return locations.size() - 1;
}
/// Remove (recycle) a location number. If \p LocNo still is used by the
/// locInts nothing is done.
void removeLocationIfUnused(unsigned LocNo) {
// Bail out if LocNo still is used.
for (LocMap::const_iterator I = locInts.begin(); I.valid(); ++I) {
const DbgVariableValue &DbgValue = I.value();
if (DbgValue.containsLocNo(LocNo))
return;
}
// Remove the entry in the locations vector, and adjust all references to
// location numbers above the removed entry.
locations.erase(locations.begin() + LocNo);
for (LocMap::iterator I = locInts.begin(); I.valid(); ++I) {
const DbgVariableValue &DbgValue = I.value();
if (DbgValue.hasLocNoGreaterThan(LocNo))
I.setValueUnchecked(DbgValue.decrementLocNosAfterPivot(LocNo));
}
}
/// Ensure that all virtual register locations are mapped.
void mapVirtRegs(LDVImpl *LDV);
/// Add a definition point to this user value.
void addDef(SlotIndex Idx, ArrayRef<MachineOperand> LocMOs, bool IsIndirect,
bool IsList, const DIExpression &Expr) {
SmallVector<unsigned> Locs;
for (const MachineOperand &Op : LocMOs)
Locs.push_back(getLocationNo(Op));
DbgVariableValue DbgValue(Locs, IsIndirect, IsList, Expr);
// Add a singular (Idx,Idx) -> value mapping.
LocMap::iterator I = locInts.find(Idx);
if (!I.valid() || I.start() != Idx)
I.insert(Idx, Idx.getNextSlot(), std::move(DbgValue));
else
// A later DBG_VALUE at the same SlotIndex overrides the old location.
I.setValue(std::move(DbgValue));
}
/// Extend the current definition as far as possible down.
///
/// Stop when meeting an existing def or when leaving the live
/// range of VNI. End points where VNI is no longer live are added to Kills.
///
/// We only propagate DBG_VALUES locally here. LiveDebugValues performs a
/// data-flow analysis to propagate them beyond basic block boundaries.
///
/// \param Idx Starting point for the definition.
/// \param DbgValue value to propagate.
/// \param LiveIntervalInfo For each location number key in this map,
/// restricts liveness to where the LiveRange has the value equal to the\
/// VNInfo.
/// \param [out] Kills Append end points of VNI's live range to Kills.
/// \param LIS Live intervals analysis.
void extendDef(SlotIndex Idx, DbgVariableValue DbgValue,
SmallDenseMap<unsigned, std::pair<LiveRange *, const VNInfo *>>
&LiveIntervalInfo,
Optional<std::pair<SlotIndex, SmallVector<unsigned>>> &Kills,
LiveIntervals &LIS);
/// The value in LI may be copies to other registers. Determine if
/// any of the copies are available at the kill points, and add defs if
/// possible.
///
/// \param DbgValue Location number of LI->reg, and DIExpression.
/// \param LocIntervals Scan for copies of the value for each location in the
/// corresponding LiveInterval->reg.
/// \param KilledAt The point where the range of DbgValue could be extended.
/// \param [in,out] NewDefs Append (Idx, DbgValue) of inserted defs here.
void addDefsFromCopies(
DbgVariableValue DbgValue,
SmallVectorImpl<std::pair<unsigned, LiveInterval *>> &LocIntervals,
SlotIndex KilledAt,
SmallVectorImpl<std::pair<SlotIndex, DbgVariableValue>> &NewDefs,
MachineRegisterInfo &MRI, LiveIntervals &LIS);
/// Compute the live intervals of all locations after collecting all their
/// def points.
void computeIntervals(MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI,
LiveIntervals &LIS, LexicalScopes &LS);
/// Replace OldReg ranges with NewRegs ranges where NewRegs is
/// live. Returns true if any changes were made.
bool splitRegister(Register OldReg, ArrayRef<Register> NewRegs,
LiveIntervals &LIS);
/// Rewrite virtual register locations according to the provided virtual
/// register map. Record the stack slot offsets for the locations that
/// were spilled.
void rewriteLocations(VirtRegMap &VRM, const MachineFunction &MF,
const TargetInstrInfo &TII,
const TargetRegisterInfo &TRI,
SpillOffsetMap &SpillOffsets);
/// Recreate DBG_VALUE instruction from data structures.
void emitDebugValues(VirtRegMap *VRM, LiveIntervals &LIS,
const TargetInstrInfo &TII,
const TargetRegisterInfo &TRI,
const SpillOffsetMap &SpillOffsets,
BlockSkipInstsMap &BBSkipInstsMap);
/// Return DebugLoc of this UserValue.
const DebugLoc &getDebugLoc() { return dl; }
void print(raw_ostream &, const TargetRegisterInfo *);
};
/// A user label is a part of a debug info user label.
class UserLabel {
const DILabel *Label; ///< The debug info label we are part of.
DebugLoc dl; ///< The debug location for the label. This is
///< used by dwarf writer to find lexical scope.
SlotIndex loc; ///< Slot used by the debug label.
/// Insert a DBG_LABEL into MBB at Idx.
void insertDebugLabel(MachineBasicBlock *MBB, SlotIndex Idx,
LiveIntervals &LIS, const TargetInstrInfo &TII,
BlockSkipInstsMap &BBSkipInstsMap);
public:
/// Create a new UserLabel.
UserLabel(const DILabel *label, DebugLoc L, SlotIndex Idx)
: Label(label), dl(std::move(L)), loc(Idx) {}
/// Does this UserLabel match the parameters?
bool matches(const DILabel *L, const DILocation *IA,
const SlotIndex Index) const {
return Label == L && dl->getInlinedAt() == IA && loc == Index;
}
/// Recreate DBG_LABEL instruction from data structures.
void emitDebugLabel(LiveIntervals &LIS, const TargetInstrInfo &TII,
BlockSkipInstsMap &BBSkipInstsMap);
/// Return DebugLoc of this UserLabel.
const DebugLoc &getDebugLoc() { return dl; }
void print(raw_ostream &, const TargetRegisterInfo *);
};
/// Implementation of the LiveDebugVariables pass.
class LDVImpl {
LiveDebugVariables &pass;
LocMap::Allocator allocator;
MachineFunction *MF = nullptr;
LiveIntervals *LIS;
const TargetRegisterInfo *TRI;
/// Position and VReg of a PHI instruction during register allocation.
struct PHIValPos {
SlotIndex SI; /// Slot where this PHI occurs.
Register Reg; /// VReg this PHI occurs in.
unsigned SubReg; /// Qualifiying subregister for Reg.
};
/// Map from debug instruction number to PHI position during allocation.
std::map<unsigned, PHIValPos> PHIValToPos;
/// Index of, for each VReg, which debug instruction numbers and corresponding
/// PHIs are sensitive to splitting. Each VReg may have multiple PHI defs,
/// at different positions.
DenseMap<Register, std::vector<unsigned>> RegToPHIIdx;
/// Record for any debug instructions unlinked from their blocks during
/// regalloc. Stores the instr and it's location, so that they can be
/// re-inserted after regalloc is over.
struct InstrPos {
MachineInstr *MI; ///< Debug instruction, unlinked from it's block.
SlotIndex Idx; ///< Slot position where MI should be re-inserted.
MachineBasicBlock *MBB; ///< Block that MI was in.
};
/// Collection of stored debug instructions, preserved until after regalloc.
SmallVector<InstrPos, 32> StashedDebugInstrs;
/// Whether emitDebugValues is called.
bool EmitDone = false;
/// Whether the machine function is modified during the pass.
bool ModifiedMF = false;
/// All allocated UserValue instances.
SmallVector<std::unique_ptr<UserValue>, 8> userValues;
/// All allocated UserLabel instances.
SmallVector<std::unique_ptr<UserLabel>, 2> userLabels;
/// Map virtual register to eq class leader.
using VRMap = DenseMap<unsigned, UserValue *>;
VRMap virtRegToEqClass;
/// Map to find existing UserValue instances.
using UVMap = DenseMap<DebugVariable, UserValue *>;
UVMap userVarMap;
/// Find or create a UserValue.
UserValue *getUserValue(const DILocalVariable *Var,
Optional<DIExpression::FragmentInfo> Fragment,
const DebugLoc &DL);
/// Find the EC leader for VirtReg or null.
UserValue *lookupVirtReg(Register VirtReg);
/// Add DBG_VALUE instruction to our maps.
///
/// \param MI DBG_VALUE instruction
/// \param Idx Last valid SLotIndex before instruction.
///
/// \returns True if the DBG_VALUE instruction should be deleted.
bool handleDebugValue(MachineInstr &MI, SlotIndex Idx);
/// Track variable location debug instructions while using the instruction
/// referencing implementation. Such debug instructions do not need to be
/// updated during regalloc because they identify instructions rather than
/// register locations. However, they needs to be removed from the
/// MachineFunction during regalloc, then re-inserted later, to avoid
/// disrupting the allocator.
///
/// \param MI Any DBG_VALUE / DBG_INSTR_REF / DBG_PHI instruction
/// \param Idx Last valid SlotIndex before instruction
///
/// \returns Iterator to continue processing from after unlinking.
MachineBasicBlock::iterator handleDebugInstr(MachineInstr &MI, SlotIndex Idx);
/// Add DBG_LABEL instruction to UserLabel.
///
/// \param MI DBG_LABEL instruction
/// \param Idx Last valid SlotIndex before instruction.
///
/// \returns True if the DBG_LABEL instruction should be deleted.
bool handleDebugLabel(MachineInstr &MI, SlotIndex Idx);
/// Collect and erase all DBG_VALUE instructions, adding a UserValue def
/// for each instruction.
///
/// \param mf MachineFunction to be scanned.
/// \param InstrRef Whether to operate in instruction referencing mode. If
/// true, most of LiveDebugVariables doesn't run.
///
/// \returns True if any debug values were found.
bool collectDebugValues(MachineFunction &mf, bool InstrRef);
/// Compute the live intervals of all user values after collecting all
/// their def points.
void computeIntervals();
public:
LDVImpl(LiveDebugVariables *ps) : pass(*ps) {}
bool runOnMachineFunction(MachineFunction &mf, bool InstrRef);
/// Release all memory.
void clear() {
MF = nullptr;
PHIValToPos.clear();
RegToPHIIdx.clear();
StashedDebugInstrs.clear();
userValues.clear();
userLabels.clear();
virtRegToEqClass.clear();
userVarMap.clear();
// Make sure we call emitDebugValues if the machine function was modified.
assert((!ModifiedMF || EmitDone) &&
"Dbg values are not emitted in LDV");
EmitDone = false;
ModifiedMF = false;
}
/// Map virtual register to an equivalence class.
void mapVirtReg(Register VirtReg, UserValue *EC);
/// Replace any PHI referring to OldReg with its corresponding NewReg, if
/// present.
void splitPHIRegister(Register OldReg, ArrayRef<Register> NewRegs);
/// Replace all references to OldReg with NewRegs.
void splitRegister(Register OldReg, ArrayRef<Register> NewRegs);
/// Recreate DBG_VALUE instruction from data structures.
void emitDebugValues(VirtRegMap *VRM);
void print(raw_ostream&);
};
} // end anonymous namespace
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
static void printDebugLoc(const DebugLoc &DL, raw_ostream &CommentOS,
const LLVMContext &Ctx) {
if (!DL)
return;
auto *Scope = cast<DIScope>(DL.getScope());
// Omit the directory, because it's likely to be long and uninteresting.
CommentOS << Scope->getFilename();
CommentOS << ':' << DL.getLine();
if (DL.getCol() != 0)
CommentOS << ':' << DL.getCol();
DebugLoc InlinedAtDL = DL.getInlinedAt();
if (!InlinedAtDL)
return;
CommentOS << " @[ ";
printDebugLoc(InlinedAtDL, CommentOS, Ctx);
CommentOS << " ]";
}
static void printExtendedName(raw_ostream &OS, const DINode *Node,
const DILocation *DL) {
const LLVMContext &Ctx = Node->getContext();
StringRef Res;
unsigned Line = 0;
if (const auto *V = dyn_cast<const DILocalVariable>(Node)) {
Res = V->getName();
Line = V->getLine();
} else if (const auto *L = dyn_cast<const DILabel>(Node)) {
Res = L->getName();
Line = L->getLine();
}
if (!Res.empty())
OS << Res << "," << Line;
auto *InlinedAt = DL ? DL->getInlinedAt() : nullptr;
if (InlinedAt) {
if (DebugLoc InlinedAtDL = InlinedAt) {
OS << " @[";
printDebugLoc(InlinedAtDL, OS, Ctx);
OS << "]";
}
}
}
void UserValue::print(raw_ostream &OS, const TargetRegisterInfo *TRI) {
OS << "!\"";
printExtendedName(OS, Variable, dl);
OS << "\"\t";
for (LocMap::const_iterator I = locInts.begin(); I.valid(); ++I) {
OS << " [" << I.start() << ';' << I.stop() << "):";
if (I.value().isUndef())
OS << " undef";
else {
I.value().printLocNos(OS);
if (I.value().getWasIndirect())
OS << " ind";
else if (I.value().getWasList())
OS << " list";
}
}
for (unsigned i = 0, e = locations.size(); i != e; ++i) {
OS << " Loc" << i << '=';
locations[i].print(OS, TRI);
}
OS << '\n';
}
void UserLabel::print(raw_ostream &OS, const TargetRegisterInfo *TRI) {
OS << "!\"";
printExtendedName(OS, Label, dl);
OS << "\"\t";
OS << loc;
OS << '\n';
}
void LDVImpl::print(raw_ostream &OS) {
OS << "********** DEBUG VARIABLES **********\n";
for (auto &userValue : userValues)
userValue->print(OS, TRI);
OS << "********** DEBUG LABELS **********\n";
for (auto &userLabel : userLabels)
userLabel->print(OS, TRI);
}
#endif
void UserValue::mapVirtRegs(LDVImpl *LDV) {
for (unsigned i = 0, e = locations.size(); i != e; ++i)
if (locations[i].isReg() &&
Register::isVirtualRegister(locations[i].getReg()))
LDV->mapVirtReg(locations[i].getReg(), this);
}
UserValue *LDVImpl::getUserValue(const DILocalVariable *Var,
Optional<DIExpression::FragmentInfo> Fragment,
const DebugLoc &DL) {
// FIXME: Handle partially overlapping fragments. See
// https://reviews.llvm.org/D70121#1849741.
DebugVariable ID(Var, Fragment, DL->getInlinedAt());
UserValue *&UV = userVarMap[ID];
if (!UV) {
userValues.push_back(
std::make_unique<UserValue>(Var, Fragment, DL, allocator));
UV = userValues.back().get();
}
return UV;
}
void LDVImpl::mapVirtReg(Register VirtReg, UserValue *EC) {
assert(Register::isVirtualRegister(VirtReg) && "Only map VirtRegs");
UserValue *&Leader = virtRegToEqClass[VirtReg];
Leader = UserValue::merge(Leader, EC);
}
UserValue *LDVImpl::lookupVirtReg(Register VirtReg) {
if (UserValue *UV = virtRegToEqClass.lookup(VirtReg))
return UV->getLeader();
return nullptr;
}
bool LDVImpl::handleDebugValue(MachineInstr &MI, SlotIndex Idx) {
// DBG_VALUE loc, offset, variable, expr
// DBG_VALUE_LIST variable, expr, locs...
if (!MI.isDebugValue()) {
LLVM_DEBUG(dbgs() << "Can't handle non-DBG_VALUE*: " << MI);
return false;
}
if (!MI.getDebugVariableOp().isMetadata()) {
LLVM_DEBUG(dbgs() << "Can't handle DBG_VALUE* with invalid variable: "
<< MI);
return false;
}
if (MI.isNonListDebugValue() &&
(MI.getNumOperands() != 4 ||
!(MI.getDebugOffset().isImm() || MI.getDebugOffset().isReg()))) {
LLVM_DEBUG(dbgs() << "Can't handle malformed DBG_VALUE: " << MI);
return false;
}
// Detect invalid DBG_VALUE instructions, with a debug-use of a virtual
// register that hasn't been defined yet. If we do not remove those here, then
// the re-insertion of the DBG_VALUE instruction after register allocation
// will be incorrect.
bool Discard = false;
for (const MachineOperand &Op : MI.debug_operands()) {
if (Op.isReg() && Register::isVirtualRegister(Op.getReg())) {
const Register Reg = Op.getReg();
if (!LIS->hasInterval(Reg)) {
// The DBG_VALUE is described by a virtual register that does not have a
// live interval. Discard the DBG_VALUE.
Discard = true;
LLVM_DEBUG(dbgs() << "Discarding debug info (no LIS interval): " << Idx
<< " " << MI);
} else {
// The DBG_VALUE is only valid if either Reg is live out from Idx, or
// Reg is defined dead at Idx (where Idx is the slot index for the
// instruction preceding the DBG_VALUE).
const LiveInterval &LI = LIS->getInterval(Reg);
LiveQueryResult LRQ = LI.Query(Idx);
if (!LRQ.valueOutOrDead()) {
// We have found a DBG_VALUE with the value in a virtual register that
// is not live. Discard the DBG_VALUE.
Discard = true;
LLVM_DEBUG(dbgs() << "Discarding debug info (reg not live): " << Idx
<< " " << MI);
}
}
}
}
// Get or create the UserValue for (variable,offset) here.
bool IsIndirect = MI.isDebugOffsetImm();
if (IsIndirect)
assert(MI.getDebugOffset().getImm() == 0 &&
"DBG_VALUE with nonzero offset");
bool IsList = MI.isDebugValueList();
const DILocalVariable *Var = MI.getDebugVariable();
const DIExpression *Expr = MI.getDebugExpression();
UserValue *UV = getUserValue(Var, Expr->getFragmentInfo(), MI.getDebugLoc());
if (!Discard)
UV->addDef(Idx,
ArrayRef<MachineOperand>(MI.debug_operands().begin(),
MI.debug_operands().end()),
IsIndirect, IsList, *Expr);
else {
MachineOperand MO = MachineOperand::CreateReg(0U, false);
MO.setIsDebug();
// We should still pass a list the same size as MI.debug_operands() even if
// all MOs are undef, so that DbgVariableValue can correctly adjust the
// expression while removing the duplicated undefs.
SmallVector<MachineOperand, 4> UndefMOs(MI.getNumDebugOperands(), MO);
UV->addDef(Idx, UndefMOs, false, IsList, *Expr);
}
return true;
}
MachineBasicBlock::iterator LDVImpl::handleDebugInstr(MachineInstr &MI,
SlotIndex Idx) {
assert(MI.isDebugValue() || MI.isDebugRef() || MI.isDebugPHI());
// In instruction referencing mode, there should be no DBG_VALUE instructions
// that refer to virtual registers. They might still refer to constants.
if (MI.isDebugValue())
assert(!MI.getOperand(0).isReg() || !MI.getOperand(0).getReg().isVirtual());
// Unlink the instruction, store it in the debug instructions collection.
auto NextInst = std::next(MI.getIterator());
auto *MBB = MI.getParent();
MI.removeFromParent();
StashedDebugInstrs.push_back({&MI, Idx, MBB});
return NextInst;
}
bool LDVImpl::handleDebugLabel(MachineInstr &MI, SlotIndex Idx) {
// DBG_LABEL label
if (MI.getNumOperands() != 1 || !MI.getOperand(0).isMetadata()) {
LLVM_DEBUG(dbgs() << "Can't handle " << MI);
return false;
}
// Get or create the UserLabel for label here.
const DILabel *Label = MI.getDebugLabel();
const DebugLoc &DL = MI.getDebugLoc();
bool Found = false;
for (auto const &L : userLabels) {
if (L->matches(Label, DL->getInlinedAt(), Idx)) {
Found = true;
break;
}
}
if (!Found)
userLabels.push_back(std::make_unique<UserLabel>(Label, DL, Idx));
return true;
}
bool LDVImpl::collectDebugValues(MachineFunction &mf, bool InstrRef) {
bool Changed = false;
for (MachineBasicBlock &MBB : mf) {
for (MachineBasicBlock::iterator MBBI = MBB.begin(), MBBE = MBB.end();
MBBI != MBBE;) {
// Use the first debug instruction in the sequence to get a SlotIndex
// for following consecutive debug instructions.
if (!MBBI->isDebugOrPseudoInstr()) {
++MBBI;
continue;
}
// Debug instructions has no slot index. Use the previous
// non-debug instruction's SlotIndex as its SlotIndex.
SlotIndex Idx =
MBBI == MBB.begin()
? LIS->getMBBStartIdx(&MBB)
: LIS->getInstructionIndex(*std::prev(MBBI)).getRegSlot();
// Handle consecutive debug instructions with the same slot index.
do {
// In instruction referencing mode, pass each instr to handleDebugInstr
// to be unlinked. Ignore DBG_VALUE_LISTs -- they refer to vregs, and
// need to go through the normal live interval splitting process.
if (InstrRef && (MBBI->isNonListDebugValue() || MBBI->isDebugPHI() ||
MBBI->isDebugRef())) {
MBBI = handleDebugInstr(*MBBI, Idx);
Changed = true;
// In normal debug mode, use the dedicated DBG_VALUE / DBG_LABEL handler
// to track things through register allocation, and erase the instr.
} else if ((MBBI->isDebugValue() && handleDebugValue(*MBBI, Idx)) ||
(MBBI->isDebugLabel() && handleDebugLabel(*MBBI, Idx))) {
MBBI = MBB.erase(MBBI);
Changed = true;
} else
++MBBI;
} while (MBBI != MBBE && MBBI->isDebugOrPseudoInstr());
}
}
return Changed;
}
void UserValue::extendDef(
SlotIndex Idx, DbgVariableValue DbgValue,
SmallDenseMap<unsigned, std::pair<LiveRange *, const VNInfo *>>
&LiveIntervalInfo,
Optional<std::pair<SlotIndex, SmallVector<unsigned>>> &Kills,
LiveIntervals &LIS) {
SlotIndex Start = Idx;
MachineBasicBlock *MBB = LIS.getMBBFromIndex(Start);
SlotIndex Stop = LIS.getMBBEndIdx(MBB);
LocMap::iterator I = locInts.find(Start);
// Limit to the intersection of the VNIs' live ranges.
for (auto &LII : LiveIntervalInfo) {
LiveRange *LR = LII.second.first;
assert(LR && LII.second.second && "Missing range info for Idx.");
LiveInterval::Segment *Segment = LR->getSegmentContaining(Start);
assert(Segment && Segment->valno == LII.second.second &&
"Invalid VNInfo for Idx given?");
if (Segment->end < Stop) {
Stop = Segment->end;
Kills = {Stop, {LII.first}};
} else if (Segment->end == Stop && Kills.hasValue()) {
// If multiple locations end at the same place, track all of them in
// Kills.
Kills->second.push_back(LII.first);
}
}
// There could already be a short def at Start.
if (I.valid() && I.start() <= Start) {
// Stop when meeting a different location or an already extended interval.
Start = Start.getNextSlot();
if (I.value() != DbgValue || I.stop() != Start) {
// Clear `Kills`, as we have a new def available.
Kills = None;
return;
}
// This is a one-slot placeholder. Just skip it.
++I;
}
// Limited by the next def.