InterferenceCache.h 7.2 KB

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