InterferenceCache.h revision 6ef7da0197735a16aa534e9e2c80709d3d6e8c56
15907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen//===-- InterferenceCache.h - Caching per-block interference ---*- C++ -*--===//
25907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen//
35907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen//                     The LLVM Compiler Infrastructure
45907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen//
55907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen// This file is distributed under the University of Illinois Open Source
65907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen// License. See LICENSE.TXT for details.
75907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen//
85907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen//===----------------------------------------------------------------------===//
95907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen//
105907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen// InterferenceCache remembers per-block interference in LiveIntervalUnions.
115907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen//
125907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen//===----------------------------------------------------------------------===//
135907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen
145907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen#ifndef LLVM_CODEGEN_INTERFERENCECACHE
155907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen#define LLVM_CODEGEN_INTERFERENCECACHE
165907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen
175907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen#include "LiveIntervalUnion.h"
185907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen
195907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesennamespace llvm {
205907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen
216ef7da0197735a16aa534e9e2c80709d3d6e8c56Jakob Stoklund Olesenclass LiveIntervals;
226ef7da0197735a16aa534e9e2c80709d3d6e8c56Jakob Stoklund Olesen
235907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesenclass InterferenceCache {
245907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen  const TargetRegisterInfo *TRI;
255907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen  LiveIntervalUnion *LIUArray;
265907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen  MachineFunction *MF;
275907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen
285907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen  /// BlockInterference - information about the interference in a single basic
295907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen  /// block.
305907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen  struct BlockInterference {
315907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    BlockInterference() : Tag(0) {}
325907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    unsigned Tag;
335907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    SlotIndex First;
345907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    SlotIndex Last;
355907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen  };
365907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen
375907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen  /// Entry - A cache entry containing interference information for all aliases
385907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen  /// of PhysReg in all basic blocks.
395907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen  class Entry {
405907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    /// PhysReg - The register currently represented.
415907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    unsigned PhysReg;
425907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen
435907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    /// Tag - Cache tag is changed when any of the underlying LiveIntervalUnions
445907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    /// change.
455907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    unsigned Tag;
465907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen
47f1c709837bd11c5383fce3b8a026a7c8eaabba86Jakob Stoklund Olesen    /// RefCount - The total number of Cursor instances referring to this Entry.
48f1c709837bd11c5383fce3b8a026a7c8eaabba86Jakob Stoklund Olesen    unsigned RefCount;
49f1c709837bd11c5383fce3b8a026a7c8eaabba86Jakob Stoklund Olesen
509d29cbad32814f31c91cd2464a3c74df412b0aacJakob Stoklund Olesen    /// MF - The current function.
519d29cbad32814f31c91cd2464a3c74df412b0aacJakob Stoklund Olesen    MachineFunction *MF;
529d29cbad32814f31c91cd2464a3c74df412b0aacJakob Stoklund Olesen
535907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    /// Indexes - Mapping block numbers to SlotIndex ranges.
545907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    SlotIndexes *Indexes;
555907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen
566ef7da0197735a16aa534e9e2c80709d3d6e8c56Jakob Stoklund Olesen    /// LIS - Used for accessing register mask interference maps.
576ef7da0197735a16aa534e9e2c80709d3d6e8c56Jakob Stoklund Olesen    LiveIntervals *LIS;
586ef7da0197735a16aa534e9e2c80709d3d6e8c56Jakob Stoklund Olesen
595907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    /// PrevPos - The previous position the iterators were moved to.
605907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    SlotIndex PrevPos;
615907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen
625907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    /// AliasTags - A LiveIntervalUnion pointer and tag for each alias of
635907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    /// PhysReg.
645907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    SmallVector<std::pair<LiveIntervalUnion*, unsigned>, 8> Aliases;
655907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen
665907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    typedef LiveIntervalUnion::SegmentIter Iter;
675907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen
685907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    /// Iters - an iterator for each alias
695907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    SmallVector<Iter, 8> Iters;
705907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen
715907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    /// Blocks - Interference for each block in the function.
725907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    SmallVector<BlockInterference, 8> Blocks;
735907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen
745907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    /// update - Recompute Blocks[MBBNum]
755907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    void update(unsigned MBBNum);
765907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen
775907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen  public:
786ef7da0197735a16aa534e9e2c80709d3d6e8c56Jakob Stoklund Olesen    Entry() : PhysReg(0), Tag(0), RefCount(0), Indexes(0), LIS(0) {}
795907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen
806ef7da0197735a16aa534e9e2c80709d3d6e8c56Jakob Stoklund Olesen    void clear(MachineFunction *mf, SlotIndexes *indexes, LiveIntervals *lis) {
81f1c709837bd11c5383fce3b8a026a7c8eaabba86Jakob Stoklund Olesen      assert(!hasRefs() && "Cannot clear cache entry with references");
825907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen      PhysReg = 0;
839d29cbad32814f31c91cd2464a3c74df412b0aacJakob Stoklund Olesen      MF = mf;
845907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen      Indexes = indexes;
856ef7da0197735a16aa534e9e2c80709d3d6e8c56Jakob Stoklund Olesen      LIS = lis;
865907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    }
875907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen
885907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    unsigned getPhysReg() const { return PhysReg; }
895907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen
90f1c709837bd11c5383fce3b8a026a7c8eaabba86Jakob Stoklund Olesen    void addRef(int Delta) { RefCount += Delta; }
91f1c709837bd11c5383fce3b8a026a7c8eaabba86Jakob Stoklund Olesen
92f1c709837bd11c5383fce3b8a026a7c8eaabba86Jakob Stoklund Olesen    bool hasRefs() const { return RefCount > 0; }
93f1c709837bd11c5383fce3b8a026a7c8eaabba86Jakob Stoklund Olesen
945907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    void revalidate();
955907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen
965907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    /// valid - Return true if this is a valid entry for physReg.
975907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    bool valid(LiveIntervalUnion *LIUArray, const TargetRegisterInfo *TRI);
985907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen
995907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    /// reset - Initialize entry to represent physReg's aliases.
1005907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    void reset(unsigned physReg,
1015907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen               LiveIntervalUnion *LIUArray,
1025907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen               const TargetRegisterInfo *TRI,
1035907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen               const MachineFunction *MF);
1045907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen
1055907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    /// get - Return an up to date BlockInterference.
1065907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    BlockInterference *get(unsigned MBBNum) {
1075907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen      if (Blocks[MBBNum].Tag != Tag)
1085907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen        update(MBBNum);
1095907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen      return &Blocks[MBBNum];
1105907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    }
1115907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen  };
1125907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen
1135907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen  // We don't keep a cache entry for every physical register, that would use too
1145907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen  // much memory. Instead, a fixed number of cache entries are used in a round-
1155907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen  // robin manner.
1165907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen  enum { CacheEntries = 32 };
1175907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen
1185907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen  // Point to an entry for each physreg. The entry pointed to may not be up to
1195907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen  // date, and it may have been reused for a different physreg.
1205907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen  SmallVector<unsigned char, 2> PhysRegEntries;
1215907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen
1225907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen  // Next round-robin entry to be picked.
1235907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen  unsigned RoundRobin;
1245907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen
1255907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen  // The actual cache entries.
1265907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen  Entry Entries[CacheEntries];
1275907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen
1285907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen  // get - Get a valid entry for PhysReg.
1295907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen  Entry *get(unsigned PhysReg);
1305907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen
1315907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesenpublic:
1323bf7a1cc3c090e766b8912c6a14c3e2ec5dde7f8Jakob Stoklund Olesen  InterferenceCache() : TRI(0), LIUArray(0), MF(0), RoundRobin(0) {}
1335907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen
1345907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen  /// init - Prepare cache for a new function.
1356ef7da0197735a16aa534e9e2c80709d3d6e8c56Jakob Stoklund Olesen  void init(MachineFunction*, LiveIntervalUnion*, SlotIndexes*, LiveIntervals*,
1365907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen            const TargetRegisterInfo *);
1375907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen
138f1c709837bd11c5383fce3b8a026a7c8eaabba86Jakob Stoklund Olesen  /// getMaxCursors - Return the maximum number of concurrent cursors that can
139f1c709837bd11c5383fce3b8a026a7c8eaabba86Jakob Stoklund Olesen  /// be supported.
140f1c709837bd11c5383fce3b8a026a7c8eaabba86Jakob Stoklund Olesen  unsigned getMaxCursors() const { return CacheEntries; }
141f1c709837bd11c5383fce3b8a026a7c8eaabba86Jakob Stoklund Olesen
1425907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen  /// Cursor - The primary query interface for the block interference cache.
1435907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen  class Cursor {
1445907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    Entry *CacheEntry;
1455907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    BlockInterference *Current;
146c7931fd725b390142f9112952b1426560000e6b4Jakob Stoklund Olesen    static BlockInterference NoInterference;
147f1c709837bd11c5383fce3b8a026a7c8eaabba86Jakob Stoklund Olesen
148f1c709837bd11c5383fce3b8a026a7c8eaabba86Jakob Stoklund Olesen    void setEntry(Entry *E) {
149f1c709837bd11c5383fce3b8a026a7c8eaabba86Jakob Stoklund Olesen      Current = 0;
150f1c709837bd11c5383fce3b8a026a7c8eaabba86Jakob Stoklund Olesen      // Update reference counts. Nothing happens when RefCount reaches 0, so
151f1c709837bd11c5383fce3b8a026a7c8eaabba86Jakob Stoklund Olesen      // we don't have to check for E == CacheEntry etc.
152f1c709837bd11c5383fce3b8a026a7c8eaabba86Jakob Stoklund Olesen      if (CacheEntry)
153f1c709837bd11c5383fce3b8a026a7c8eaabba86Jakob Stoklund Olesen        CacheEntry->addRef(-1);
154f1c709837bd11c5383fce3b8a026a7c8eaabba86Jakob Stoklund Olesen      CacheEntry = E;
155f1c709837bd11c5383fce3b8a026a7c8eaabba86Jakob Stoklund Olesen      if (CacheEntry)
156f1c709837bd11c5383fce3b8a026a7c8eaabba86Jakob Stoklund Olesen        CacheEntry->addRef(+1);
157f1c709837bd11c5383fce3b8a026a7c8eaabba86Jakob Stoklund Olesen    }
158f1c709837bd11c5383fce3b8a026a7c8eaabba86Jakob Stoklund Olesen
1595907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen  public:
160c66a37df73f70ec3dbed06277763624f33ee3512Jakob Stoklund Olesen    /// Cursor - Create a dangling cursor.
161c66a37df73f70ec3dbed06277763624f33ee3512Jakob Stoklund Olesen    Cursor() : CacheEntry(0), Current(0) {}
162f1c709837bd11c5383fce3b8a026a7c8eaabba86Jakob Stoklund Olesen    ~Cursor() { setEntry(0); }
163f1c709837bd11c5383fce3b8a026a7c8eaabba86Jakob Stoklund Olesen
164f1c709837bd11c5383fce3b8a026a7c8eaabba86Jakob Stoklund Olesen    Cursor(const Cursor &O) : CacheEntry(0), Current(0) {
165f1c709837bd11c5383fce3b8a026a7c8eaabba86Jakob Stoklund Olesen      setEntry(O.CacheEntry);
166f1c709837bd11c5383fce3b8a026a7c8eaabba86Jakob Stoklund Olesen    }
167f1c709837bd11c5383fce3b8a026a7c8eaabba86Jakob Stoklund Olesen
168f1c709837bd11c5383fce3b8a026a7c8eaabba86Jakob Stoklund Olesen    Cursor &operator=(const Cursor &O) {
169f1c709837bd11c5383fce3b8a026a7c8eaabba86Jakob Stoklund Olesen      setEntry(O.CacheEntry);
170f1c709837bd11c5383fce3b8a026a7c8eaabba86Jakob Stoklund Olesen      return *this;
171f1c709837bd11c5383fce3b8a026a7c8eaabba86Jakob Stoklund Olesen    }
172c66a37df73f70ec3dbed06277763624f33ee3512Jakob Stoklund Olesen
173c66a37df73f70ec3dbed06277763624f33ee3512Jakob Stoklund Olesen    /// setPhysReg - Point this cursor to PhysReg's interference.
174c66a37df73f70ec3dbed06277763624f33ee3512Jakob Stoklund Olesen    void setPhysReg(InterferenceCache &Cache, unsigned PhysReg) {
175f1c709837bd11c5383fce3b8a026a7c8eaabba86Jakob Stoklund Olesen      // Release reference before getting a new one. That guarantees we can
176f1c709837bd11c5383fce3b8a026a7c8eaabba86Jakob Stoklund Olesen      // actually have CacheEntries live cursors.
177f1c709837bd11c5383fce3b8a026a7c8eaabba86Jakob Stoklund Olesen      setEntry(0);
178f1c709837bd11c5383fce3b8a026a7c8eaabba86Jakob Stoklund Olesen      if (PhysReg)
179f1c709837bd11c5383fce3b8a026a7c8eaabba86Jakob Stoklund Olesen        setEntry(Cache.get(PhysReg));
180c66a37df73f70ec3dbed06277763624f33ee3512Jakob Stoklund Olesen    }
1815907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen
1825907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    /// moveTo - Move cursor to basic block MBBNum.
1835907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    void moveToBlock(unsigned MBBNum) {
184c7931fd725b390142f9112952b1426560000e6b4Jakob Stoklund Olesen      Current = CacheEntry ? CacheEntry->get(MBBNum) : &NoInterference;
1855907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    }
1865907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen
1875907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    /// hasInterference - Return true if the current block has any interference.
1885907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    bool hasInterference() {
1895907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen      return Current->First.isValid();
1905907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    }
1915907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen
1925907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    /// first - Return the starting index of the first interfering range in the
1935907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    /// current block.
1945907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    SlotIndex first() {
1955907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen      return Current->First;
1965907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    }
1975907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen
1985907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    /// last - Return the ending index of the last interfering range in the
1995907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    /// current block.
2005907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    SlotIndex last() {
2015907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen      return Current->Last;
2025907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen    }
2035907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen  };
2045907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen
2055907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen  friend class Cursor;
2065907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen};
2075907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen
2085907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen} // namespace llvm
2095907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen
2105907d863659eb972ebb2afe07bc863a4c616f0efJakob Stoklund Olesen#endif
211