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