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