LLVM API Documentation
00001 //===-- InterferenceCache.h - Caching per-block interference ---*- C++ -*--===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // InterferenceCache remembers per-block interference from LiveIntervalUnions, 00011 // fixed RegUnit interference, and register masks. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #ifndef LLVM_LIB_CODEGEN_INTERFERENCECACHE_H 00016 #define LLVM_LIB_CODEGEN_INTERFERENCECACHE_H 00017 00018 #include "llvm/CodeGen/LiveIntervalUnion.h" 00019 00020 namespace llvm { 00021 00022 class LiveIntervals; 00023 00024 class InterferenceCache { 00025 const TargetRegisterInfo *TRI; 00026 LiveIntervalUnion *LIUArray; 00027 MachineFunction *MF; 00028 00029 /// BlockInterference - information about the interference in a single basic 00030 /// block. 00031 struct BlockInterference { 00032 BlockInterference() : Tag(0) {} 00033 unsigned Tag; 00034 SlotIndex First; 00035 SlotIndex Last; 00036 }; 00037 00038 /// Entry - A cache entry containing interference information for all aliases 00039 /// of PhysReg in all basic blocks. 00040 class Entry { 00041 /// PhysReg - The register currently represented. 00042 unsigned PhysReg; 00043 00044 /// Tag - Cache tag is changed when any of the underlying LiveIntervalUnions 00045 /// change. 00046 unsigned Tag; 00047 00048 /// RefCount - The total number of Cursor instances referring to this Entry. 00049 unsigned RefCount; 00050 00051 /// MF - The current function. 00052 MachineFunction *MF; 00053 00054 /// Indexes - Mapping block numbers to SlotIndex ranges. 00055 SlotIndexes *Indexes; 00056 00057 /// LIS - Used for accessing register mask interference maps. 00058 LiveIntervals *LIS; 00059 00060 /// PrevPos - The previous position the iterators were moved to. 00061 SlotIndex PrevPos; 00062 00063 /// RegUnitInfo - Information tracked about each RegUnit in PhysReg. 00064 /// When PrevPos is set, the iterators are valid as if advanceTo(PrevPos) 00065 /// had just been called. 00066 struct RegUnitInfo { 00067 /// Iterator pointing into the LiveIntervalUnion containing virtual 00068 /// register interference. 00069 LiveIntervalUnion::SegmentIter VirtI; 00070 00071 /// Tag of the LIU last time we looked. 00072 unsigned VirtTag; 00073 00074 /// Fixed interference in RegUnit. 00075 LiveRange *Fixed; 00076 00077 /// Iterator pointing into the fixed RegUnit interference. 00078 LiveInterval::iterator FixedI; 00079 00080 RegUnitInfo(LiveIntervalUnion &LIU) 00081 : VirtTag(LIU.getTag()), Fixed(nullptr) { 00082 VirtI.setMap(LIU.getMap()); 00083 } 00084 }; 00085 00086 /// Info for each RegUnit in PhysReg. It is very rare ofr a PHysReg to have 00087 /// more than 4 RegUnits. 00088 SmallVector<RegUnitInfo, 4> RegUnits; 00089 00090 /// Blocks - Interference for each block in the function. 00091 SmallVector<BlockInterference, 8> Blocks; 00092 00093 /// update - Recompute Blocks[MBBNum] 00094 void update(unsigned MBBNum); 00095 00096 public: 00097 Entry() : PhysReg(0), Tag(0), RefCount(0), Indexes(nullptr), LIS(nullptr) {} 00098 00099 void clear(MachineFunction *mf, SlotIndexes *indexes, LiveIntervals *lis) { 00100 assert(!hasRefs() && "Cannot clear cache entry with references"); 00101 PhysReg = 0; 00102 MF = mf; 00103 Indexes = indexes; 00104 LIS = lis; 00105 } 00106 00107 unsigned getPhysReg() const { return PhysReg; } 00108 00109 void addRef(int Delta) { RefCount += Delta; } 00110 00111 bool hasRefs() const { return RefCount > 0; } 00112 00113 void revalidate(LiveIntervalUnion *LIUArray, const TargetRegisterInfo *TRI); 00114 00115 /// valid - Return true if this is a valid entry for physReg. 00116 bool valid(LiveIntervalUnion *LIUArray, const TargetRegisterInfo *TRI); 00117 00118 /// reset - Initialize entry to represent physReg's aliases. 00119 void reset(unsigned physReg, 00120 LiveIntervalUnion *LIUArray, 00121 const TargetRegisterInfo *TRI, 00122 const MachineFunction *MF); 00123 00124 /// get - Return an up to date BlockInterference. 00125 BlockInterference *get(unsigned MBBNum) { 00126 if (Blocks[MBBNum].Tag != Tag) 00127 update(MBBNum); 00128 return &Blocks[MBBNum]; 00129 } 00130 }; 00131 00132 // We don't keep a cache entry for every physical register, that would use too 00133 // much memory. Instead, a fixed number of cache entries are used in a round- 00134 // robin manner. 00135 enum { CacheEntries = 32 }; 00136 00137 // Point to an entry for each physreg. The entry pointed to may not be up to 00138 // date, and it may have been reused for a different physreg. 00139 unsigned char* PhysRegEntries; 00140 size_t PhysRegEntriesCount; 00141 00142 // Next round-robin entry to be picked. 00143 unsigned RoundRobin; 00144 00145 // The actual cache entries. 00146 Entry Entries[CacheEntries]; 00147 00148 // get - Get a valid entry for PhysReg. 00149 Entry *get(unsigned PhysReg); 00150 00151 public: 00152 InterferenceCache() 00153 : TRI(nullptr), LIUArray(nullptr), MF(nullptr), PhysRegEntries(nullptr), 00154 PhysRegEntriesCount(0), RoundRobin(0) {} 00155 00156 ~InterferenceCache() { 00157 free(PhysRegEntries); 00158 } 00159 00160 void reinitPhysRegEntries(); 00161 00162 /// init - Prepare cache for a new function. 00163 void init(MachineFunction*, LiveIntervalUnion*, SlotIndexes*, LiveIntervals*, 00164 const TargetRegisterInfo *); 00165 00166 /// getMaxCursors - Return the maximum number of concurrent cursors that can 00167 /// be supported. 00168 unsigned getMaxCursors() const { return CacheEntries; } 00169 00170 /// Cursor - The primary query interface for the block interference cache. 00171 class Cursor { 00172 Entry *CacheEntry; 00173 BlockInterference *Current; 00174 static BlockInterference NoInterference; 00175 00176 void setEntry(Entry *E) { 00177 Current = nullptr; 00178 // Update reference counts. Nothing happens when RefCount reaches 0, so 00179 // we don't have to check for E == CacheEntry etc. 00180 if (CacheEntry) 00181 CacheEntry->addRef(-1); 00182 CacheEntry = E; 00183 if (CacheEntry) 00184 CacheEntry->addRef(+1); 00185 } 00186 00187 public: 00188 /// Cursor - Create a dangling cursor. 00189 Cursor() : CacheEntry(nullptr), Current(nullptr) {} 00190 ~Cursor() { setEntry(nullptr); } 00191 00192 Cursor(const Cursor &O) : CacheEntry(nullptr), Current(nullptr) { 00193 setEntry(O.CacheEntry); 00194 } 00195 00196 Cursor &operator=(const Cursor &O) { 00197 setEntry(O.CacheEntry); 00198 return *this; 00199 } 00200 00201 /// setPhysReg - Point this cursor to PhysReg's interference. 00202 void setPhysReg(InterferenceCache &Cache, unsigned PhysReg) { 00203 // Release reference before getting a new one. That guarantees we can 00204 // actually have CacheEntries live cursors. 00205 setEntry(nullptr); 00206 if (PhysReg) 00207 setEntry(Cache.get(PhysReg)); 00208 } 00209 00210 /// moveTo - Move cursor to basic block MBBNum. 00211 void moveToBlock(unsigned MBBNum) { 00212 Current = CacheEntry ? CacheEntry->get(MBBNum) : &NoInterference; 00213 } 00214 00215 /// hasInterference - Return true if the current block has any interference. 00216 bool hasInterference() { 00217 return Current->First.isValid(); 00218 } 00219 00220 /// first - Return the starting index of the first interfering range in the 00221 /// current block. 00222 SlotIndex first() { 00223 return Current->First; 00224 } 00225 00226 /// last - Return the ending index of the last interfering range in the 00227 /// current block. 00228 SlotIndex last() { 00229 return Current->Last; 00230 } 00231 }; 00232 00233 friend class Cursor; 00234 }; 00235 00236 } // namespace llvm 00237 00238 #endif