InterferenceCache.h 7.1 KB

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