LLVM  3.7.0
InterferenceCache.h
Go to the documentation of this file.
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_LIB_CODEGEN_INTERFERENCECACHE_H
16 #define LLVM_LIB_CODEGEN_INTERFERENCECACHE_H
17 
19 
20 namespace llvm {
21 
22 class LiveIntervals;
23 
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.
70 
71  /// Tag of the LIU last time we looked.
72  unsigned VirtTag;
73 
74  /// Fixed interference in RegUnit.
75  LiveRange *Fixed;
76 
77  /// Iterator pointing into the fixed RegUnit interference.
79 
80  RegUnitInfo(LiveIntervalUnion &LIU)
81  : VirtTag(LIU.getTag()), Fixed(nullptr) {
82  VirtI.setMap(LIU.getMap());
83  }
84  };
85 
86  /// Info for each RegUnit in PhysReg. It is very rare ofr a PHysReg to have
87  /// more than 4 RegUnits.
89 
90  /// Blocks - Interference for each block in the function.
92 
93  /// update - Recompute Blocks[MBBNum]
94  void update(unsigned MBBNum);
95 
96  public:
97  Entry() : PhysReg(0), Tag(0), RefCount(0), Indexes(nullptr), LIS(nullptr) {}
98 
99  void clear(MachineFunction *mf, SlotIndexes *indexes, LiveIntervals *lis) {
100  assert(!hasRefs() && "Cannot clear cache entry with references");
101  PhysReg = 0;
102  MF = mf;
103  Indexes = indexes;
104  LIS = lis;
105  }
106 
107  unsigned getPhysReg() const { return PhysReg; }
108 
109  void addRef(int Delta) { RefCount += Delta; }
110 
111  bool hasRefs() const { return RefCount > 0; }
112 
113  void revalidate(LiveIntervalUnion *LIUArray, const TargetRegisterInfo *TRI);
114 
115  /// valid - Return true if this is a valid entry for physReg.
116  bool valid(LiveIntervalUnion *LIUArray, const TargetRegisterInfo *TRI);
117 
118  /// reset - Initialize entry to represent physReg's aliases.
119  void reset(unsigned physReg,
120  LiveIntervalUnion *LIUArray,
121  const TargetRegisterInfo *TRI,
122  const MachineFunction *MF);
123 
124  /// get - Return an up to date BlockInterference.
125  BlockInterference *get(unsigned MBBNum) {
126  if (Blocks[MBBNum].Tag != Tag)
127  update(MBBNum);
128  return &Blocks[MBBNum];
129  }
130  };
131 
132  // We don't keep a cache entry for every physical register, that would use too
133  // much memory. Instead, a fixed number of cache entries are used in a round-
134  // robin manner.
135  enum { CacheEntries = 32 };
136 
137  // Point to an entry for each physreg. The entry pointed to may not be up to
138  // date, and it may have been reused for a different physreg.
139  unsigned char* PhysRegEntries;
140  size_t PhysRegEntriesCount;
141 
142  // Next round-robin entry to be picked.
143  unsigned RoundRobin;
144 
145  // The actual cache entries.
146  Entry Entries[CacheEntries];
147 
148  // get - Get a valid entry for PhysReg.
149  Entry *get(unsigned PhysReg);
150 
151 public:
153  : TRI(nullptr), LIUArray(nullptr), MF(nullptr), PhysRegEntries(nullptr),
154  PhysRegEntriesCount(0), RoundRobin(0) {}
155 
157  free(PhysRegEntries);
158  }
159 
160  void reinitPhysRegEntries();
161 
162  /// init - Prepare cache for a new function.
164  const TargetRegisterInfo *);
165 
166  /// getMaxCursors - Return the maximum number of concurrent cursors that can
167  /// be supported.
168  unsigned getMaxCursors() const { return CacheEntries; }
169 
170  /// Cursor - The primary query interface for the block interference cache.
171  class Cursor {
172  Entry *CacheEntry;
173  const BlockInterference *Current;
174  static const BlockInterference NoInterference;
175 
176  void setEntry(Entry *E) {
177  Current = nullptr;
178  // Update reference counts. Nothing happens when RefCount reaches 0, so
179  // we don't have to check for E == CacheEntry etc.
180  if (CacheEntry)
181  CacheEntry->addRef(-1);
182  CacheEntry = E;
183  if (CacheEntry)
184  CacheEntry->addRef(+1);
185  }
186 
187  public:
188  /// Cursor - Create a dangling cursor.
189  Cursor() : CacheEntry(nullptr), Current(nullptr) {}
190  ~Cursor() { setEntry(nullptr); }
191 
192  Cursor(const Cursor &O) : CacheEntry(nullptr), Current(nullptr) {
193  setEntry(O.CacheEntry);
194  }
195 
196  Cursor &operator=(const Cursor &O) {
197  setEntry(O.CacheEntry);
198  return *this;
199  }
200 
201  /// setPhysReg - Point this cursor to PhysReg's interference.
202  void setPhysReg(InterferenceCache &Cache, unsigned PhysReg) {
203  // Release reference before getting a new one. That guarantees we can
204  // actually have CacheEntries live cursors.
205  setEntry(nullptr);
206  if (PhysReg)
207  setEntry(Cache.get(PhysReg));
208  }
209 
210  /// moveTo - Move cursor to basic block MBBNum.
211  void moveToBlock(unsigned MBBNum) {
212  Current = CacheEntry ? CacheEntry->get(MBBNum) : &NoInterference;
213  }
214 
215  /// hasInterference - Return true if the current block has any interference.
217  return Current->First.isValid();
218  }
219 
220  /// first - Return the starting index of the first interfering range in the
221  /// current block.
223  return Current->First;
224  }
225 
226  /// last - Return the ending index of the last interfering range in the
227  /// current block.
229  return Current->Last;
230  }
231  };
232 
233  friend class Cursor;
234 };
235 
236 } // namespace llvm
237 
238 #endif
void setPhysReg(InterferenceCache &Cache, unsigned PhysReg)
setPhysReg - Point this cursor to PhysReg's interference.
Cursor()
Cursor - Create a dangling cursor.
This class represents the liveness of a register, stack slot, etc.
Definition: LiveInterval.h:153
SlotIndexes pass.
Definition: SlotIndexes.h:334
SlotIndex last()
last - Return the ending index of the last interfering range in the current block.
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:325
Cursor - The primary query interface for the block interference cache.
unsigned getTag() const
getTag - Return an opaque tag representing the current state of the union.
Union of live intervals that are strong candidates for coalescing into a single register (either phys...
#define LLVM_LIBRARY_VISIBILITY
LLVM_LIBRARY_VISIBILITY - If a class marked with this attribute is linked into a shared library...
Definition: Compiler.h:110
unsigned getMaxCursors() const
getMaxCursors - Return the maximum number of concurrent cursors that can be supported.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
bool hasInterference()
hasInterference - Return true if the current block has any interference.
LiveSegments::iterator SegmentIter
void moveToBlock(unsigned MBBNum)
moveTo - Move cursor to basic block MBBNum.
Cursor & operator=(const Cursor &O)
SlotIndex - An opaque wrapper around machine indexes.
Definition: SlotIndexes.h:92
SlotIndex first()
first - Return the starting index of the first interfering range in the current block.