1 //===- llvm/CodeGen/SlotIndexes.h - Slot indexes representation -*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements SlotIndex and related classes. The purpuse of SlotIndex
11 // is to describe a position at which a register can become live, or cease to
14 // SlotIndex is mostly a proxy for entries of the SlotIndexList, a class which
15 // is held is LiveIntervals and provides the real numbering. This allows
16 // LiveIntervals to perform largely transparent renumbering.
17 //===----------------------------------------------------------------------===//
19 #ifndef LLVM_CODEGEN_SLOTINDEXES_H
20 #define LLVM_CODEGEN_SLOTINDEXES_H
22 #include "llvm/CodeGen/MachineBasicBlock.h"
23 #include "llvm/CodeGen/MachineFunction.h"
24 #include "llvm/CodeGen/MachineFunctionPass.h"
25 #include "llvm/ADT/PointerIntPair.h"
26 #include "llvm/ADT/SmallVector.h"
27 #include "llvm/ADT/DenseMap.h"
28 #include "llvm/Support/Allocator.h"
32 /// This class represents an entry in the slot index list held in the
33 /// SlotIndexes pass. It should not be used directly. See the
34 /// SlotIndex & SlotIndexes classes for the public interface to this
36 class IndexListEntry {
37 static const unsigned EMPTY_KEY_INDEX = ~0U & ~3U,
38 TOMBSTONE_KEY_INDEX = ~0U & ~7U;
40 IndexListEntry *next, *prev;
46 typedef enum { EMPTY_KEY, TOMBSTONE_KEY } ReservedEntryType;
48 // This constructor is only to be used by getEmptyKeyEntry
49 // & getTombstoneKeyEntry. It sets index to the given
50 // value and mi to zero.
51 IndexListEntry(ReservedEntryType r) : mi(0) {
53 case EMPTY_KEY: index = EMPTY_KEY_INDEX; break;
54 case TOMBSTONE_KEY: index = TOMBSTONE_KEY_INDEX; break;
55 default: assert(false && "Invalid value for constructor.");
63 IndexListEntry(MachineInstr *mi, unsigned index) : mi(mi), index(index) {
64 assert(index != EMPTY_KEY_INDEX && index != TOMBSTONE_KEY_INDEX &&
65 "Attempt to create invalid index. "
66 "Available indexes may have been exhausted?.");
69 bool isValid() const {
70 return (index != EMPTY_KEY_INDEX && index != TOMBSTONE_KEY_INDEX);
73 MachineInstr* getInstr() const { return mi; }
74 void setInstr(MachineInstr *mi) {
75 assert(isValid() && "Attempt to modify reserved index.");
79 unsigned getIndex() const { return index; }
80 void setIndex(unsigned index) {
81 assert(index != EMPTY_KEY_INDEX && index != TOMBSTONE_KEY_INDEX &&
82 "Attempt to set index to invalid value.");
83 assert(isValid() && "Attempt to reset reserved index value.");
87 IndexListEntry* getNext() { return next; }
88 const IndexListEntry* getNext() const { return next; }
89 void setNext(IndexListEntry *next) {
90 assert(isValid() && "Attempt to modify reserved index.");
94 IndexListEntry* getPrev() { return prev; }
95 const IndexListEntry* getPrev() const { return prev; }
96 void setPrev(IndexListEntry *prev) {
97 assert(isValid() && "Attempt to modify reserved index.");
101 // This function returns the index list entry that is to be used for empty
103 static IndexListEntry* getEmptyKeyEntry();
105 // This function returns the index list entry that is to be used for
106 // tombstone SlotIndex keys.
107 static IndexListEntry* getTombstoneKeyEntry();
110 // Specialize PointerLikeTypeTraits for IndexListEntry.
112 class PointerLikeTypeTraits<IndexListEntry*> {
114 static inline void* getAsVoidPointer(IndexListEntry *p) {
117 static inline IndexListEntry* getFromVoidPointer(void *p) {
118 return static_cast<IndexListEntry*>(p);
120 enum { NumLowBitsAvailable = 3 };
123 /// SlotIndex - An opaque wrapper around machine indexes.
125 friend class SlotIndexes;
126 friend struct DenseMapInfo<SlotIndex>;
128 enum Slot { LOAD, USE, DEF, STORE, NUM };
130 PointerIntPair<IndexListEntry*, 2, unsigned> lie;
132 SlotIndex(IndexListEntry *entry, unsigned slot)
134 assert(entry != 0 && "Attempt to construct index with 0 pointer.");
137 IndexListEntry& entry() const {
138 assert(isValid() && "Attempt to compare reserved index.");
139 return *lie.getPointer();
142 int getIndex() const {
143 return entry().getIndex() | getSlot();
146 /// Returns the slot for this SlotIndex.
147 Slot getSlot() const {
148 return static_cast<Slot>(lie.getInt());
151 static inline unsigned getHashValue(const SlotIndex &v) {
152 IndexListEntry *ptrVal = &v.entry();
153 return (unsigned((intptr_t)ptrVal) >> 4) ^
154 (unsigned((intptr_t)ptrVal) >> 9);
158 static inline SlotIndex getEmptyKey() {
159 return SlotIndex(IndexListEntry::getEmptyKeyEntry(), 0);
162 static inline SlotIndex getTombstoneKey() {
163 return SlotIndex(IndexListEntry::getTombstoneKeyEntry(), 0);
166 /// Construct an invalid index.
167 SlotIndex() : lie(IndexListEntry::getEmptyKeyEntry(), 0) {}
169 // Construct a new slot index from the given one, and set the slot.
170 SlotIndex(const SlotIndex &li, Slot s)
171 : lie(&li.entry(), unsigned(s)) {
172 assert(lie.getPointer() != 0 &&
173 "Attempt to construct index with 0 pointer.");
176 /// Returns true if this is a valid index. Invalid indicies do
177 /// not point into an index table, and cannot be compared.
178 bool isValid() const {
179 IndexListEntry *entry = lie.getPointer();
180 return ((entry!= 0) && (entry->isValid()));
183 /// Print this index to the given raw_ostream.
184 void print(raw_ostream &os) const;
186 /// Dump this index to stderr.
189 /// Compare two SlotIndex objects for equality.
190 bool operator==(SlotIndex other) const {
191 return lie == other.lie;
193 /// Compare two SlotIndex objects for inequality.
194 bool operator!=(SlotIndex other) const {
195 return lie != other.lie;
198 /// Compare two SlotIndex objects. Return true if the first index
199 /// is strictly lower than the second.
200 bool operator<(SlotIndex other) const {
201 return getIndex() < other.getIndex();
203 /// Compare two SlotIndex objects. Return true if the first index
204 /// is lower than, or equal to, the second.
205 bool operator<=(SlotIndex other) const {
206 return getIndex() <= other.getIndex();
209 /// Compare two SlotIndex objects. Return true if the first index
210 /// is greater than the second.
211 bool operator>(SlotIndex other) const {
212 return getIndex() > other.getIndex();
215 /// Compare two SlotIndex objects. Return true if the first index
216 /// is greater than, or equal to, the second.
217 bool operator>=(SlotIndex other) const {
218 return getIndex() >= other.getIndex();
221 /// Return the distance from this index to the given one.
222 int distance(SlotIndex other) const {
223 return other.getIndex() - getIndex();
226 /// isLoad - Return true if this is a LOAD slot.
227 bool isLoad() const {
228 return getSlot() == LOAD;
231 /// isDef - Return true if this is a DEF slot.
233 return getSlot() == DEF;
236 /// isUse - Return true if this is a USE slot.
238 return getSlot() == USE;
241 /// isStore - Return true if this is a STORE slot.
242 bool isStore() const {
243 return getSlot() == STORE;
246 /// Returns the base index for associated with this index. The base index
247 /// is the one associated with the LOAD slot for the instruction pointed to
249 SlotIndex getBaseIndex() const {
250 return getLoadIndex();
253 /// Returns the boundary index for associated with this index. The boundary
254 /// index is the one associated with the LOAD slot for the instruction
255 /// pointed to by this index.
256 SlotIndex getBoundaryIndex() const {
257 return getStoreIndex();
260 /// Returns the index of the LOAD slot for the instruction pointed to by
262 SlotIndex getLoadIndex() const {
263 return SlotIndex(&entry(), SlotIndex::LOAD);
266 /// Returns the index of the USE slot for the instruction pointed to by
268 SlotIndex getUseIndex() const {
269 return SlotIndex(&entry(), SlotIndex::USE);
272 /// Returns the index of the DEF slot for the instruction pointed to by
274 SlotIndex getDefIndex() const {
275 return SlotIndex(&entry(), SlotIndex::DEF);
278 /// Returns the index of the STORE slot for the instruction pointed to by
280 SlotIndex getStoreIndex() const {
281 return SlotIndex(&entry(), SlotIndex::STORE);
284 /// Returns the next slot in the index list. This could be either the
285 /// next slot for the instruction pointed to by this index or, if this
286 /// index is a STORE, the first slot for the next instruction.
287 /// WARNING: This method is considerably more expensive than the methods
288 /// that return specific slots (getUseIndex(), etc). If you can - please
289 /// use one of those methods.
290 SlotIndex getNextSlot() const {
292 if (s == SlotIndex::STORE) {
293 return SlotIndex(entry().getNext(), SlotIndex::LOAD);
295 return SlotIndex(&entry(), s + 1);
298 /// Returns the next index. This is the index corresponding to the this
299 /// index's slot, but for the next instruction.
300 SlotIndex getNextIndex() const {
301 return SlotIndex(entry().getNext(), getSlot());
304 /// Returns the previous slot in the index list. This could be either the
305 /// previous slot for the instruction pointed to by this index or, if this
306 /// index is a LOAD, the last slot for the previous instruction.
307 /// WARNING: This method is considerably more expensive than the methods
308 /// that return specific slots (getUseIndex(), etc). If you can - please
309 /// use one of those methods.
310 SlotIndex getPrevSlot() const {
312 if (s == SlotIndex::LOAD) {
313 return SlotIndex(entry().getPrev(), SlotIndex::STORE);
315 return SlotIndex(&entry(), s - 1);
318 /// Returns the previous index. This is the index corresponding to this
319 /// index's slot, but for the previous instruction.
320 SlotIndex getPrevIndex() const {
321 return SlotIndex(entry().getPrev(), getSlot());
326 /// DenseMapInfo specialization for SlotIndex.
328 struct DenseMapInfo<SlotIndex> {
329 static inline SlotIndex getEmptyKey() {
330 return SlotIndex::getEmptyKey();
332 static inline SlotIndex getTombstoneKey() {
333 return SlotIndex::getTombstoneKey();
335 static inline unsigned getHashValue(const SlotIndex &v) {
336 return SlotIndex::getHashValue(v);
338 static inline bool isEqual(const SlotIndex &LHS, const SlotIndex &RHS) {
343 template <> struct isPodLike<SlotIndex> { static const bool value = true; };
346 inline raw_ostream& operator<<(raw_ostream &os, SlotIndex li) {
351 typedef std::pair<SlotIndex, MachineBasicBlock*> IdxMBBPair;
353 inline bool operator<(SlotIndex V, const IdxMBBPair &IM) {
357 inline bool operator<(const IdxMBBPair &IM, SlotIndex V) {
361 struct Idx2MBBCompare {
362 bool operator()(const IdxMBBPair &LHS, const IdxMBBPair &RHS) const {
363 return LHS.first < RHS.first;
367 /// SlotIndexes pass.
369 /// This pass assigns indexes to each instruction.
370 class SlotIndexes : public MachineFunctionPass {
374 IndexListEntry *indexListHead;
375 unsigned functionSize;
377 typedef DenseMap<const MachineInstr*, SlotIndex> Mi2IndexMap;
380 /// MBB2IdxMap - The indexes of the first and last instructions in the
381 /// specified basic block.
382 typedef DenseMap<const MachineBasicBlock*,
383 std::pair<SlotIndex, SlotIndex> > MBB2IdxMap;
384 MBB2IdxMap mbb2IdxMap;
386 /// Idx2MBBMap - Sorted list of pairs of index of first instruction
388 std::vector<IdxMBBPair> idx2MBBMap;
390 // IndexListEntry allocator.
391 BumpPtrAllocator ileAllocator;
393 IndexListEntry* createEntry(MachineInstr *mi, unsigned index) {
394 IndexListEntry *entry =
395 static_cast<IndexListEntry*>(
396 ileAllocator.Allocate(sizeof(IndexListEntry),
397 alignOf<IndexListEntry>()));
399 new (entry) IndexListEntry(mi, index);
405 assert(indexListHead == 0 && "Zero entry non-null at initialisation.");
406 indexListHead = createEntry(0, ~0U);
407 indexListHead->setNext(0);
408 indexListHead->setPrev(indexListHead);
413 ileAllocator.Reset();
416 IndexListEntry* getTail() {
417 assert(indexListHead != 0 && "Call to getTail on uninitialized list.");
418 return indexListHead->getPrev();
421 const IndexListEntry* getTail() const {
422 assert(indexListHead != 0 && "Call to getTail on uninitialized list.");
423 return indexListHead->getPrev();
426 // Returns true if the index list is empty.
427 bool empty() const { return (indexListHead == getTail()); }
429 IndexListEntry* front() {
430 assert(!empty() && "front() called on empty index list.");
431 return indexListHead;
434 const IndexListEntry* front() const {
435 assert(!empty() && "front() called on empty index list.");
436 return indexListHead;
439 IndexListEntry* back() {
440 assert(!empty() && "back() called on empty index list.");
441 return getTail()->getPrev();
444 const IndexListEntry* back() const {
445 assert(!empty() && "back() called on empty index list.");
446 return getTail()->getPrev();
449 /// Insert a new entry before itr.
450 void insert(IndexListEntry *itr, IndexListEntry *val) {
451 assert(itr != 0 && "itr should not be null.");
452 IndexListEntry *prev = itr->getPrev();
456 if (itr != indexListHead) {
465 /// Push a new entry on to the end of the list.
466 void push_back(IndexListEntry *val) {
467 insert(getTail(), val);
473 SlotIndexes() : MachineFunctionPass(ID), indexListHead(0) {
474 initializeSlotIndexesPass(*PassRegistry::getPassRegistry());
477 virtual void getAnalysisUsage(AnalysisUsage &au) const;
478 virtual void releaseMemory();
480 virtual bool runOnMachineFunction(MachineFunction &fn);
482 /// Dump the indexes.
485 /// Renumber the index list, providing space for new instructions.
486 void renumberIndexes();
488 /// Returns the zero index for this analysis.
489 SlotIndex getZeroIndex() {
490 assert(front()->getIndex() == 0 && "First index is not 0?");
491 return SlotIndex(front(), 0);
494 /// Returns the base index of the last slot in this analysis.
495 SlotIndex getLastIndex() {
496 return SlotIndex(back(), 0);
499 /// Returns the invalid index marker for this analysis.
500 SlotIndex getInvalidIndex() {
501 return getZeroIndex();
504 /// Returns the distance between the highest and lowest indexes allocated
506 unsigned getIndexesLength() const {
507 assert(front()->getIndex() == 0 &&
508 "Initial index isn't zero?");
510 return back()->getIndex();
513 /// Returns the number of instructions in the function.
514 unsigned getFunctionSize() const {
518 /// Returns true if the given machine instr is mapped to an index,
519 /// otherwise returns false.
520 bool hasIndex(const MachineInstr *instr) const {
521 return (mi2iMap.find(instr) != mi2iMap.end());
524 /// Returns the base index for the given instruction.
525 SlotIndex getInstructionIndex(const MachineInstr *instr) const {
526 Mi2IndexMap::const_iterator itr = mi2iMap.find(instr);
527 assert(itr != mi2iMap.end() && "Instruction not found in maps.");
531 /// Returns the instruction for the given index, or null if the given
532 /// index has no instruction associated with it.
533 MachineInstr* getInstructionFromIndex(SlotIndex index) const {
534 return index.isValid() ? index.entry().getInstr() : 0;
537 /// Returns the next non-null index.
538 SlotIndex getNextNonNullIndex(SlotIndex index) {
539 SlotIndex nextNonNull = index.getNextIndex();
541 while (&nextNonNull.entry() != getTail() &&
542 getInstructionFromIndex(nextNonNull) == 0) {
543 nextNonNull = nextNonNull.getNextIndex();
549 /// Return the (start,end) range of the given basic block.
550 const std::pair<SlotIndex, SlotIndex> &
551 getMBBRange(const MachineBasicBlock *mbb) const {
552 MBB2IdxMap::const_iterator itr = mbb2IdxMap.find(mbb);
553 assert(itr != mbb2IdxMap.end() && "MBB not found in maps.");
557 /// Returns the first index in the given basic block.
558 SlotIndex getMBBStartIdx(const MachineBasicBlock *mbb) const {
559 return getMBBRange(mbb).first;
562 /// Returns the last index in the given basic block.
563 SlotIndex getMBBEndIdx(const MachineBasicBlock *mbb) const {
564 return getMBBRange(mbb).second;
567 /// Returns the basic block which the given index falls in.
568 MachineBasicBlock* getMBBFromIndex(SlotIndex index) const {
569 std::vector<IdxMBBPair>::const_iterator I =
570 std::lower_bound(idx2MBBMap.begin(), idx2MBBMap.end(), index);
571 // Take the pair containing the index
572 std::vector<IdxMBBPair>::const_iterator J =
573 ((I != idx2MBBMap.end() && I->first > index) ||
574 (I == idx2MBBMap.end() && idx2MBBMap.size()>0)) ? (I-1): I;
576 assert(J != idx2MBBMap.end() && J->first <= index &&
577 index < getMBBEndIdx(J->second) &&
578 "index does not correspond to an MBB");
582 bool findLiveInMBBs(SlotIndex start, SlotIndex end,
583 SmallVectorImpl<MachineBasicBlock*> &mbbs) const {
584 std::vector<IdxMBBPair>::const_iterator itr =
585 std::lower_bound(idx2MBBMap.begin(), idx2MBBMap.end(), start);
588 while (itr != idx2MBBMap.end()) {
589 if (itr->first >= end)
591 mbbs.push_back(itr->second);
598 /// Returns the MBB covering the given range, or null if the range covers
599 /// more than one basic block.
600 MachineBasicBlock* getMBBCoveringRange(SlotIndex start, SlotIndex end) const {
602 assert(start < end && "Backwards ranges not allowed.");
604 std::vector<IdxMBBPair>::const_iterator itr =
605 std::lower_bound(idx2MBBMap.begin(), idx2MBBMap.end(), start);
607 if (itr == idx2MBBMap.end()) {
612 // Check that we don't cross the boundary into this block.
613 if (itr->first < end)
618 if (itr->first <= start)
624 /// Insert the given machine instruction into the mapping. Returns the
626 SlotIndex insertMachineInstrInMaps(MachineInstr *mi,
627 bool *deferredRenumber = 0) {
628 assert(mi2iMap.find(mi) == mi2iMap.end() && "Instr already indexed.");
629 // Numbering DBG_VALUE instructions could cause code generation to be
630 // affected by debug information.
631 assert(!mi->isDebugValue() && "Cannot number DBG_VALUE instructions.");
633 MachineBasicBlock *mbb = mi->getParent();
635 assert(mbb != 0 && "Instr must be added to function.");
637 MBB2IdxMap::iterator mbbRangeItr = mbb2IdxMap.find(mbb);
639 assert(mbbRangeItr != mbb2IdxMap.end() &&
640 "Instruction's parent MBB has not been added to SlotIndexes.");
642 MachineBasicBlock::iterator miItr(mi);
643 bool needRenumber = false;
644 IndexListEntry *newEntry;
645 // Get previous index, considering that not all instructions are indexed.
646 IndexListEntry *prevEntry;
648 // If mi is at the mbb beginning, get the prev index from the mbb.
649 if (miItr == mbb->begin()) {
650 prevEntry = &mbbRangeItr->second.first.entry();
653 // Otherwise rewind until we find a mapped instruction.
654 Mi2IndexMap::const_iterator itr = mi2iMap.find(--miItr);
655 if (itr != mi2iMap.end()) {
656 prevEntry = &itr->second.entry();
661 // Get next entry from previous entry.
662 IndexListEntry *nextEntry = prevEntry->getNext();
664 // Get a number for the new instr, or 0 if there's no room currently.
665 // In the latter case we'll force a renumber later.
666 unsigned dist = nextEntry->getIndex() - prevEntry->getIndex();
667 unsigned newNumber = dist > SlotIndex::NUM ?
668 prevEntry->getIndex() + ((dist >> 1) & ~3U) : 0;
670 if (newNumber == 0) {
674 // Insert a new list entry for mi.
675 newEntry = createEntry(mi, newNumber);
676 insert(nextEntry, newEntry);
678 SlotIndex newIndex(newEntry, SlotIndex::LOAD);
679 mi2iMap.insert(std::make_pair(mi, newIndex));
681 if (miItr == mbb->end()) {
682 // If this is the last instr in the MBB then we need to fix up the bb
684 mbbRangeItr->second.second = SlotIndex(newEntry, SlotIndex::STORE);
687 // Renumber if we need to.
689 if (deferredRenumber == 0)
692 *deferredRenumber = true;
698 /// Add all instructions in the vector to the index list. This method will
699 /// defer renumbering until all instrs have been added, and should be
700 /// preferred when adding multiple instrs.
701 void insertMachineInstrsInMaps(SmallVectorImpl<MachineInstr*> &mis) {
702 bool renumber = false;
704 for (SmallVectorImpl<MachineInstr*>::iterator
705 miItr = mis.begin(), miEnd = mis.end();
706 miItr != miEnd; ++miItr) {
707 insertMachineInstrInMaps(*miItr, &renumber);
715 /// Remove the given machine instruction from the mapping.
716 void removeMachineInstrFromMaps(MachineInstr *mi) {
717 // remove index -> MachineInstr and
718 // MachineInstr -> index mappings
719 Mi2IndexMap::iterator mi2iItr = mi2iMap.find(mi);
720 if (mi2iItr != mi2iMap.end()) {
721 IndexListEntry *miEntry(&mi2iItr->second.entry());
722 assert(miEntry->getInstr() == mi && "Instruction indexes broken.");
723 // FIXME: Eventually we want to actually delete these indexes.
724 miEntry->setInstr(0);
725 mi2iMap.erase(mi2iItr);
729 /// ReplaceMachineInstrInMaps - Replacing a machine instr with a new one in
730 /// maps used by register allocator.
731 void replaceMachineInstrInMaps(MachineInstr *mi, MachineInstr *newMI) {
732 Mi2IndexMap::iterator mi2iItr = mi2iMap.find(mi);
733 if (mi2iItr == mi2iMap.end())
735 SlotIndex replaceBaseIndex = mi2iItr->second;
736 IndexListEntry *miEntry(&replaceBaseIndex.entry());
737 assert(miEntry->getInstr() == mi &&
738 "Mismatched instruction in index tables.");
739 miEntry->setInstr(newMI);
740 mi2iMap.erase(mi2iItr);
741 mi2iMap.insert(std::make_pair(newMI, replaceBaseIndex));
744 /// Add the given MachineBasicBlock into the maps.
745 void insertMBBInMaps(MachineBasicBlock *mbb) {
746 MachineFunction::iterator nextMBB =
747 llvm::next(MachineFunction::iterator(mbb));
748 IndexListEntry *startEntry = createEntry(0, 0);
749 IndexListEntry *stopEntry = createEntry(0, 0);
750 IndexListEntry *nextEntry = 0;
752 if (nextMBB == mbb->getParent()->end()) {
753 nextEntry = getTail();
755 nextEntry = &getMBBStartIdx(nextMBB).entry();
758 insert(nextEntry, startEntry);
759 insert(nextEntry, stopEntry);
761 SlotIndex startIdx(startEntry, SlotIndex::LOAD);
762 SlotIndex endIdx(nextEntry, SlotIndex::LOAD);
765 std::make_pair(mbb, std::make_pair(startIdx, endIdx)));
767 idx2MBBMap.push_back(IdxMBBPair(startIdx, mbb));
769 if (MachineFunction::iterator(mbb) != mbb->getParent()->begin()) {
770 // Have to update the end index of the previous block.
771 MachineBasicBlock *priorMBB =
772 llvm::prior(MachineFunction::iterator(mbb));
773 mbb2IdxMap[priorMBB].second = startIdx;
777 std::sort(idx2MBBMap.begin(), idx2MBBMap.end(), Idx2MBBCompare());
784 // Specialize IntervalMapInfo for half-open slot index intervals.
785 template <typename> struct IntervalMapInfo;
786 template <> struct IntervalMapInfo<SlotIndex> {
787 static inline bool startLess(const SlotIndex &x, const SlotIndex &a) {
790 static inline bool stopLess(const SlotIndex &b, const SlotIndex &x) {
793 static inline bool adjacent(const SlotIndex &a, const SlotIndex &b) {
800 #endif // LLVM_CODEGEN_LIVEINDEX_H