LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RegisterPressure.h
Go to the documentation of this file.
1 //===-- RegisterPressure.h - Dynamic Register Pressure -*- 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 // This file defines the RegisterPressure class which can be used to track
11 // MachineInstr level register pressure.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_CODEGEN_REGISTERPRESSURE_H
16 #define LLVM_CODEGEN_REGISTERPRESSURE_H
17 
18 #include "llvm/ADT/SparseSet.h"
21 
22 namespace llvm {
23 
24 class LiveIntervals;
25 class LiveRange;
26 class RegisterClassInfo;
27 class MachineInstr;
28 
29 /// Base class for register pressure results.
31  /// Map of max reg pressure indexed by pressure set ID, not class ID.
32  std::vector<unsigned> MaxSetPressure;
33 
34  /// List of live in virtual registers or physical register units.
37 
38  /// Increase register pressure for each pressure set impacted by this register
39  /// class. Normally called by RegPressureTracker, but may be called manually
40  /// to account for live through (global liveness).
41  ///
42  /// \param Reg is either a virtual register number or register unit number.
43  void increase(unsigned Reg, const TargetRegisterInfo *TRI,
44  const MachineRegisterInfo *MRI);
45 
46  /// Decrease register pressure for each pressure set impacted by this register
47  /// class. This is only useful to account for spilling or rematerialization.
48  ///
49  /// \param Reg is either a virtual register number or register unit number.
50  void decrease(unsigned Reg, const TargetRegisterInfo *TRI,
51  const MachineRegisterInfo *MRI);
52 
53  void dump(const TargetRegisterInfo *TRI) const;
54 };
55 
56 /// RegisterPressure computed within a region of instructions delimited by
57 /// TopIdx and BottomIdx. During pressure computation, the maximum pressure per
58 /// register pressure set is increased. Once pressure within a region is fully
59 /// computed, the live-in and live-out sets are recorded.
60 ///
61 /// This is preferable to RegionPressure when LiveIntervals are available,
62 /// because delimiting regions by SlotIndex is more robust and convenient than
63 /// holding block iterators. The block contents can change without invalidating
64 /// the pressure result.
66  /// Record the boundary of the region being tracked.
69 
70  void reset();
71 
72  void openTop(SlotIndex NextTop);
73 
74  void openBottom(SlotIndex PrevBottom);
75 };
76 
77 /// RegisterPressure computed within a region of instructions delimited by
78 /// TopPos and BottomPos. This is a less precise version of IntervalPressure for
79 /// use when LiveIntervals are unavailable.
81  /// Record the boundary of the region being tracked.
84 
85  void reset();
86 
88 
90 };
91 
92 /// Capture a change in pressure for a single pressure set. UnitInc may be
93 /// expressed in terms of upward or downward pressure depending on the client
94 /// and will be dynamically adjusted for current liveness.
95 ///
96 /// Pressure increments are tiny, typically 1-2 units, and this is only for
97 /// heuristics, so we don't check UnitInc overflow. Instead, we may have a
98 /// higher level assert that pressure is consistent within a region. We also
99 /// effectively ignore dead defs which don't affect heuristics much.
101  uint16_t PSetID; // ID+1. 0=Invalid.
102  int16_t UnitInc;
103 public:
104  PressureChange(): PSetID(0), UnitInc(0) {}
105  PressureChange(unsigned id): PSetID(id+1), UnitInc(0) {
106  assert(id < UINT16_MAX && "PSetID overflow.");
107  }
108 
109  bool isValid() const { return PSetID > 0; }
110 
111  unsigned getPSet() const {
112  assert(isValid() && "invalid PressureChange");
113  return PSetID - 1;
114  }
115  // If PSetID is invalid, return UINT16_MAX to give it lowest priority.
116  unsigned getPSetOrMax() const { return (PSetID - 1) & UINT16_MAX; }
117 
118  int getUnitInc() const { return UnitInc; }
119 
120  void setUnitInc(int Inc) { UnitInc = Inc; }
121 
122  bool operator==(const PressureChange &RHS) const {
123  return PSetID == RHS.PSetID && UnitInc == RHS.UnitInc;
124  }
125 };
126 
127 template <> struct isPodLike<PressureChange> {
128  static const bool value = true;
129 };
130 
131 /// List of PressureChanges in order of increasing, unique PSetID.
132 ///
133 /// Use a small fixed number, because we can fit more PressureChanges in an
134 /// empty SmallVector than ever need to be tracked per register class. If more
135 /// PSets are affected, then we only track the most constrained.
137  // The initial design was for MaxPSets=4, but that requires PSet partitions,
138  // which are not yet implemented. (PSet partitions are equivalent PSets given
139  // the register classes actually in use within the scheduling region.)
140  enum { MaxPSets = 16 };
141 
142  PressureChange PressureChanges[MaxPSets];
143 public:
146  iterator begin() { return &PressureChanges[0]; }
147  iterator end() { return &PressureChanges[MaxPSets]; }
148  const_iterator begin() const { return &PressureChanges[0]; }
149  const_iterator end() const { return &PressureChanges[MaxPSets]; }
150 
151  void addPressureChange(unsigned RegUnit, bool IsDec,
152  const MachineRegisterInfo *MRI);
153 };
154 
155 /// Array of PressureDiffs.
157  PressureDiff *PDiffArray;
158  unsigned Size;
159  unsigned Max;
160 public:
161  PressureDiffs(): PDiffArray(0), Size(0), Max(0) {}
162  ~PressureDiffs() { free(PDiffArray); }
163 
164  void clear() { Size = 0; }
165 
166  void init(unsigned N);
167 
168  PressureDiff &operator[](unsigned Idx) {
169  assert(Idx < Size && "PressureDiff index out of bounds");
170  return PDiffArray[Idx];
171  }
172  const PressureDiff &operator[](unsigned Idx) const {
173  return const_cast<PressureDiffs*>(this)->operator[](Idx);
174  }
175 };
176 
177 /// Store the effects of a change in pressure on things that MI scheduler cares
178 /// about.
179 ///
180 /// Excess records the value of the largest difference in register units beyond
181 /// the target's pressure limits across the affected pressure sets, where
182 /// largest is defined as the absolute value of the difference. Negative
183 /// ExcessUnits indicates a reduction in pressure that had already exceeded the
184 /// target's limits.
185 ///
186 /// CriticalMax records the largest increase in the tracker's max pressure that
187 /// exceeds the critical limit for some pressure set determined by the client.
188 ///
189 /// CurrentMax records the largest increase in the tracker's max pressure that
190 /// exceeds the current limit for some pressure set determined by the client.
195 
197 
198  bool operator==(const RegPressureDelta &RHS) const {
199  return Excess == RHS.Excess && CriticalMax == RHS.CriticalMax
200  && CurrentMax == RHS.CurrentMax;
201  }
202  bool operator!=(const RegPressureDelta &RHS) const {
203  return !operator==(RHS);
204  }
205 };
206 
207 /// \brief A set of live virtual registers and physical register units.
208 ///
209 /// Virtual and physical register numbers require separate sparse sets, but most
210 /// of the RegisterPressureTracker handles them uniformly.
211 struct LiveRegSet {
214 
215  bool contains(unsigned Reg) const {
217  return VirtRegs.count(Reg);
218  return PhysRegs.count(Reg);
219  }
220 
221  bool insert(unsigned Reg) {
223  return VirtRegs.insert(Reg).second;
224  return PhysRegs.insert(Reg).second;
225  }
226 
227  bool erase(unsigned Reg) {
229  return VirtRegs.erase(Reg);
230  return PhysRegs.erase(Reg);
231  }
232 };
233 
234 /// Track the current register pressure at some position in the instruction
235 /// stream, and remember the high water mark within the region traversed. This
236 /// does not automatically consider live-through ranges. The client may
237 /// independently adjust for global liveness.
238 ///
239 /// Each RegPressureTracker only works within a MachineBasicBlock. Pressure can
240 /// be tracked across a larger region by storing a RegisterPressure result at
241 /// each block boundary and explicitly adjusting pressure to account for block
242 /// live-in and live-out register sets.
243 ///
244 /// RegPressureTracker holds a reference to a RegisterPressure result that it
245 /// computes incrementally. During downward tracking, P.BottomIdx or P.BottomPos
246 /// is invalid until it reaches the end of the block or closeRegion() is
247 /// explicitly called. Similarly, P.TopIdx is invalid during upward
248 /// tracking. Changing direction has the side effect of closing region, and
249 /// traversing past TopIdx or BottomIdx reopens it.
251  const MachineFunction *MF;
252  const TargetRegisterInfo *TRI;
253  const RegisterClassInfo *RCI;
254  const MachineRegisterInfo *MRI;
255  const LiveIntervals *LIS;
256 
257  /// We currently only allow pressure tracking within a block.
258  const MachineBasicBlock *MBB;
259 
260  /// Track the max pressure within the region traversed so far.
261  RegisterPressure &P;
262 
263  /// Run in two modes dependending on whether constructed with IntervalPressure
264  /// or RegisterPressure. If requireIntervals is false, LIS are ignored.
265  bool RequireIntervals;
266 
267  /// True if UntiedDefs will be populated.
268  bool TrackUntiedDefs;
269 
270  /// Register pressure corresponds to liveness before this instruction
271  /// iterator. It may point to the end of the block or a DebugValue rather than
272  /// an instruction.
274 
275  /// Pressure map indexed by pressure set ID, not class ID.
276  std::vector<unsigned> CurrSetPressure;
277 
278  /// Set of live registers.
279  LiveRegSet LiveRegs;
280 
281  /// Set of vreg defs that start a live range.
283  /// Live-through pressure.
284  std::vector<unsigned> LiveThruPressure;
285 
286 public:
288  MF(0), TRI(0), RCI(0), LIS(0), MBB(0), P(rp), RequireIntervals(true),
289  TrackUntiedDefs(false) {}
290 
292  MF(0), TRI(0), RCI(0), LIS(0), MBB(0), P(rp), RequireIntervals(false),
293  TrackUntiedDefs(false) {}
294 
295  void reset();
296 
297  void init(const MachineFunction *mf, const RegisterClassInfo *rci,
298  const LiveIntervals *lis, const MachineBasicBlock *mbb,
300  bool ShouldTrackUntiedDefs = false);
301 
302  /// Force liveness of virtual registers or physical register
303  /// units. Particularly useful to initialize the livein/out state of the
304  /// tracker before the first call to advance/recede.
305  void addLiveRegs(ArrayRef<unsigned> Regs);
306 
307  /// Get the MI position corresponding to this register pressure.
308  MachineBasicBlock::const_iterator getPos() const { return CurrPos; }
309 
310  // Reset the MI position corresponding to the register pressure. This allows
311  // schedulers to move instructions above the RegPressureTracker's
312  // CurrPos. Since the pressure is computed before CurrPos, the iterator
313  // position changes while pressure does not.
314  void setPos(MachineBasicBlock::const_iterator Pos) { CurrPos = Pos; }
315 
316  /// \brief Get the SlotIndex for the first nondebug instruction including or
317  /// after the current position.
318  SlotIndex getCurrSlot() const;
319 
320  /// Recede across the previous instruction.
321  bool recede(SmallVectorImpl<unsigned> *LiveUses = 0, PressureDiff *PDiff = 0);
322 
323  /// Advance across the current instruction.
324  bool advance();
325 
326  /// Finalize the region boundaries and recored live ins and live outs.
327  void closeRegion();
328 
329  /// Initialize the LiveThru pressure set based on the untied defs found in
330  /// RPTracker.
331  void initLiveThru(const RegPressureTracker &RPTracker);
332 
333  /// Copy an existing live thru pressure result.
334  void initLiveThru(ArrayRef<unsigned> PressureSet) {
335  LiveThruPressure.assign(PressureSet.begin(), PressureSet.end());
336  }
337 
338  ArrayRef<unsigned> getLiveThru() const { return LiveThruPressure; }
339 
340  /// Get the resulting register pressure over the traversed region.
341  /// This result is complete if either advance() or recede() has returned true,
342  /// or if closeRegion() was explicitly invoked.
343  RegisterPressure &getPressure() { return P; }
344  const RegisterPressure &getPressure() const { return P; }
345 
346  /// Get the register set pressure at the current position, which may be less
347  /// than the pressure across the traversed region.
348  std::vector<unsigned> &getRegSetPressureAtPos() { return CurrSetPressure; }
349 
350  void discoverLiveOut(unsigned Reg);
351  void discoverLiveIn(unsigned Reg);
352 
353  bool isTopClosed() const;
354  bool isBottomClosed() const;
355 
356  void closeTop();
357  void closeBottom();
358 
359  /// Consider the pressure increase caused by traversing this instruction
360  /// bottom-up. Find the pressure set with the most change beyond its pressure
361  /// limit based on the tracker's current pressure, and record the number of
362  /// excess register units of that pressure set introduced by this instruction.
364  PressureDiff *PDiff,
365  RegPressureDelta &Delta,
366  ArrayRef<PressureChange> CriticalPSets,
367  ArrayRef<unsigned> MaxPressureLimit);
368 
370  /*const*/ PressureDiff &PDiff,
371  RegPressureDelta &Delta,
372  ArrayRef<PressureChange> CriticalPSets,
373  ArrayRef<unsigned> MaxPressureLimit) const;
374 
375  /// Consider the pressure increase caused by traversing this instruction
376  /// top-down. Find the pressure set with the most change beyond its pressure
377  /// limit based on the tracker's current pressure, and record the number of
378  /// excess register units of that pressure set introduced by this instruction.
380  RegPressureDelta &Delta,
381  ArrayRef<PressureChange> CriticalPSets,
382  ArrayRef<unsigned> MaxPressureLimit);
383 
384  /// Find the pressure set with the most change beyond its pressure limit after
385  /// traversing this instruction either upward or downward depending on the
386  /// closed end of the current region.
388  RegPressureDelta &Delta,
389  ArrayRef<PressureChange> CriticalPSets,
390  ArrayRef<unsigned> MaxPressureLimit) {
391  if (isTopClosed())
392  return getMaxDownwardPressureDelta(MI, Delta, CriticalPSets,
393  MaxPressureLimit);
394 
395  assert(isBottomClosed() && "Uninitialized pressure tracker");
396  return getMaxUpwardPressureDelta(MI, 0, Delta, CriticalPSets,
397  MaxPressureLimit);
398  }
399 
400  /// Get the pressure of each PSet after traversing this instruction bottom-up.
401  void getUpwardPressure(const MachineInstr *MI,
402  std::vector<unsigned> &PressureResult,
403  std::vector<unsigned> &MaxPressureResult);
404 
405  /// Get the pressure of each PSet after traversing this instruction top-down.
406  void getDownwardPressure(const MachineInstr *MI,
407  std::vector<unsigned> &PressureResult,
408  std::vector<unsigned> &MaxPressureResult);
409 
411  std::vector<unsigned> &PressureResult,
412  std::vector<unsigned> &MaxPressureResult) {
413  if (isTopClosed())
414  return getUpwardPressure(MI, PressureResult, MaxPressureResult);
415 
416  assert(isBottomClosed() && "Uninitialized pressure tracker");
417  return getDownwardPressure(MI, PressureResult, MaxPressureResult);
418  }
419 
420  bool hasUntiedDef(unsigned VirtReg) const {
421  return UntiedDefs.count(VirtReg);
422  }
423 
424  void dump() const;
425 
426 protected:
427  const LiveRange *getLiveRange(unsigned Reg) const;
428 
431 
432  void bumpUpwardPressure(const MachineInstr *MI);
433  void bumpDownwardPressure(const MachineInstr *MI);
434 };
435 
436 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
437 void dumpRegSetPressure(ArrayRef<unsigned> SetPressure,
438  const TargetRegisterInfo *TRI);
439 #endif
440 } // end namespace llvm
441 
442 #endif
void decrease(unsigned Reg, const TargetRegisterInfo *TRI, const MachineRegisterInfo *MRI)
void dump(const TargetRegisterInfo *TRI) const
bool advance()
Advance across the current instruction.
void increaseRegPressure(ArrayRef< unsigned > Regs)
void getPressureAfterInst(const MachineInstr *MI, std::vector< unsigned > &PressureResult, std::vector< unsigned > &MaxPressureResult)
void addPressureChange(unsigned RegUnit, bool IsDec, const MachineRegisterInfo *MRI)
Add a change in pressure to the pressure diff of a given instruction.
void init(unsigned N)
Initialize an array of N PressureDiffs.
bool operator==(const PressureChange &RHS) const
std::pair< iterator, bool > insert(const ValueT &Val)
Definition: SparseSet.h:246
iterator end() const
Definition: ArrayRef.h:98
void setUnitInc(int Inc)
static bool isVirtualRegister(unsigned Reg)
const LiveRange * getLiveRange(unsigned Reg) const
static const bool value
Definition: type_traits.h:74
void closeRegion()
Finalize the region boundaries and recored live ins and live outs.
bool isTopClosed() const
Does this pressure result have a valid top position and live ins.
void openBottom(MachineBasicBlock::const_iterator PrevBottom)
If the current bottom is the previous instr (before advancing), open it.
MachineBasicBlock::const_iterator getPos() const
Get the MI position corresponding to this register pressure.
Base class for register pressure results.
SlotIndex TopIdx
Record the boundary of the region being tracked.
void closeBottom()
Set the boundary for the bottom of the region and summarize live outs.
unsigned getPSet() const
void openBottom(SlotIndex PrevBottom)
If the current bottom is not greater than the previous index, open it.
MachineBasicBlock::const_iterator TopPos
Record the boundary of the region being tracked.
void discoverLiveOut(unsigned Reg)
Add Reg to the live out set and increase max pressure.
#define false
Definition: ConvertUTF.c:64
bool recede(SmallVectorImpl< unsigned > *LiveUses=0, PressureDiff *PDiff=0)
Recede across the previous instruction.
SlotIndex getCurrSlot() const
Get the SlotIndex for the first nondebug instruction including or after the current position...
std::vector< unsigned > & getRegSetPressureAtPos()
const_iterator end() const
void openTop(SlotIndex NextTop)
SparseSet< unsigned, VirtReg2IndexFunctor > VirtRegs
bool hasUntiedDef(unsigned VirtReg) const
PressureDiff & operator[](unsigned Idx)
iterator erase(iterator I)
Definition: SparseSet.h:277
void decreaseRegPressure(ArrayRef< unsigned > Regs)
Simply decrease the current pressure as impacted by these registers.
void getMaxDownwardPressureDelta(const MachineInstr *MI, RegPressureDelta &Delta, ArrayRef< PressureChange > CriticalPSets, ArrayRef< unsigned > MaxPressureLimit)
#define true
Definition: ConvertUTF.c:65
ArrayRef< unsigned > getLiveThru() const
Array of PressureDiffs.
bool operator!=(const RegPressureDelta &RHS) const
bool operator==(const RegPressureDelta &RHS) const
void bumpDownwardPressure(const MachineInstr *MI)
SparseSet< unsigned > PhysRegs
void free(void *ptr);
A set of live virtual registers and physical register units.
void openTop(MachineBasicBlock::const_iterator PrevTop)
If the current top is the previous instruction (before receding), open it.
iterator begin() const
Definition: ArrayRef.h:97
SmallVector< unsigned, 8 > LiveOutRegs
void increase(unsigned Reg, const TargetRegisterInfo *TRI, const MachineRegisterInfo *MRI)
void dumpRegSetPressure(ArrayRef< unsigned > SetPressure, const TargetRegisterInfo *TRI)
void initLiveThru(const RegPressureTracker &RPTracker)
std::vector< unsigned > MaxSetPressure
Map of max reg pressure indexed by pressure set ID, not class ID.
const RegisterPressure & getPressure() const
void discoverLiveIn(unsigned Reg)
Add Reg to the live in set and increase max pressure.
bool insert(unsigned Reg)
void getMaxPressureDelta(const MachineInstr *MI, RegPressureDelta &Delta, ArrayRef< PressureChange > CriticalPSets, ArrayRef< unsigned > MaxPressureLimit)
void reset()
Clear the result so it can be used for another round of pressure tracking.
bool contains(unsigned Reg) const
PressureChange(unsigned id)
bool count(const KeyT &Key) const
Definition: SparseSet.h:232
RegPressureTracker(RegionPressure &rp)
PressureChange CriticalMax
bool erase(unsigned Reg)
void init(const MachineFunction *mf, const RegisterClassInfo *rci, const LiveIntervals *lis, const MachineBasicBlock *mbb, MachineBasicBlock::const_iterator pos, bool ShouldTrackUntiedDefs=false)
void closeTop()
Set the boundary for the top of the region and summarize live ins.
bundle_iterator< const MachineInstr, const_instr_iterator > const_iterator
RegPressureTracker(IntervalPressure &rp)
#define N
void getMaxUpwardPressureDelta(const MachineInstr *MI, PressureDiff *PDiff, RegPressureDelta &Delta, ArrayRef< PressureChange > CriticalPSets, ArrayRef< unsigned > MaxPressureLimit)
void getUpwardPressure(const MachineInstr *MI, std::vector< unsigned > &PressureResult, std::vector< unsigned > &MaxPressureResult)
Get the pressure of each PSet after traversing this instruction bottom-up.
const_iterator begin() const
bool isBottomClosed() const
Does this pressure result have a valid bottom position and live outs.
PressureChange * iterator
void bumpUpwardPressure(const MachineInstr *MI)
unsigned getPSetOrMax() const
void addLiveRegs(ArrayRef< unsigned > Regs)
Force liveness of registers.
const PressureChange * const_iterator
const PressureDiff & operator[](unsigned Idx) const
void initLiveThru(ArrayRef< unsigned > PressureSet)
Copy an existing live thru pressure result.
void reset()
Clear the result so it can be used for another round of pressure tracking.
SmallVector< unsigned, 8 > LiveInRegs
List of live in virtual registers or physical register units.
void getDownwardPressure(const MachineInstr *MI, std::vector< unsigned > &PressureResult, std::vector< unsigned > &MaxPressureResult)
Get the pressure of each PSet after traversing this instruction top-down.
const MCRegisterInfo & MRI
void setPos(MachineBasicBlock::const_iterator Pos)
RegisterPressure & getPressure()
MachineBasicBlock::const_iterator BottomPos
SlotIndex - An opaque wrapper around machine indexes.
Definition: SlotIndexes.h:92
void getUpwardPressureDelta(const MachineInstr *MI, PressureDiff &PDiff, RegPressureDelta &Delta, ArrayRef< PressureChange > CriticalPSets, ArrayRef< unsigned > MaxPressureLimit) const