LLVM 24.0.0git
InstrRefBasedImpl.h
Go to the documentation of this file.
1//===- InstrRefBasedImpl.h - Tracking Debug Value MIs ---------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_LIB_CODEGEN_LIVEDEBUGVALUES_INSTRREFBASEDLDV_H
10#define LLVM_LIB_CODEGEN_LIVEDEBUGVALUES_INSTRREFBASEDLDV_H
11
12#include "llvm/ADT/DenseMap.h"
13#include "llvm/ADT/IndexedMap.h"
23#include <optional>
24
25#include "LiveDebugValues.h"
26
27class TransferTracker;
28
29// Forward dec of unit test class, so that we can peer into the LDV object.
30class InstrRefLDVTest;
31
32namespace LiveDebugValues {
33
34class MLocTracker;
35class DbgOpIDMap;
36
37using namespace llvm;
38
40using VarAndLoc = std::pair<DebugVariable, const DILocation *>;
41
42/// Mapping from DebugVariable to/from a unique identifying number. Each
43/// DebugVariable consists of three pointers, and after a small amount of
44/// work to identify overlapping fragments of variables we mostly only use
45/// DebugVariables as identities of variables. It's much more compile-time
46/// efficient to use an ID number instead, which this class provides.
50
51public:
53 auto It = VarToIdx.find(Var);
54 assert(It != VarToIdx.end());
55 return It->second;
56 }
57
59 unsigned Size = VarToIdx.size();
60 auto ItPair = VarToIdx.insert({Var, Size});
61 if (ItPair.second) {
62 IdxToVar.push_back({Var, Loc});
63 return Size;
64 }
65
66 return ItPair.first->second;
67 }
68
69 const VarAndLoc &lookupDVID(DebugVariableID ID) const { return IdxToVar[ID]; }
70
71 void clear() {
72 VarToIdx.clear();
73 IdxToVar.clear();
74 }
75};
76
77/// Handle-class for a particular "location". This value-type uniquely
78/// symbolises a register or stack location, allowing manipulation of locations
79/// without concern for where that location is. Practically, this allows us to
80/// treat the state of the machine at a particular point as an array of values,
81/// rather than a map of values.
82class LocIdx {
83 unsigned Location;
84
85 // Default constructor is private, initializing to an illegal location number.
86 // Use only for "not an entry" elements in IndexedMaps.
87 LocIdx() : Location(UINT_MAX) {}
88
89public:
90#define NUM_LOC_BITS 24
91 LocIdx(unsigned L) : Location(L) {
92 assert(L < (1 << NUM_LOC_BITS) && "Machine locations must fit in 24 bits");
93 }
94
95 static LocIdx MakeIllegalLoc() { return LocIdx(); }
96
97 bool isIllegal() const { return Location == UINT_MAX; }
98
99 uint64_t asU64() const { return Location; }
100
101 bool operator==(unsigned L) const { return Location == L; }
102
103 bool operator==(const LocIdx &L) const { return Location == L.Location; }
104
105 bool operator!=(unsigned L) const { return !(*this == L); }
106
107 bool operator!=(const LocIdx &L) const { return !(*this == L); }
108
109 bool operator<(const LocIdx &Other) const {
110 return Location < Other.Location;
111 }
112};
113
114// The location at which a spilled value resides. It consists of a register and
115// an offset.
116struct SpillLoc {
117 unsigned SpillBase;
119 bool operator==(const SpillLoc &Other) const {
120 return std::make_pair(SpillBase, SpillOffset) ==
121 std::make_pair(Other.SpillBase, Other.SpillOffset);
122 }
123 bool operator<(const SpillLoc &Other) const {
124 return std::make_tuple(SpillBase, SpillOffset.getFixed(),
125 SpillOffset.getScalable()) <
126 std::make_tuple(Other.SpillBase, Other.SpillOffset.getFixed(),
127 Other.SpillOffset.getScalable());
128 }
129};
130
131/// Unique identifier for a value defined by an instruction, as a value type.
132/// Casts back and forth to a uint64_t. Probably replacable with something less
133/// bit-constrained. Each value identifies the instruction and machine location
134/// where the value is defined, although there may be no corresponding machine
135/// operand for it (ex: regmasks clobbering values). The instructions are
136/// one-based, and definitions that are PHIs have instruction number zero.
137///
138/// The obvious limits of a 1M block function or 1M instruction blocks are
139/// problematic; but by that point we should probably have bailed out of
140/// trying to analyse the function.
142 union {
143 struct {
144 uint64_t BlockNo : 20; /// The block where the def happens.
145 uint64_t InstNo : 20; /// The Instruction where the def happens.
146 /// One based, is distance from start of block.
148 : NUM_LOC_BITS; /// The machine location where the def happens.
149 } s;
151 } u;
152
153 static_assert(sizeof(u) == 8, "Badly packed ValueIDNum?");
154
155public:
156 // Default-initialize to EmptyValue. This is necessary to make IndexedMaps
157 // of values to work.
158 ValueIDNum() { u.Value = EmptyValue.asU64(); }
159
161 u.s = {Block, Inst, Loc};
162 }
163
165 u.s = {Block, Inst, Loc.asU64()};
166 }
167
168 uint64_t getBlock() const { return u.s.BlockNo; }
169 uint64_t getInst() const { return u.s.InstNo; }
170 uint64_t getLoc() const { return u.s.LocNo; }
171 bool isPHI() const { return u.s.InstNo == 0; }
172
173 uint64_t asU64() const { return u.Value; }
174
176 ValueIDNum Val;
177 Val.u.Value = v;
178 return Val;
179 }
180
181 bool operator<(const ValueIDNum &Other) const {
182 return asU64() < Other.asU64();
183 }
184
185 bool operator==(const ValueIDNum &Other) const {
186 return u.Value == Other.u.Value;
187 }
188
189 bool operator!=(const ValueIDNum &Other) const { return !(*this == Other); }
190
191 std::string asString(const std::string &mlocname) const {
192 return Twine("Value{bb: ")
193 .concat(Twine(u.s.BlockNo)
194 .concat(Twine(", inst: ")
195 .concat((u.s.InstNo ? Twine(u.s.InstNo)
196 : Twine("live-in"))
197 .concat(Twine(", loc: ").concat(
198 Twine(mlocname)))
199 .concat(Twine("}")))))
200 .str();
201 }
202
204};
205
206} // End namespace LiveDebugValues
207
208namespace llvm {
209using namespace LiveDebugValues;
210
211template <> struct DenseMapInfo<LocIdx> {
212 static unsigned getHashValue(const LocIdx &Loc) { return Loc.asU64(); }
213
214 static bool isEqual(const LocIdx &A, const LocIdx &B) { return A == B; }
215};
216
217template <> struct DenseMapInfo<ValueIDNum> {
218 static unsigned getHashValue(const ValueIDNum &Val) {
219 return hash_value(Val.asU64());
220 }
221
222 static bool isEqual(const ValueIDNum &A, const ValueIDNum &B) {
223 return A == B;
224 }
225};
226
227} // end namespace llvm
228
229namespace LiveDebugValues {
230using namespace llvm;
231
232/// Type for a table of values in a block.
234
235/// A collection of ValueTables, one per BB in a function, with convenient
236/// accessor methods.
238 FuncValueTable(int NumBBs, int NumLocs) {
239 Storage.reserve(NumBBs);
240 for (int i = 0; i != NumBBs; ++i)
241 Storage.push_back(
242 std::make_unique<ValueTable>(NumLocs, ValueIDNum::EmptyValue));
243 }
244
245 /// Returns the ValueTable associated with MBB.
247 return (*this)[MBB.getNumber()];
248 }
249
250 /// Returns the ValueTable associated with the MachineBasicBlock whose number
251 /// is MBBNum.
252 ValueTable &operator[](int MBBNum) const {
253 auto &TablePtr = Storage[MBBNum];
254 assert(TablePtr && "Trying to access a deleted table");
255 return *TablePtr;
256 }
257
258 /// Returns the ValueTable associated with the entry MachineBasicBlock.
259 ValueTable &tableForEntryMBB() const { return (*this)[0]; }
260
261 /// Returns true if the ValueTable associated with MBB has not been freed.
263 return Storage[MBB.getNumber()] != nullptr;
264 }
265
266 /// Frees the memory of the ValueTable associated with MBB.
268 Storage[MBB.getNumber()].reset();
269 }
270
271private:
272 /// ValueTables are stored as unique_ptrs to allow for deallocation during
273 /// LDV; this was measured to have a significant impact on compiler memory
274 /// usage.
276};
277
278/// Thin wrapper around an integer -- designed to give more type safety to
279/// spill location numbers.
281public:
282 explicit SpillLocationNo(unsigned SpillNo) : SpillNo(SpillNo) {}
283 unsigned SpillNo;
284 unsigned id() const { return SpillNo; }
285
286 bool operator<(const SpillLocationNo &Other) const {
287 return SpillNo < Other.SpillNo;
288 }
289
290 bool operator==(const SpillLocationNo &Other) const {
291 return SpillNo == Other.SpillNo;
292 }
293 bool operator!=(const SpillLocationNo &Other) const {
294 return !(*this == Other);
295 }
296};
297
298/// Meta qualifiers for a value. Pair of whatever expression is used to qualify
299/// the value, and Boolean of whether or not it's indirect.
301public:
303 std::optional<unsigned> NumLocOps = std::nullopt)
306 ? *NumLocOps
307 : (IsVariadic ? DIExpr->getNumLocationOperands() : 1)) {}
308
309 /// Extract properties from an existing DBG_VALUE instruction.
311 assert(MI.isDebugValue());
312 assert(MI.getDebugExpression()->getNumLocationOperands() == 0 ||
313 MI.isDebugValueList() || MI.isUndefDebugValue());
314 IsVariadic = MI.isDebugValueList();
315 DIExpr = MI.getDebugExpression();
316 Indirect = MI.isDebugOffsetImm();
317 NumLocOps = MI.getNumDebugOperands();
318 }
319
321 // Joining pairs location operands by index, so the operand counts must
322 // agree. Equal expressions do not imply equal counts, because the same
323 // DIExpression can appear on MachineInstrs with different numbers of
324 // debug operands.
325 if (NumLocOps != Other.NumLocOps)
326 return false;
328 Other.Indirect);
329 }
330
332 return std::tie(DIExpr, Indirect, IsVariadic, NumLocOps) ==
333 std::tie(Other.DIExpr, Other.Indirect, Other.IsVariadic,
334 Other.NumLocOps);
335 }
336
338 return !(*this == Other);
339 }
340
341 unsigned getLocationOpCount() const { return NumLocOps; }
342
346 unsigned NumLocOps;
347};
348
349/// TODO: Might pack better if we changed this to a Struct of Arrays, since
350/// MachineOperand is width 32, making this struct width 33. We could also
351/// potentially avoid storing the whole MachineOperand (sizeof=32), instead
352/// choosing to store just the contents portion (sizeof=8) and a Kind enum,
353/// since we already know it is some type of immediate value.
354/// Stores a single debug operand, which can either be a MachineOperand for
355/// directly storing immediate values, or a ValueIDNum representing some value
356/// computed at some point in the program. IsConst is used as a discriminator.
357struct DbgOp {
358 union {
361 };
363
364 DbgOp() : ID(ValueIDNum::EmptyValue), IsConst(false) {}
367
368 bool isUndef() const { return !IsConst && ID == ValueIDNum::EmptyValue; }
369
370#ifndef NDEBUG
371 void dump(const MLocTracker *MTrack) const;
372#endif
373};
374
375/// A DbgOp whose ID (if any) has resolved to an actual location, LocIdx. Used
376/// when working with concrete debug values, i.e. when joining MLocs and VLocs
377/// in the TransferTracker or emitting DBG_VALUE/DBG_VALUE_LIST instructions in
378/// the MLocTracker.
380 union {
383 };
385
388
389 bool operator==(const ResolvedDbgOp &Other) const {
390 if (IsConst != Other.IsConst)
391 return false;
392 if (IsConst)
393 return MO.isIdenticalTo(Other.MO);
394 return Loc == Other.Loc;
395 }
396
397#ifndef NDEBUG
398 void dump(const MLocTracker *MTrack) const;
399#endif
400};
401
402/// An ID used in the DbgOpIDMap (below) to lookup a stored DbgOp. This is used
403/// in place of actual DbgOps inside of a DbgValue to reduce its size, as
404/// DbgValue is very frequently used and passed around, and the actual DbgOp is
405/// over 8x larger than this class, due to storing a MachineOperand. This ID
406/// should be equal for all equal DbgOps, and also encodes whether the mapped
407/// DbgOp is a constant, meaning that for simple equality or const-ness checks
408/// it is not necessary to lookup this ID.
409struct DbgOpID {
414
415 union {
418 };
419
421 static_assert(sizeof(DbgOpID) == 4, "DbgOpID should fit within 4 bytes.");
422 }
424 DbgOpID(bool IsConst, uint32_t Index) : ID({IsConst, Index}) {}
425
427
428 bool operator==(const DbgOpID &Other) const { return RawID == Other.RawID; }
429 bool operator!=(const DbgOpID &Other) const { return !(*this == Other); }
430
431 uint32_t asU32() const { return RawID; }
432
433 bool isUndef() const { return *this == UndefID; }
434 bool isConst() const { return ID.IsConst && !isUndef(); }
435 uint32_t getIndex() const { return ID.Index; }
436
437#ifndef NDEBUG
438 void dump(const MLocTracker *MTrack, const DbgOpIDMap *OpStore) const;
439#endif
440};
441
442/// Class storing the complete set of values that are observed by DbgValues
443/// within the current function. Allows 2-way lookup, with `find` returning the
444/// Op for a given ID and `insert` returning the ID for a given Op (creating one
445/// if none exists).
447
450
453
454public:
455 /// If \p Op does not already exist in this map, it is inserted and the
456 /// corresponding DbgOpID is returned. If Op already exists in this map, then
457 /// no change is made and the existing ID for Op is returned.
458 /// Calling this with the undef DbgOp will always return DbgOpID::UndefID.
460 if (Op.isUndef())
461 return DbgOpID::UndefID;
462 if (Op.IsConst)
463 return insertConstOp(Op.MO);
464 return insertValueOp(Op.ID);
465 }
466 /// Returns the DbgOp associated with \p ID. Should only be used for IDs
467 /// returned from calling `insert` from this map or DbgOpID::UndefID.
468 DbgOp find(DbgOpID ID) const {
469 if (ID == DbgOpID::UndefID)
470 return DbgOp();
471 if (ID.isConst())
472 return DbgOp(ConstOps[ID.getIndex()]);
473 return DbgOp(ValueOps[ID.getIndex()]);
474 }
475
476 void clear() {
477 ValueOps.clear();
478 ConstOps.clear();
479 ValueOpToID.clear();
480 ConstOpToID.clear();
481 }
482
483private:
484 DbgOpID insertConstOp(MachineOperand &MO) {
485 auto [It, Inserted] = ConstOpToID.try_emplace(MO, true, ConstOps.size());
486 if (Inserted)
487 ConstOps.push_back(MO);
488 return It->second;
489 }
490 DbgOpID insertValueOp(ValueIDNum VID) {
491 auto [It, Inserted] = ValueOpToID.try_emplace(VID, false, ValueOps.size());
492 if (Inserted)
493 ValueOps.push_back(VID);
494 return It->second;
495 }
496};
497
498// We set the maximum number of operands that we will handle to keep DbgValue
499// within a reasonable size (64 bytes), as we store and pass a lot of them
500// around.
501#define MAX_DBG_OPS 8
502
503/// Class recording the (high level) _value_ of a variable. Identifies the value
504/// of the variable as a list of ValueIDNums and constant MachineOperands, or as
505/// an empty list for undef debug values or VPHI values which we have not found
506/// valid locations for.
507/// This class also stores meta-information about how the value is qualified.
508/// Used to reason about variable values when performing the second
509/// (DebugVariable specific) dataflow analysis.
510class DbgValue {
511private:
512 /// If Kind is Def or VPHI, the set of IDs corresponding to the DbgOps that
513 /// are used. VPHIs set every ID to EmptyID when we have not found a valid
514 /// machine-value for every operand, and sets them to the corresponding
515 /// machine-values when we have found all of them.
516 DbgOpID DbgOps[MAX_DBG_OPS];
517 unsigned OpCount;
518
519public:
520 /// For a NoVal or VPHI DbgValue, which block it was generated in.
522
523 /// Qualifiers for the ValueIDNum above.
525
526 typedef enum {
527 Undef, // Represents a DBG_VALUE $noreg in the transfer function only.
528 Def, // This value is defined by some combination of constants,
529 // instructions, or PHI values.
530 VPHI, // Incoming values to BlockNo differ, those values must be joined by
531 // a PHI in this block.
532 NoVal, // Empty DbgValue indicating an unknown value. Used as initializer,
533 // before dominating blocks values are propagated in.
534 } KindT;
535 /// Discriminator for whether this is a constant or an in-program value.
537
539 : OpCount(DbgOps.size()), BlockNo(0), Properties(Prop), Kind(Def) {
540 static_assert(sizeof(DbgValue) <= 64,
541 "DbgValue should fit within 64 bytes.");
542 assert(DbgOps.size() == Prop.getLocationOpCount());
543 if (DbgOps.size() > MAX_DBG_OPS ||
544 any_of(DbgOps, [](DbgOpID ID) { return ID.isUndef(); })) {
545 Kind = Undef;
546 OpCount = 0;
547#define DEBUG_TYPE "LiveDebugValues"
548 if (DbgOps.size() > MAX_DBG_OPS) {
549 LLVM_DEBUG(dbgs() << "Found DbgValue with more than maximum allowed "
550 "operands.\n");
551 }
552#undef DEBUG_TYPE
553 } else {
554 for (unsigned Idx = 0; Idx < DbgOps.size(); ++Idx)
555 this->DbgOps[Idx] = DbgOps[Idx];
556 }
557 }
558
560 : OpCount(0), BlockNo(BlockNo), Properties(Prop), Kind(Kind) {
561 assert(Kind == NoVal || Kind == VPHI);
562 }
563
565 : OpCount(0), BlockNo(0), Properties(Prop), Kind(Kind) {
566 assert(Kind == Undef &&
567 "Empty DbgValue constructor must pass in Undef kind");
568 }
569
570#ifndef NDEBUG
571 void dump(const MLocTracker *MTrack = nullptr,
572 const DbgOpIDMap *OpStore = nullptr) const;
573#endif
574
575 bool operator==(const DbgValue &Other) const {
576 if (std::tie(Kind, Properties) != std::tie(Other.Kind, Other.Properties))
577 return false;
578 else if (Kind == Def && !equal(getDbgOpIDs(), Other.getDbgOpIDs()))
579 return false;
580 else if (Kind == NoVal && BlockNo != Other.BlockNo)
581 return false;
582 else if (Kind == VPHI && BlockNo != Other.BlockNo)
583 return false;
584 else if (Kind == VPHI && !equal(getDbgOpIDs(), Other.getDbgOpIDs()))
585 return false;
586
587 return true;
588 }
589
590 bool operator!=(const DbgValue &Other) const { return !(*this == Other); }
591
592 // Returns an array of all the machine values used to calculate this variable
593 // value, or an empty list for an Undef or unjoined VPHI.
594 ArrayRef<DbgOpID> getDbgOpIDs() const { return {DbgOps, OpCount}; }
595
596 // Returns either DbgOps[Index] if this DbgValue has Debug Operands, or
597 // the ID for ValueIDNum::EmptyValue otherwise (i.e. if this is an Undef,
598 // NoVal, or an unjoined VPHI).
599 DbgOpID getDbgOpID(unsigned Index) const {
600 if (!OpCount)
601 return DbgOpID::UndefID;
602 assert(Index < OpCount);
603 return DbgOps[Index];
604 }
605 // Replaces this DbgValue's existing DbgOpIDs (if any) with the contents of
606 // \p NewIDs. The number of DbgOpIDs passed must be equal to the number of
607 // arguments expected by this DbgValue's properties (the return value of
608 // `getLocationOpCount()`).
610 // We can go from no ops to some ops, but not from some ops to no ops.
611 assert(NewIDs.size() == getLocationOpCount() &&
612 "Incorrect number of Debug Operands for this DbgValue.");
613 OpCount = NewIDs.size();
614 for (unsigned Idx = 0; Idx < NewIDs.size(); ++Idx)
615 DbgOps[Idx] = NewIDs[Idx];
616 }
617
618 // The number of debug operands expected by this DbgValue's expression.
619 // getDbgOpIDs() should return an array of this length, unless this is an
620 // Undef or an unjoined VPHI.
621 unsigned getLocationOpCount() const {
622 return Properties.getLocationOpCount();
623 }
624
625 // Returns true if this or Other are unjoined PHIs, which do not have defined
626 // Loc Ops, or if the `n`th Loc Op for this has a different constness to the
627 // `n`th Loc Op for Other.
628 bool hasJoinableLocOps(const DbgValue &Other) const {
629 if (isUnjoinedPHI() || Other.isUnjoinedPHI())
630 return true;
631 for (unsigned Idx = 0; Idx < getLocationOpCount(); ++Idx) {
632 if (getDbgOpID(Idx).isConst() != Other.getDbgOpID(Idx).isConst())
633 return false;
634 }
635 return true;
636 }
637
638 bool isUnjoinedPHI() const { return Kind == VPHI && OpCount == 0; }
639
641 if (!OpCount)
642 return false;
643 return equal(getDbgOpIDs(), Other.getDbgOpIDs());
644 }
645};
646
648public:
650 unsigned operator()(const LocIdx &L) const { return L.asU64(); }
651};
652
653/// Tracker for what values are in machine locations. Listens to the Things
654/// being Done by various instructions, and maintains a table of what machine
655/// locations have what values (as defined by a ValueIDNum).
656///
657/// There are potentially a much larger number of machine locations on the
658/// target machine than the actual working-set size of the function. On x86 for
659/// example, we're extremely unlikely to want to track values through control
660/// or debug registers. To avoid doing so, MLocTracker has several layers of
661/// indirection going on, described below, to avoid unnecessarily tracking
662/// any location.
663///
664/// Here's a sort of diagram of the indexes, read from the bottom up:
665///
666/// Size on stack Offset on stack
667/// \ /
668/// Stack Idx (Where in slot is this?)
669/// /
670/// /
671/// Slot Num (%stack.0) /
672/// FrameIdx => SpillNum /
673/// \ /
674/// SpillID (int) Register number (int)
675/// \ /
676/// LocationID => LocIdx
677/// |
678/// LocIdx => ValueIDNum
679///
680/// The aim here is that the LocIdx => ValueIDNum vector is just an array of
681/// values in numbered locations, so that later analyses can ignore whether the
682/// location is a register or otherwise. To map a register / spill location to
683/// a LocIdx, you have to use the (sparse) LocationID => LocIdx map. And to
684/// build a LocationID for a stack slot, you need to combine identifiers for
685/// which stack slot it is and where within that slot is being described.
686///
687/// Register mask operands cause trouble by technically defining every register;
688/// various hacks are used to avoid tracking registers that are never read and
689/// only written by regmasks.
691public:
696
697 /// IndexedMap type, mapping from LocIdx to ValueIDNum.
699
700 /// Map of LocIdxes to the ValueIDNums that they store. This is tightly
701 /// packed, entries only exist for locations that are being tracked.
703
704 /// "Map" of machine location IDs (i.e., raw register or spill number) to the
705 /// LocIdx key / number for that location. There are always at least as many
706 /// as the number of registers on the target -- if the value in the register
707 /// is not being tracked, then the LocIdx value will be zero. New entries are
708 /// appended if a new spill slot begins being tracked.
709 /// This, and the corresponding reverse map persist for the analysis of the
710 /// whole function, and is necessarying for decoding various vectors of
711 /// values.
712 std::vector<LocIdx> LocIDToLocIdx;
713
714 /// Inverse map of LocIDToLocIdx.
716
717 /// When clobbering register masks, we chose to not believe the machine model
718 /// and don't clobber SP. Do the same for SP aliases, and for efficiency,
719 /// keep a set of them here.
721
722 /// Unique-ification of spill. Used to number them -- their LocID number is
723 /// the index in SpillLocs minus one plus NumRegs.
725
726 // If we discover a new machine location, assign it an mphi with this
727 // block number.
728 unsigned CurBB = -1;
729
730 /// Cached local copy of the number of registers the target has.
731 unsigned NumRegs;
732
733 /// Number of slot indexes the target has -- distinct segments of a stack
734 /// slot that can take on the value of a subregister, when a super-register
735 /// is written to the stack.
736 unsigned NumSlotIdxes;
737
738 /// Collection of register mask operands that have been observed. Second part
739 /// of pair indicates the instruction that they happened in. Used to
740 /// reconstruct where defs happened if we start tracking a location later
741 /// on.
743
744 /// Pair for describing a position within a stack slot -- first the size in
745 /// bits, then the offset.
746 typedef std::pair<unsigned short, unsigned short> StackSlotPos;
747
748 /// Map from a size/offset pair describing a position in a stack slot, to a
749 /// numeric identifier for that position. Allows easier identification of
750 /// individual positions.
752
753 /// Inverse of StackSlotIdxes.
755
756 /// Iterator for locations and the values they contain. Dereferencing
757 /// produces a struct/pair containing the LocIdx key for this location,
758 /// and a reference to the value currently stored. Simplifies the process
759 /// of seeking a particular location.
761 LocToValueType &ValueMap;
762 LocIdx Idx;
763
764 public:
766 public:
768 const LocIdx Idx; /// Read-only index of this location.
769 ValueIDNum &Value; /// Reference to the stored value at this location.
770 };
771
773 : ValueMap(ValueMap), Idx(Idx) {}
774
775 bool operator==(const MLocIterator &Other) const {
776 assert(&ValueMap == &Other.ValueMap);
777 return Idx == Other.Idx;
778 }
779
780 bool operator!=(const MLocIterator &Other) const {
781 return !(*this == Other);
782 }
783
784 void operator++() { Idx = LocIdx(Idx.asU64() + 1); }
785
786 value_type operator*() { return value_type(Idx, ValueMap[LocIdx(Idx)]); }
787 };
788
790 const TargetRegisterInfo &TRI,
791 const TargetLowering &TLI);
792
793 /// Produce location ID number for a Register. Provides some small amount of
794 /// type safety.
795 /// \param Reg The register we're looking up.
796 unsigned getLocID(Register Reg) { return Reg.id(); }
797
798 /// Produce location ID number for a spill position.
799 /// \param Spill The number of the spill we're fetching the location for.
800 /// \param SpillSubReg Subregister within the spill we're addressing.
801 unsigned getLocID(SpillLocationNo Spill, unsigned SpillSubReg) {
802 unsigned short Size = TRI.getSubRegIdxSize(SpillSubReg);
803 unsigned short Offs = TRI.getSubRegIdxOffset(SpillSubReg);
804 return getLocID(Spill, {Size, Offs});
805 }
806
807 /// Produce location ID number for a spill position.
808 /// \param Spill The number of the spill we're fetching the location for.
809 /// \apram SpillIdx size/offset within the spill slot to be addressed.
810 unsigned getLocID(SpillLocationNo Spill, StackSlotPos Idx) {
811 unsigned SlotNo = Spill.id() - 1;
812 SlotNo *= NumSlotIdxes;
813 assert(StackSlotIdxes.contains(Idx));
814 SlotNo += StackSlotIdxes[Idx];
815 SlotNo += NumRegs;
816 return SlotNo;
817 }
818
819 /// Given a spill number, and a slot within the spill, calculate the ID number
820 /// for that location.
821 unsigned getSpillIDWithIdx(SpillLocationNo Spill, unsigned Idx) {
822 unsigned SlotNo = Spill.id() - 1;
823 SlotNo *= NumSlotIdxes;
824 SlotNo += Idx;
825 SlotNo += NumRegs;
826 return SlotNo;
827 }
828
829 /// Return the spill number that a location ID corresponds to.
830 SpillLocationNo locIDToSpill(unsigned ID) const {
831 assert(ID >= NumRegs);
832 ID -= NumRegs;
833 // Truncate away the index part, leaving only the spill number.
834 ID /= NumSlotIdxes;
835 return SpillLocationNo(ID + 1); // The UniqueVector is one-based.
836 }
837
838 /// Returns the spill-slot size/offs that a location ID corresponds to.
839 StackSlotPos locIDToSpillIdx(unsigned ID) const {
840 assert(ID >= NumRegs);
841 ID -= NumRegs;
842 unsigned Idx = ID % NumSlotIdxes;
843 return StackIdxesToPos.find(Idx)->second;
844 }
845
846 unsigned getNumLocs() const { return LocIdxToIDNum.size(); }
847
848 /// Reset all locations to contain a PHI value at the designated block. Used
849 /// sometimes for actual PHI values, othertimes to indicate the block entry
850 /// value (before any more information is known).
851 void setMPhis(unsigned NewCurBB) {
852 CurBB = NewCurBB;
853 for (auto Location : locations())
854 Location.Value = {CurBB, 0, Location.Idx};
855 }
856
857 /// Load values for each location from array of ValueIDNums. Take current
858 /// bbnum just in case we read a value from a hitherto untouched register.
859 void loadFromArray(ValueTable &Locs, unsigned NewCurBB) {
860 CurBB = NewCurBB;
861 // Iterate over all tracked locations, and load each locations live-in
862 // value into our local index.
863 for (auto Location : locations())
864 Location.Value = Locs[Location.Idx.asU64()];
865 }
866
867 /// Wipe any un-necessary location records after traversing a block.
868 void reset() {
869 // We could reset all the location values too; however either loadFromArray
870 // or setMPhis should be called before this object is re-used. Just
871 // clear Masks, they're definitely not needed.
872 Masks.clear();
873 }
874
875 /// Clear all data. Destroys the LocID <=> LocIdx map, which makes most of
876 /// the information in this pass uninterpretable.
877 void clear() {
878 reset();
879 LocIDToLocIdx.clear();
880 LocIdxToLocID.clear();
881 LocIdxToIDNum.clear();
882 // SpillLocs.reset(); XXX UniqueVector::reset assumes a SpillLoc casts from
883 // 0
884 SpillLocs = decltype(SpillLocs)();
885 StackSlotIdxes.clear();
886 StackIdxesToPos.clear();
887
889 }
890
891 /// Set a locaiton to a certain value.
892 void setMLoc(LocIdx L, ValueIDNum Num) {
893 assert(L.asU64() < LocIdxToIDNum.size());
894 LocIdxToIDNum[L] = Num;
895 }
896
897 /// Read the value of a particular location
899 assert(L.asU64() < LocIdxToIDNum.size());
900 return LocIdxToIDNum[L];
901 }
902
903 /// Create a LocIdx for an untracked register ID. Initialize it to either an
904 /// mphi value representing a live-in, or a recent register mask clobber.
906
908 LocIdx &Index = LocIDToLocIdx[ID];
909 if (Index.isIllegal())
910 Index = trackRegister(ID);
911 return Index;
912 }
913
914 /// Is register R currently tracked by MLocTracker?
916 LocIdx &Index = LocIDToLocIdx[R];
917 return !Index.isIllegal();
918 }
919
920 /// Record a definition of the specified register at the given block / inst.
921 /// This doesn't take a ValueIDNum, because the definition and its location
922 /// are synonymous.
923 void defReg(Register R, unsigned BB, unsigned Inst) {
924 unsigned ID = getLocID(R);
926 ValueIDNum ValueID = {BB, Inst, Idx};
927 LocIdxToIDNum[Idx] = ValueID;
928 }
929
930 /// Set a register to a value number. To be used if the value number is
931 /// known in advance.
932 void setReg(Register R, ValueIDNum ValueID) {
933 unsigned ID = getLocID(R);
935 LocIdxToIDNum[Idx] = ValueID;
936 }
937
939 unsigned ID = getLocID(R);
941 return LocIdxToIDNum[Idx];
942 }
943
944 /// Reset a register value to zero / empty. Needed to replicate the
945 /// VarLoc implementation where a copy to/from a register effectively
946 /// clears the contents of the source register. (Values can only have one
947 /// machine location in VarLocBasedImpl).
949 unsigned ID = getLocID(R);
950 LocIdx Idx = LocIDToLocIdx[ID];
952 }
953
954 /// Determine the LocIdx of an existing register.
956 unsigned ID = getLocID(R);
957 assert(ID < LocIDToLocIdx.size());
958 assert(LocIDToLocIdx[ID] != UINT_MAX); // Sentinel for IndexedMap.
959 return LocIDToLocIdx[ID];
960 }
961
962 /// Record a RegMask operand being executed. Defs any register we currently
963 /// track, stores a pointer to the mask in case we have to account for it
964 /// later.
965 void writeRegMask(const MachineOperand *MO, unsigned CurBB, unsigned InstID);
966
967 /// Find LocIdx for SpillLoc \p L, creating a new one if it's not tracked.
968 /// Returns std::nullopt when in scenarios where a spill slot could be
969 /// tracked, but we would likely run into resource limitations.
970 LLVM_ABI_FOR_TEST std::optional<SpillLocationNo>
972
973 // Get LocIdx of a spill ID.
974 LocIdx getSpillMLoc(unsigned SpillID) {
975 assert(LocIDToLocIdx[SpillID] != UINT_MAX); // Sentinel for IndexedMap.
976 return LocIDToLocIdx[SpillID];
977 }
978
979 /// Return true if Idx is a spill machine location.
980 bool isSpill(LocIdx Idx) const { return LocIdxToLocID[Idx] >= NumRegs; }
981
982 /// How large is this location (aka, how wide is a value defined there?).
983 unsigned getLocSizeInBits(LocIdx L) const {
984 unsigned ID = LocIdxToLocID[L];
985 if (!isSpill(L)) {
986 return TRI.getRegSizeInBits(Register(ID), MF.getRegInfo());
987 } else {
988 // The slot location on the stack is uninteresting, we care about the
989 // position of the value within the slot (which comes with a size).
991 return Pos.first;
992 }
993 }
994
996
1000
1001 /// Return a range over all locations currently tracked.
1005
1006 std::string LocIdxToName(LocIdx Idx) const;
1007
1008 std::string IDAsString(const ValueIDNum &Num) const;
1009
1010#ifndef NDEBUG
1011 LLVM_DUMP_METHOD void dump();
1012
1014#endif
1015
1016 /// Create a DBG_VALUE based on debug operands \p DbgOps. Qualify it with the
1017 /// information in \pProperties, for variable Var. Don't insert it anywhere,
1018 /// just return the builder for it.
1020 const DebugVariable &Var, const DILocation *DILoc,
1021 const DbgValueProperties &Properties);
1022};
1023
1024/// Types for recording sets of variable fragments that overlap. For a given
1025/// local variable, we record all other fragments of that variable that could
1026/// overlap it, to reduce search time.
1028 std::pair<const DILocalVariable *, DIExpression::FragmentInfo>;
1031
1032/// Collection of DBG_VALUEs observed when traversing a block. Records each
1033/// variable and the value the DBG_VALUE refers to. Requires the machine value
1034/// location dataflow algorithm to have run already, so that values can be
1035/// identified.
1037public:
1038 /// Ref to function-wide map of DebugVariable <=> ID-numbers.
1040 /// Map DebugVariable to the latest Value it's defined to have.
1041 /// Needs to be a MapVector because we determine order-in-the-input-MIR from
1042 /// the order in this container. (FIXME: likely no longer true as the ordering
1043 /// is now provided by DebugVariableMap).
1044 /// We only retain the last DbgValue in each block for each variable, to
1045 /// determine the blocks live-out variable value. The Vars container forms the
1046 /// transfer function for this block, as part of the dataflow analysis. The
1047 /// movement of values between locations inside of a block is handled at a
1048 /// much later stage, in the TransferTracker class.
1054
1055public:
1057 const DIExpression *EmptyExpr)
1059 EmptyProperties(EmptyExpr, false, false) {}
1060
1061 void defVar(const MachineInstr &MI, const DbgValueProperties &Properties,
1062 const SmallVectorImpl<DbgOpID> &DebugOps) {
1063 assert(MI.isDebugValueLike());
1064 DebugVariable Var(MI.getDebugVariable(), MI.getDebugExpression(),
1065 MI.getDebugLoc()->getInlinedAt());
1066 // Either insert or fetch an ID number for this variable.
1067 DebugVariableID VarID = DVMap.insertDVID(Var, MI.getDebugLoc().get());
1068 DbgValue Rec = (DebugOps.size() > 0)
1069 ? DbgValue(DebugOps, Properties)
1070 : DbgValue(Properties, DbgValue::Undef);
1071
1072 // Attempt insertion; overwrite if it's already mapped.
1073 Vars.insert_or_assign(VarID, Rec);
1074 Scopes[VarID] = MI.getDebugLoc().get();
1075
1076 considerOverlaps(Var, MI.getDebugLoc().get());
1077 }
1078
1080 auto Overlaps = OverlappingFragments.find(
1081 {Var.getVariable(), Var.getFragmentOrDefault()});
1082 if (Overlaps == OverlappingFragments.end())
1083 return;
1084
1085 // Otherwise: terminate any overlapped variable locations.
1086 for (auto FragmentInfo : Overlaps->second) {
1087 // The "empty" fragment is stored as DebugVariable::DefaultFragment, so
1088 // that it overlaps with everything, however its cannonical representation
1089 // in a DebugVariable is as "None".
1090 std::optional<DIExpression::FragmentInfo> OptFragmentInfo = FragmentInfo;
1091 if (DebugVariable::isDefaultFragment(FragmentInfo))
1092 OptFragmentInfo = std::nullopt;
1093
1094 DebugVariable Overlapped(Var.getVariable(), OptFragmentInfo,
1095 Var.getInlinedAt());
1096 // Produce an ID number for this overlapping fragment of a variable.
1097 DebugVariableID OverlappedID = DVMap.insertDVID(Overlapped, Loc);
1099
1100 // Attempt insertion; overwrite if it's already mapped.
1101 Vars.insert_or_assign(OverlappedID, Rec);
1102 Scopes[OverlappedID] = Loc;
1103 }
1104 }
1105
1106 void clear() {
1107 Vars.clear();
1108 Scopes.clear();
1109 }
1110};
1111
1112// XXX XXX docs
1114public:
1115 friend class ::InstrRefLDVTest;
1116
1118 using OptFragmentInfo = std::optional<DIExpression::FragmentInfo>;
1119
1120 // Helper while building OverlapMap, a map of all fragments seen for a given
1121 // DILocalVariable.
1124
1125 /// Machine location/value transfer function, a mapping of which locations
1126 /// are assigned which new values.
1128
1129 /// Live in/out structure for the variable values: a per-block map of
1130 /// variables to their values.
1132
1133 using VarAndLoc = std::pair<DebugVariableID, DbgValue>;
1134
1135 /// Type for a live-in value: the predecessor block, and its value.
1136 using InValueT = std::pair<MachineBasicBlock *, DbgValue *>;
1137
1138 /// Vector (per block) of a collection (inner smallvector) of live-ins.
1139 /// Used as the result type for the variable value dataflow problem.
1141
1142 /// Mapping from lexical scopes to a DILocation in that scope.
1144
1145 /// Mapping from lexical scopes to variables in that scope.
1148
1149 /// Mapping from lexical scopes to blocks where variables in that scope are
1150 /// assigned. Such blocks aren't necessarily "in" the lexical scope, it's
1151 /// just a block where an assignment happens.
1153
1154private:
1155 MachineDominatorTree *DomTree;
1156 const TargetRegisterInfo *TRI;
1157 const MachineRegisterInfo *MRI;
1158 const TargetInstrInfo *TII;
1159 const TargetFrameLowering *TFI;
1160 const MachineFrameInfo *MFI;
1161 BitVector CalleeSavedRegs;
1162 LexicalScopes LS;
1163
1164 // An empty DIExpression. Used default / placeholder DbgValueProperties
1165 // objects, as we can't have null expressions.
1166 const DIExpression *EmptyExpr;
1167
1168 /// Object to track machine locations as we step through a block. Could
1169 /// probably be a field rather than a pointer, as it's always used.
1170 MLocTracker *MTracker = nullptr;
1171
1172 /// Number of the current block LiveDebugValues is stepping through.
1173 unsigned CurBB = -1;
1174
1175 /// Number of the current instruction LiveDebugValues is evaluating.
1176 unsigned CurInst;
1177
1178 /// Variable tracker -- listens to DBG_VALUEs occurring as InstrRefBasedImpl
1179 /// steps through a block. Reads the values at each location from the
1180 /// MLocTracker object.
1181 VLocTracker *VTracker = nullptr;
1182
1183 /// Tracker for transfers, listens to DBG_VALUEs and transfers of values
1184 /// between locations during stepping, creates new DBG_VALUEs when values move
1185 /// location.
1186 TransferTracker *TTracker = nullptr;
1187
1188 /// Blocks which are artificial, i.e. blocks which exclusively contain
1189 /// instructions without DebugLocs, or with line 0 locations.
1190 SmallPtrSet<MachineBasicBlock *, 16> ArtificialBlocks;
1191
1192 // Mapping of blocks to and from their RPOT order.
1196
1197 /// Pair of MachineInstr, and its 1-based offset into the containing block.
1198 using InstAndNum = std::pair<const MachineInstr *, unsigned>;
1199 /// Map from debug instruction number to the MachineInstr labelled with that
1200 /// number, and its location within the function. Used to transform
1201 /// instruction numbers in DBG_INSTR_REFs into machine value numbers.
1202 std::map<uint64_t, InstAndNum> DebugInstrNumToInstr;
1203
1204 /// Record of where we observed a DBG_PHI instruction.
1205 class DebugPHIRecord {
1206 public:
1207 /// Instruction number of this DBG_PHI.
1208 uint64_t InstrNum;
1209 /// Block where DBG_PHI occurred.
1211 /// The value number read by the DBG_PHI -- or std::nullopt if it didn't
1212 /// refer to a value.
1213 std::optional<ValueIDNum> ValueRead;
1214 /// Register/Stack location the DBG_PHI reads -- or std::nullopt if it
1215 /// referred to something unexpected.
1216 std::optional<LocIdx> ReadLoc;
1217
1218 operator unsigned() const { return InstrNum; }
1219 };
1220
1221 /// Map from instruction numbers defined by DBG_PHIs to a record of what that
1222 /// DBG_PHI read and where. Populated and edited during the machine value
1223 /// location problem -- we use LLVMs SSA Updater to fix changes by
1224 /// optimizations that destroy PHI instructions.
1225 SmallVector<DebugPHIRecord, 32> DebugPHINumToValue;
1226
1227 // Map of overlapping variable fragments.
1228 OverlapMap OverlapFragments;
1229 VarToFragments SeenFragments;
1230
1231 /// Mapping of DBG_INSTR_REF instructions to their values, for those
1232 /// DBG_INSTR_REFs that call resolveDbgPHIs. These variable references solve
1233 /// a mini SSA problem caused by DBG_PHIs being cloned, this collection caches
1234 /// the result.
1235 DenseMap<std::pair<MachineInstr *, unsigned>, std::optional<ValueIDNum>>
1236 SeenDbgPHIs;
1237
1238 DbgOpIDMap DbgOpStore;
1239
1240 /// Mapping between DebugVariables and unique ID numbers. This is a more
1241 /// efficient way to represent the identity of a variable, versus a plain
1242 /// DebugVariable.
1243 DebugVariableMap DVMap;
1244
1245 /// True if we need to examine call instructions for stack clobbers. We
1246 /// normally assume that they don't clobber SP, but stack probes on Windows
1247 /// do.
1248 bool AdjustsStackInCalls = false;
1249
1250 /// If AdjustsStackInCalls is true, this holds the name of the target's stack
1251 /// probe function, which is the function we expect will alter the stack
1252 /// pointer.
1253 StringRef StackProbeSymbolName;
1254
1255 /// Tests whether this instruction is a spill to a stack slot.
1256 std::optional<SpillLocationNo> isSpillInstruction(const MachineInstr &MI,
1257 MachineFunction *MF);
1258
1259 /// Decide if @MI is a spill instruction and return true if it is. We use 2
1260 /// criteria to make this decision:
1261 /// - Is this instruction a store to a spill slot?
1262 /// - Is there a register operand that is both used and killed?
1263 /// TODO: Store optimization can fold spills into other stores (including
1264 /// other spills). We do not handle this yet (more than one memory operand).
1265 bool isLocationSpill(const MachineInstr &MI, MachineFunction *MF,
1266 unsigned &Reg);
1267
1268 /// If a given instruction is identified as a spill, return the spill slot
1269 /// and set \p Reg to the spilled register.
1270 std::optional<SpillLocationNo> isRestoreInstruction(const MachineInstr &MI,
1271 MachineFunction *MF,
1272 unsigned &Reg);
1273
1274 /// Given a spill instruction, extract the spill slot information, ensure it's
1275 /// tracked, and return the spill number.
1276 std::optional<SpillLocationNo>
1277 extractSpillBaseRegAndOffset(const MachineInstr &MI);
1278
1279 /// For an instruction reference given by \p InstNo and \p OpNo in instruction
1280 /// \p MI returns the Value pointed to by that instruction reference if any
1281 /// exists, otherwise returns std::nullopt.
1282 std::optional<ValueIDNum> getValueForInstrRef(unsigned InstNo, unsigned OpNo,
1284 const FuncValueTable *MLiveOuts,
1285 const FuncValueTable *MLiveIns);
1286
1287 /// Observe a single instruction while stepping through a block.
1288 void process(MachineInstr &MI, const FuncValueTable *MLiveOuts,
1289 const FuncValueTable *MLiveIns);
1290
1291 /// Examines whether \p MI is a DBG_VALUE and notifies trackers.
1292 /// \returns true if MI was recognized and processed.
1293 bool transferDebugValue(const MachineInstr &MI);
1294
1295 /// Examines whether \p MI is a DBG_INSTR_REF and notifies trackers.
1296 /// \returns true if MI was recognized and processed.
1297 bool transferDebugInstrRef(MachineInstr &MI, const FuncValueTable *MLiveOuts,
1298 const FuncValueTable *MLiveIns);
1299
1300 /// Stores value-information about where this PHI occurred, and what
1301 /// instruction number is associated with it.
1302 /// \returns true if MI was recognized and processed.
1303 bool transferDebugPHI(MachineInstr &MI);
1304
1305 /// Examines whether \p MI is copy instruction, and notifies trackers.
1306 /// \returns true if MI was recognized and processed.
1307 bool transferRegisterCopy(MachineInstr &MI);
1308
1309 /// Examines whether \p MI is stack spill or restore instruction, and
1310 /// notifies trackers. \returns true if MI was recognized and processed.
1311 bool transferSpillOrRestoreInst(MachineInstr &MI);
1312
1313 /// Examines \p MI for any registers that it defines, and notifies trackers.
1314 void transferRegisterDef(MachineInstr &MI);
1315
1316 /// Copy one location to the other, accounting for movement of subregisters
1317 /// too.
1318 void performCopy(Register Src, Register Dst);
1319
1320 void accumulateFragmentMap(MachineInstr &MI);
1321
1322 /// Determine the machine value number referred to by (potentially several)
1323 /// DBG_PHI instructions. Block duplication and tail folding can duplicate
1324 /// DBG_PHIs, shifting the position where values in registers merge, and
1325 /// forming another mini-ssa problem to solve.
1326 /// \p Here the position of a DBG_INSTR_REF seeking a machine value number
1327 /// \p InstrNum Debug instruction number defined by DBG_PHI instructions.
1328 /// \returns The machine value number at position Here, or std::nullopt.
1329 std::optional<ValueIDNum> resolveDbgPHIs(MachineFunction &MF,
1330 const FuncValueTable &MLiveOuts,
1331 const FuncValueTable &MLiveIns,
1332 MachineInstr &Here,
1333 uint64_t InstrNum);
1334
1335 std::optional<ValueIDNum> resolveDbgPHIsImpl(MachineFunction &MF,
1336 const FuncValueTable &MLiveOuts,
1337 const FuncValueTable &MLiveIns,
1338 MachineInstr &Here,
1339 uint64_t InstrNum);
1340
1341 /// Step through the function, recording register definitions and movements
1342 /// in an MLocTracker. Convert the observations into a per-block transfer
1343 /// function in \p MLocTransfer, suitable for using with the machine value
1344 /// location dataflow problem.
1346 produceMLocTransferFunction(MachineFunction &MF,
1348 unsigned MaxNumBlocks);
1349
1350 /// Solve the machine value location dataflow problem. Takes as input the
1351 /// transfer functions in \p MLocTransfer. Writes the output live-in and
1352 /// live-out arrays to the (initialized to zero) multidimensional arrays in
1353 /// \p MInLocs and \p MOutLocs. The outer dimension is indexed by block
1354 /// number, the inner by LocIdx.
1356 buildMLocValueMap(MachineFunction &MF, FuncValueTable &MInLocs,
1357 FuncValueTable &MOutLocs,
1358 SmallVectorImpl<MLocTransferMap> &MLocTransfer);
1359
1360 /// Examine the stack indexes (i.e. offsets within the stack) to find the
1361 /// basic units of interference -- like reg units, but for the stack.
1362 void findStackIndexInterference(SmallVectorImpl<unsigned> &Slots);
1363
1364 /// Install PHI values into the live-in array for each block, according to
1365 /// the IDF of each register.
1366 LLVM_ABI_FOR_TEST void placeMLocPHIs(
1368 FuncValueTable &MInLocs, SmallVectorImpl<MLocTransferMap> &MLocTransfer);
1369
1370 /// Propagate variable values to blocks in the common case where there's
1371 /// only one value assigned to the variable. This function has better
1372 /// performance as it doesn't have to find the dominance frontier between
1373 /// different assignments.
1374 void placePHIsForSingleVarDefinition(
1375 const SmallPtrSetImpl<MachineBasicBlock *> &InScopeBlocks,
1377 DebugVariableID Var, LiveInsT &Output);
1378
1379 /// Calculate the iterated-dominance-frontier for a set of defs, using the
1380 /// existing LLVM facilities for this. Works for a single "value" or
1381 /// machine/variable location.
1382 /// \p AllBlocks Set of blocks where we might consume the value.
1383 /// \p DefBlocks Set of blocks where the value/location is defined.
1384 /// \p PHIBlocks Output set of blocks where PHIs must be placed.
1385 void BlockPHIPlacement(const SmallPtrSetImpl<MachineBasicBlock *> &AllBlocks,
1386 const SmallPtrSetImpl<MachineBasicBlock *> &DefBlocks,
1388
1389 /// Perform a control flow join (lattice value meet) of the values in machine
1390 /// locations at \p MBB. Follows the algorithm described in the file-comment,
1391 /// reading live-outs of predecessors from \p OutLocs, the current live ins
1392 /// from \p InLocs, and assigning the newly computed live ins back into
1393 /// \p InLocs. \returns two bools -- the first indicates whether a change
1394 /// was made, the second whether a lattice downgrade occurred. If the latter
1395 /// is true, revisiting this block is necessary.
1396 bool mlocJoin(MachineBasicBlock &MBB,
1398 FuncValueTable &OutLocs, ValueTable &InLocs);
1399
1400 /// Produce a set of blocks that are in the current lexical scope. This means
1401 /// those blocks that contain instructions "in" the scope, blocks where
1402 /// assignments to variables in scope occur, and artificial blocks that are
1403 /// successors to any of the earlier blocks. See https://llvm.org/PR48091 for
1404 /// more commentry on what "in scope" means.
1405 /// \p DILoc A location in the scope that we're fetching blocks for.
1406 /// \p Output Set to put in-scope-blocks into.
1407 /// \p AssignBlocks Blocks known to contain assignments of variables in scope.
1408 void
1409 getBlocksForScope(const DILocation *DILoc,
1411 const SmallPtrSetImpl<MachineBasicBlock *> &AssignBlocks);
1412
1413 /// Solve the variable value dataflow problem, for a single lexical scope.
1414 /// Uses the algorithm from the file comment to resolve control flow joins
1415 /// using PHI placement and value propagation. Reads the locations of machine
1416 /// values from the \p MInLocs and \p MOutLocs arrays (see buildMLocValueMap)
1417 /// and reads the variable values transfer function from \p AllTheVlocs.
1418 /// Live-in and Live-out variable values are stored locally, with the live-ins
1419 /// permanently stored to \p Output once a fixedpoint is reached.
1420 /// \p VarsWeCareAbout contains a collection of the variables in \p Scope
1421 /// that we should be tracking.
1422 /// \p AssignBlocks contains the set of blocks that aren't in \p DILoc's
1423 /// scope, but which do contain DBG_VALUEs, which VarLocBasedImpl tracks
1424 /// locations through.
1426 buildVLocValueMap(const DILocation *DILoc,
1427 const SmallSet<DebugVariableID, 4> &VarsWeCareAbout,
1429 LiveInsT &Output, FuncValueTable &MOutLocs,
1430 FuncValueTable &MInLocs,
1431 SmallVectorImpl<VLocTracker> &AllTheVLocs);
1432
1433 /// Attempt to eliminate un-necessary PHIs on entry to a block. Examines the
1434 /// live-in values coming from predecessors live-outs, and replaces any PHIs
1435 /// already present in this blocks live-ins with a live-through value if the
1436 /// PHI isn't needed.
1437 /// \p LiveIn Old live-in value, overwritten with new one if live-in changes.
1438 /// \returns true if any live-ins change value, either from value propagation
1439 /// or PHI elimination.
1441 vlocJoin(MachineBasicBlock &MBB, LiveIdxT &VLOCOutLocs,
1443 DbgValue &LiveIn);
1444
1445 /// For the given block and live-outs feeding into it, try to find
1446 /// machine locations for each debug operand where all the values feeding
1447 /// into that operand join together.
1448 /// \returns true if a joined location was found for every value that needed
1449 /// to be joined.
1451 pickVPHILoc(SmallVectorImpl<DbgOpID> &OutValues, const MachineBasicBlock &MBB,
1452 const LiveIdxT &LiveOuts, FuncValueTable &MOutLocs,
1454
1455 std::optional<ValueIDNum> pickOperandPHILoc(
1456 unsigned DbgOpIdx, const MachineBasicBlock &MBB, const LiveIdxT &LiveOuts,
1457 FuncValueTable &MOutLocs,
1459
1460 /// Take collections of DBG_VALUE instructions stored in TTracker, and
1461 /// install them into their output blocks.
1462 bool emitTransfers();
1463
1464 /// Boilerplate computation of some initial sets, artifical blocks and
1465 /// RPOT block ordering.
1466 LLVM_ABI_FOR_TEST void initialSetup(MachineFunction &MF);
1467
1468 /// Produce a map of the last lexical scope that uses a block, using the
1469 /// scopes DFSOut number. Mapping is block-number to DFSOut.
1470 /// \p EjectionMap Pre-allocated vector in which to install the built ma.
1471 /// \p ScopeToDILocation Mapping of LexicalScopes to their DILocations.
1472 /// \p AssignBlocks Map of blocks where assignments happen for a scope.
1473 void makeDepthFirstEjectionMap(SmallVectorImpl<unsigned> &EjectionMap,
1474 const ScopeToDILocT &ScopeToDILocation,
1475 ScopeToAssignBlocksT &AssignBlocks);
1476
1477 /// When determining per-block variable values and emitting to DBG_VALUEs,
1478 /// this function explores by lexical scope depth. Doing so means that per
1479 /// block information can be fully computed before exploration finishes,
1480 /// allowing us to emit it and free data structures earlier than otherwise.
1481 /// It's also good for locality.
1482 bool depthFirstVLocAndEmit(
1483 unsigned MaxNumBlocks, const ScopeToDILocT &ScopeToDILocation,
1484 const ScopeToVarsT &ScopeToVars, ScopeToAssignBlocksT &ScopeToBlocks,
1485 LiveInsT &Output, FuncValueTable &MOutLocs, FuncValueTable &MInLocs,
1487 bool ShouldEmitDebugEntryValues);
1488
1489 bool ExtendRanges(MachineFunction &MF, MachineDominatorTree *DomTree,
1490 bool ShouldEmitDebugEntryValues, unsigned InputBBLimit,
1491 unsigned InputDbgValLimit) override;
1492
1493public:
1494 /// Default construct and initialize the pass.
1496
1498 void dump_mloc_transfer(const MLocTransferMap &mloc_transfer) const;
1499
1500 bool isCalleeSaved(LocIdx L) const;
1501 bool isCalleeSavedReg(Register R) const;
1502
1504 // Instruction must have a memory operand that's a stack slot, and isn't
1505 // aliased, meaning it's a spill from regalloc instead of a variable.
1506 // If it's aliased, we can't guarantee its value.
1507 if (!MI.hasOneMemOperand())
1508 return false;
1509 auto *MemOperand = *MI.memoperands_begin();
1510 return MemOperand->isStore() &&
1511 MemOperand->getPseudoValue() &&
1512 MemOperand->getPseudoValue()->kind() == PseudoSourceValue::FixedStack
1513 && !MemOperand->getPseudoValue()->isAliased(MFI);
1514 }
1515
1516 std::optional<LocIdx> findLocationForMemOperand(const MachineInstr &MI);
1517
1518 // Utility for unit testing, don't use directly.
1520 return DVMap;
1521 }
1522};
1523
1524} // namespace LiveDebugValues
1525
1526#endif /* LLVM_LIB_CODEGEN_LIVEDEBUGVALUES_INSTRREFBASEDLDV_H */
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned uint64_t
MachineBasicBlock & MBB
static cl::opt< unsigned > MaxNumBlocks("debug-ata-max-blocks", cl::init(10000), cl::desc("Maximum num basic blocks before debug info dropped"), cl::Hidden)
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition Compiler.h:678
#define LLVM_ABI_FOR_TEST
Definition Compiler.h:220
This file defines the DenseMap class.
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
This file implements an indexed map.
#define NUM_LOC_BITS
#define MAX_DBG_OPS
static cl::opt< unsigned > InputBBLimit("livedebugvalues-input-bb-limit", cl::desc("Maximum input basic blocks before DBG_VALUE limit applies"), cl::init(10000), cl::Hidden)
Register Reg
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
#define LLVM_DEBUG(...)
Definition Debug.h:119
Class storing the complete set of values that are observed by DbgValues within the current function.
DbgOp find(DbgOpID ID) const
Returns the DbgOp associated with ID.
DbgOpID insert(DbgOp Op)
If Op does not already exist in this map, it is inserted and the corresponding DbgOpID is returned.
Meta qualifiers for a value.
bool operator==(const DbgValueProperties &Other) const
DbgValueProperties(const DIExpression *DIExpr, bool Indirect, bool IsVariadic, std::optional< unsigned > NumLocOps=std::nullopt)
DbgValueProperties(const MachineInstr &MI)
Extract properties from an existing DBG_VALUE instruction.
bool isJoinable(const DbgValueProperties &Other) const
bool operator!=(const DbgValueProperties &Other) const
Class recording the (high level) value of a variable.
int BlockNo
For a NoVal or VPHI DbgValue, which block it was generated in.
DbgValueProperties Properties
Qualifiers for the ValueIDNum above.
ArrayRef< DbgOpID > getDbgOpIDs() const
void setDbgOpIDs(ArrayRef< DbgOpID > NewIDs)
bool hasJoinableLocOps(const DbgValue &Other) const
void dump(const MLocTracker *MTrack=nullptr, const DbgOpIDMap *OpStore=nullptr) const
DbgValue(ArrayRef< DbgOpID > DbgOps, const DbgValueProperties &Prop)
DbgOpID getDbgOpID(unsigned Index) const
DbgValue(unsigned BlockNo, const DbgValueProperties &Prop, KindT Kind)
bool operator!=(const DbgValue &Other) const
DbgValue(const DbgValueProperties &Prop, KindT Kind)
KindT Kind
Discriminator for whether this is a constant or an in-program value.
unsigned getLocationOpCount() const
bool operator==(const DbgValue &Other) const
bool hasIdenticalValidLocOps(const DbgValue &Other) const
Mapping from DebugVariable to/from a unique identifying number.
const VarAndLoc & lookupDVID(DebugVariableID ID) const
DebugVariableID insertDVID(DebugVariable &Var, const DILocation *Loc)
DebugVariableID getDVID(const DebugVariable &Var) const
DenseMap< const LexicalScope *, const DILocation * > ScopeToDILocT
Mapping from lexical scopes to a DILocation in that scope.
DenseMap< const DILocalVariable *, SmallSet< FragmentInfo, 4 > > VarToFragments
std::optional< LocIdx > findLocationForMemOperand(const MachineInstr &MI)
std::pair< MachineBasicBlock *, DbgValue * > InValueT
Type for a live-in value: the predecessor block, and its value.
std::pair< DebugVariableID, DbgValue > VarAndLoc
SmallVector< SmallVector< VarAndLoc, 8 >, 8 > LiveInsT
Vector (per block) of a collection (inner smallvector) of live-ins.
LLVM_ABI_FOR_TEST InstrRefBasedLDV()
Default construct and initialize the pass.
DenseMap< const LexicalScope *, SmallPtrSet< MachineBasicBlock *, 4 > > ScopeToAssignBlocksT
Mapping from lexical scopes to blocks where variables in that scope are assigned.
DIExpression::FragmentInfo FragmentInfo
DenseMap< const LexicalScope *, SmallSet< DebugVariableID, 4 > > ScopeToVarsT
Mapping from lexical scopes to variables in that scope.
std::optional< DIExpression::FragmentInfo > OptFragmentInfo
SmallDenseMap< const MachineBasicBlock *, DbgValue *, 16 > LiveIdxT
Live in/out structure for the variable values: a per-block map of variables to their values.
SmallDenseMap< LocIdx, ValueIDNum > MLocTransferMap
Machine location/value transfer function, a mapping of which locations are assigned which new values.
bool hasFoldedStackStore(const MachineInstr &MI)
LLVM_DUMP_METHOD void dump_mloc_transfer(const MLocTransferMap &mloc_transfer) const
unsigned operator()(const LocIdx &L) const
Handle-class for a particular "location".
bool operator!=(const LocIdx &L) const
bool operator<(const LocIdx &Other) const
static LocIdx MakeIllegalLoc()
bool operator!=(unsigned L) const
bool operator==(unsigned L) const
bool operator==(const LocIdx &L) const
ValueIDNum & Value
Read-only index of this location.
Iterator for locations and the values they contain.
bool operator!=(const MLocIterator &Other) const
MLocIterator(LocToValueType &ValueMap, LocIdx Idx)
bool operator==(const MLocIterator &Other) const
Tracker for what values are in machine locations.
unsigned getLocSizeInBits(LocIdx L) const
How large is this location (aka, how wide is a value defined there?).
bool isRegisterTracked(Register R)
Is register R currently tracked by MLocTracker?
LLVM_ABI_FOR_TEST std::optional< SpillLocationNo > getOrTrackSpillLoc(SpillLoc L)
Find LocIdx for SpillLoc L, creating a new one if it's not tracked.
void loadFromArray(ValueTable &Locs, unsigned NewCurBB)
Load values for each location from array of ValueIDNums.
IndexedMap< unsigned, LocIdxToIndexFunctor > LocIdxToLocID
Inverse map of LocIDToLocIdx.
unsigned getSpillIDWithIdx(SpillLocationNo Spill, unsigned Idx)
Given a spill number, and a slot within the spill, calculate the ID number for that location.
unsigned getLocID(SpillLocationNo Spill, unsigned SpillSubReg)
Produce location ID number for a spill position.
iterator_range< MLocIterator > locations()
Return a range over all locations currently tracked.
unsigned getLocID(SpillLocationNo Spill, StackSlotPos Idx)
Produce location ID number for a spill position.
SmallSet< Register, 8 > SPAliases
When clobbering register masks, we chose to not believe the machine model and don't clobber SP.
unsigned getLocID(Register Reg)
Produce location ID number for a Register.
const TargetRegisterInfo & TRI
unsigned NumRegs
Cached local copy of the number of registers the target has.
DenseMap< StackSlotPos, unsigned > StackSlotIdxes
Map from a size/offset pair describing a position in a stack slot, to a numeric identifier for that p...
LocIdx lookupOrTrackRegister(unsigned ID)
void setReg(Register R, ValueIDNum ValueID)
Set a register to a value number.
SpillLocationNo locIDToSpill(unsigned ID) const
Return the spill number that a location ID corresponds to.
void reset()
Wipe any un-necessary location records after traversing a block.
DenseMap< unsigned, StackSlotPos > StackIdxesToPos
Inverse of StackSlotIdxes.
std::string IDAsString(const ValueIDNum &Num) const
void writeRegMask(const MachineOperand *MO, unsigned CurBB, unsigned InstID)
Record a RegMask operand being executed.
std::pair< unsigned short, unsigned short > StackSlotPos
Pair for describing a position within a stack slot – first the size in bits, then the offset.
const TargetInstrInfo & TII
bool isSpill(LocIdx Idx) const
Return true if Idx is a spill machine location.
LocIdx getRegMLoc(Register R)
Determine the LocIdx of an existing register.
MachineInstrBuilder emitLoc(const SmallVectorImpl< ResolvedDbgOp > &DbgOps, const DebugVariable &Var, const DILocation *DILoc, const DbgValueProperties &Properties)
Create a DBG_VALUE based on debug operands DbgOps.
void wipeRegister(Register R)
Reset a register value to zero / empty.
void setMLoc(LocIdx L, ValueIDNum Num)
Set a locaiton to a certain value.
LocToValueType LocIdxToIDNum
Map of LocIdxes to the ValueIDNums that they store.
std::vector< LocIdx > LocIDToLocIdx
"Map" of machine location IDs (i.e., raw register or spill number) to the LocIdx key / number for tha...
IndexedMap< ValueIDNum, LocIdxToIndexFunctor > LocToValueType
IndexedMap type, mapping from LocIdx to ValueIDNum.
SmallVector< std::pair< const MachineOperand *, unsigned >, 32 > Masks
Collection of register mask operands that have been observed.
unsigned NumSlotIdxes
Number of slot indexes the target has – distinct segments of a stack slot that can take on the value ...
UniqueVector< SpillLoc > SpillLocs
Unique-ification of spill.
ValueIDNum readMLoc(LocIdx L)
Read the value of a particular location.
void setMPhis(unsigned NewCurBB)
Reset all locations to contain a PHI value at the designated block.
ValueIDNum readReg(Register R)
void defReg(Register R, unsigned BB, unsigned Inst)
Record a definition of the specified register at the given block / inst.
LLVM_ABI_FOR_TEST LocIdx trackRegister(unsigned ID)
Create a LocIdx for an untracked register ID.
LLVM_ABI_FOR_TEST MLocTracker(MachineFunction &MF, const TargetInstrInfo &TII, const TargetRegisterInfo &TRI, const TargetLowering &TLI)
LLVM_DUMP_METHOD void dump_mloc_map()
StackSlotPos locIDToSpillIdx(unsigned ID) const
Returns the spill-slot size/offs that a location ID corresponds to.
LocIdx getSpillMLoc(unsigned SpillID)
std::string LocIdxToName(LocIdx Idx) const
Thin wrapper around an integer – designed to give more type safety to spill location numbers.
bool operator==(const SpillLocationNo &Other) const
bool operator!=(const SpillLocationNo &Other) const
bool operator<(const SpillLocationNo &Other) const
Collection of DBG_VALUEs observed when traversing a block.
const OverlapMap & OverlappingFragments
SmallDenseMap< DebugVariableID, const DILocation *, 8 > Scopes
SmallMapVector< DebugVariableID, DbgValue, 8 > Vars
Map DebugVariable to the latest Value it's defined to have.
void defVar(const MachineInstr &MI, const DbgValueProperties &Properties, const SmallVectorImpl< DbgOpID > &DebugOps)
void considerOverlaps(const DebugVariable &Var, const DILocation *Loc)
VLocTracker(DebugVariableMap &DVMap, const OverlapMap &O, const DIExpression *EmptyExpr)
DebugVariableMap & DVMap
Ref to function-wide map of DebugVariable <=> ID-numbers.
Unique identifier for a value defined by an instruction, as a value type.
uint64_t LocNo
The Instruction where the def happens.
ValueIDNum(uint64_t Block, uint64_t Inst, uint64_t Loc)
struct LiveDebugValues::ValueIDNum::@122243371010332366363270357367014132366357004151::@211331010212204211312147341360354163043131005174 s
bool operator==(const ValueIDNum &Other) const
bool operator<(const ValueIDNum &Other) const
static ValueIDNum fromU64(uint64_t v)
std::string asString(const std::string &mlocname) const
static LLVM_ABI_FOR_TEST ValueIDNum EmptyValue
ValueIDNum(uint64_t Block, uint64_t Inst, LocIdx Loc)
bool operator!=(const ValueIDNum &Other) const
uint64_t InstNo
The block where the def happens.
Tracker for converting machine value locations and variable values into variable locations (the outpu...
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
Get the array size.
Definition ArrayRef.h:141
DWARF expression.
DbgVariableFragmentInfo FragmentInfo
static LLVM_ABI bool isEqualExpression(const DIExpression *FirstExpr, bool FirstIndirect, const DIExpression *SecondExpr, bool SecondIndirect)
Determines whether two debug values should produce equivalent DWARF expressions, using their DIExpres...
Identifies a unique instance of a variable.
static bool isDefaultFragment(const FragmentInfo F)
const DILocation * getInlinedAt() const
FragmentInfo getFragmentOrDefault() const
const DILocalVariable * getVariable() const
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Definition DenseMap.h:341
This class provides interface to collect and use lexical scoping information from machine instruction...
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Wrapper class representing virtual and physical registers.
Definition Register.h:20
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition SmallSet.h:134
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StackOffset holds a fixed and a scalable offset in bytes.
Definition TypeSize.h:30
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
Information about stack frame layout on the target.
TargetInstrInfo - Interface to description of machine instruction set.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
LLVM_ABI std::string str() const
Return the twine contents as a std::string.
Definition Twine.cpp:17
Twine concat(const Twine &Suffix) const
Definition Twine.h:497
UniqueVector - This class produces a sequential ID number (base 1) for each unique entry that is adde...
A range adaptor for a pair of iterators.
DenseMap< FragmentOfVar, SmallVector< DIExpression::FragmentInfo, 1 > > OverlapMap
SmallVector< ValueIDNum, 0 > ValueTable
Type for a table of values in a block.
std::pair< const DILocalVariable *, DIExpression::FragmentInfo > FragmentOfVar
Types for recording sets of variable fragments that overlap.
std::pair< DebugVariable, const DILocation * > VarAndLoc
This is an optimization pass for GlobalISel generic memory operations.
std::tuple< const DIScope *, const DIScope *, const DILocalVariable * > VarID
A unique key that represents a debug variable.
hash_code hash_value(const FixedPointSemantics &Val)
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition STLExtras.h:1669
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
detail::concat_range< ValueT, RangeTs... > concat(RangeTs &&...Ranges)
Returns a concatenated range across two or more ranges.
Definition STLExtras.h:1151
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1746
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
@ Other
Any other memory.
Definition ModRef.h:68
DWARFExpression::Operation Op
bool equal(L &&LRange, R &&RRange)
Wrapper function around std::equal to detect if pair-wise elements between two ranges are the same.
Definition STLExtras.h:2146
An ID used in the DbgOpIDMap (below) to lookup a stored DbgOp.
bool operator==(const DbgOpID &Other) const
bool operator!=(const DbgOpID &Other) const
void dump(const MLocTracker *MTrack, const DbgOpIDMap *OpStore) const
DbgOpID(bool IsConst, uint32_t Index)
static LLVM_ABI_FOR_TEST DbgOpID UndefID
struct IsConstIndexPair ID
TODO: Might pack better if we changed this to a Struct of Arrays, since MachineOperand is width 32,...
void dump(const MLocTracker *MTrack) const
DbgOp(MachineOperand MO)
A collection of ValueTables, one per BB in a function, with convenient accessor methods.
ValueTable & operator[](int MBBNum) const
Returns the ValueTable associated with the MachineBasicBlock whose number is MBBNum.
void ejectTableForBlock(const MachineBasicBlock &MBB)
Frees the memory of the ValueTable associated with MBB.
ValueTable & tableForEntryMBB() const
Returns the ValueTable associated with the entry MachineBasicBlock.
FuncValueTable(int NumBBs, int NumLocs)
ValueTable & operator[](const MachineBasicBlock &MBB) const
Returns the ValueTable associated with MBB.
bool hasTableFor(MachineBasicBlock &MBB) const
Returns true if the ValueTable associated with MBB has not been freed.
bool operator==(const ResolvedDbgOp &Other) const
void dump(const MLocTracker *MTrack) const
bool operator<(const SpillLoc &Other) const
bool operator==(const SpillLoc &Other) const
static bool isEqual(const LocIdx &A, const LocIdx &B)
static unsigned getHashValue(const LocIdx &Loc)
static unsigned getHashValue(const ValueIDNum &Val)
static bool isEqual(const ValueIDNum &A, const ValueIDNum &B)
An information struct used to provide DenseMap with the various necessary components for a given valu...
A MapVector that performs no allocations if smaller than a certain size.
Definition MapVector.h:342