Home | History | Annotate | Download | only in CodeGen
      1 //===-- InterferenceCache.h - Caching per-block interference ---*- C++ -*--===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // InterferenceCache remembers per-block interference from LiveIntervalUnions,
     11 // fixed RegUnit interference, and register masks.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #ifndef LLVM_CODEGEN_INTERFERENCECACHE
     16 #define LLVM_CODEGEN_INTERFERENCECACHE
     17 
     18 #include "llvm/CodeGen/LiveIntervalUnion.h"
     19 
     20 namespace llvm {
     21 
     22 class LiveIntervals;
     23 
     24 class InterferenceCache {
     25   const TargetRegisterInfo *TRI;
     26   LiveIntervalUnion *LIUArray;
     27   MachineFunction *MF;
     28 
     29   /// BlockInterference - information about the interference in a single basic
     30   /// block.
     31   struct BlockInterference {
     32     BlockInterference() : Tag(0) {}
     33     unsigned Tag;
     34     SlotIndex First;
     35     SlotIndex Last;
     36   };
     37 
     38   /// Entry - A cache entry containing interference information for all aliases
     39   /// of PhysReg in all basic blocks.
     40   class Entry {
     41     /// PhysReg - The register currently represented.
     42     unsigned PhysReg;
     43 
     44     /// Tag - Cache tag is changed when any of the underlying LiveIntervalUnions
     45     /// change.
     46     unsigned Tag;
     47 
     48     /// RefCount - The total number of Cursor instances referring to this Entry.
     49     unsigned RefCount;
     50 
     51     /// MF - The current function.
     52     MachineFunction *MF;
     53 
     54     /// Indexes - Mapping block numbers to SlotIndex ranges.
     55     SlotIndexes *Indexes;
     56 
     57     /// LIS - Used for accessing register mask interference maps.
     58     LiveIntervals *LIS;
     59 
     60     /// PrevPos - The previous position the iterators were moved to.
     61     SlotIndex PrevPos;
     62 
     63     /// RegUnitInfo - Information tracked about each RegUnit in PhysReg.
     64     /// When PrevPos is set, the iterators are valid as if advanceTo(PrevPos)
     65     /// had just been called.
     66     struct RegUnitInfo {
     67       /// Iterator pointing into the LiveIntervalUnion containing virtual
     68       /// register interference.
     69       LiveIntervalUnion::SegmentIter VirtI;
     70 
     71       /// Tag of the LIU last time we looked.
     72       unsigned VirtTag;
     73 
     74       /// Fixed interference in RegUnit.
     75       LiveInterval *Fixed;
     76 
     77       /// Iterator pointing into the fixed RegUnit interference.
     78       LiveInterval::iterator FixedI;
     79 
     80       RegUnitInfo(LiveIntervalUnion &LIU) : VirtTag(LIU.getTag()), Fixed(0) {
     81         VirtI.setMap(LIU.getMap());
     82       }
     83     };
     84 
     85     /// Info for each RegUnit in PhysReg. It is very rare ofr a PHysReg to have
     86     /// more than 4 RegUnits.
     87     SmallVector<RegUnitInfo, 4> RegUnits;
     88 
     89     /// Blocks - Interference for each block in the function.
     90     SmallVector<BlockInterference, 8> Blocks;
     91 
     92     /// update - Recompute Blocks[MBBNum]
     93     void update(unsigned MBBNum);
     94 
     95   public:
     96     Entry() : PhysReg(0), Tag(0), RefCount(0), Indexes(0), LIS(0) {}
     97 
     98     void clear(MachineFunction *mf, SlotIndexes *indexes, LiveIntervals *lis) {
     99       assert(!hasRefs() && "Cannot clear cache entry with references");
    100       PhysReg = 0;
    101       MF = mf;
    102       Indexes = indexes;
    103       LIS = lis;
    104     }
    105 
    106     unsigned getPhysReg() const { return PhysReg; }
    107 
    108     void addRef(int Delta) { RefCount += Delta; }
    109 
    110     bool hasRefs() const { return RefCount > 0; }
    111 
    112     void revalidate(LiveIntervalUnion *LIUArray, const TargetRegisterInfo *TRI);
    113 
    114     /// valid - Return true if this is a valid entry for physReg.
    115     bool valid(LiveIntervalUnion *LIUArray, const TargetRegisterInfo *TRI);
    116 
    117     /// reset - Initialize entry to represent physReg's aliases.
    118     void reset(unsigned physReg,
    119                LiveIntervalUnion *LIUArray,
    120                const TargetRegisterInfo *TRI,
    121                const MachineFunction *MF);
    122 
    123     /// get - Return an up to date BlockInterference.
    124     BlockInterference *get(unsigned MBBNum) {
    125       if (Blocks[MBBNum].Tag != Tag)
    126         update(MBBNum);
    127       return &Blocks[MBBNum];
    128     }
    129   };
    130 
    131   // We don't keep a cache entry for every physical register, that would use too
    132   // much memory. Instead, a fixed number of cache entries are used in a round-
    133   // robin manner.
    134   enum { CacheEntries = 32 };
    135 
    136   // Point to an entry for each physreg. The entry pointed to may not be up to
    137   // date, and it may have been reused for a different physreg.
    138   SmallVector<unsigned char, 2> PhysRegEntries;
    139 
    140   // Next round-robin entry to be picked.
    141   unsigned RoundRobin;
    142 
    143   // The actual cache entries.
    144   Entry Entries[CacheEntries];
    145 
    146   // get - Get a valid entry for PhysReg.
    147   Entry *get(unsigned PhysReg);
    148 
    149 public:
    150   InterferenceCache() : TRI(0), LIUArray(0), MF(0), RoundRobin(0) {}
    151 
    152   /// init - Prepare cache for a new function.
    153   void init(MachineFunction*, LiveIntervalUnion*, SlotIndexes*, LiveIntervals*,
    154             const TargetRegisterInfo *);
    155 
    156   /// getMaxCursors - Return the maximum number of concurrent cursors that can
    157   /// be supported.
    158   unsigned getMaxCursors() const { return CacheEntries; }
    159 
    160   /// Cursor - The primary query interface for the block interference cache.
    161   class Cursor {
    162     Entry *CacheEntry;
    163     BlockInterference *Current;
    164     static BlockInterference NoInterference;
    165 
    166     void setEntry(Entry *E) {
    167       Current = 0;
    168       // Update reference counts. Nothing happens when RefCount reaches 0, so
    169       // we don't have to check for E == CacheEntry etc.
    170       if (CacheEntry)
    171         CacheEntry->addRef(-1);
    172       CacheEntry = E;
    173       if (CacheEntry)
    174         CacheEntry->addRef(+1);
    175     }
    176 
    177   public:
    178     /// Cursor - Create a dangling cursor.
    179     Cursor() : CacheEntry(0), Current(0) {}
    180     ~Cursor() { setEntry(0); }
    181 
    182     Cursor(const Cursor &O) : CacheEntry(0), Current(0) {
    183       setEntry(O.CacheEntry);
    184     }
    185 
    186     Cursor &operator=(const Cursor &O) {
    187       setEntry(O.CacheEntry);
    188       return *this;
    189     }
    190 
    191     /// setPhysReg - Point this cursor to PhysReg's interference.
    192     void setPhysReg(InterferenceCache &Cache, unsigned PhysReg) {
    193       // Release reference before getting a new one. That guarantees we can
    194       // actually have CacheEntries live cursors.
    195       setEntry(0);
    196       if (PhysReg)
    197         setEntry(Cache.get(PhysReg));
    198     }
    199 
    200     /// moveTo - Move cursor to basic block MBBNum.
    201     void moveToBlock(unsigned MBBNum) {
    202       Current = CacheEntry ? CacheEntry->get(MBBNum) : &NoInterference;
    203     }
    204 
    205     /// hasInterference - Return true if the current block has any interference.
    206     bool hasInterference() {
    207       return Current->First.isValid();
    208     }
    209 
    210     /// first - Return the starting index of the first interfering range in the
    211     /// current block.
    212     SlotIndex first() {
    213       return Current->First;
    214     }
    215 
    216     /// last - Return the ending index of the last interfering range in the
    217     /// current block.
    218     SlotIndex last() {
    219       return Current->Last;
    220     }
    221   };
    222 
    223   friend class Cursor;
    224 };
    225 
    226 } // namespace llvm
    227 
    228 #endif
    229