Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
14 | pmbaty | 1 | //===- RegisterPressure.h - Dynamic Register Pressure -----------*- 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 | // This file defines the RegisterPressure class which can be used to track |
||
10 | // MachineInstr level register pressure. |
||
11 | // |
||
12 | //===----------------------------------------------------------------------===// |
||
13 | |||
14 | #ifndef LLVM_CODEGEN_REGISTERPRESSURE_H |
||
15 | #define LLVM_CODEGEN_REGISTERPRESSURE_H |
||
16 | |||
17 | #include "llvm/ADT/ArrayRef.h" |
||
18 | #include "llvm/ADT/SmallVector.h" |
||
19 | #include "llvm/ADT/SparseSet.h" |
||
20 | #include "llvm/CodeGen/MachineBasicBlock.h" |
||
21 | #include "llvm/CodeGen/SlotIndexes.h" |
||
22 | #include "llvm/CodeGen/TargetRegisterInfo.h" |
||
23 | #include "llvm/MC/LaneBitmask.h" |
||
24 | #include <cassert> |
||
25 | #include <cstdint> |
||
26 | #include <cstdlib> |
||
27 | #include <limits> |
||
28 | #include <vector> |
||
29 | |||
30 | namespace llvm { |
||
31 | |||
32 | class LiveIntervals; |
||
33 | class MachineFunction; |
||
34 | class MachineInstr; |
||
35 | class MachineRegisterInfo; |
||
36 | class RegisterClassInfo; |
||
37 | |||
38 | struct RegisterMaskPair { |
||
39 | Register RegUnit; ///< Virtual register or register unit. |
||
40 | LaneBitmask LaneMask; |
||
41 | |||
42 | RegisterMaskPair(Register RegUnit, LaneBitmask LaneMask) |
||
43 | : RegUnit(RegUnit), LaneMask(LaneMask) {} |
||
44 | }; |
||
45 | |||
46 | /// Base class for register pressure results. |
||
47 | struct RegisterPressure { |
||
48 | /// Map of max reg pressure indexed by pressure set ID, not class ID. |
||
49 | std::vector<unsigned> MaxSetPressure; |
||
50 | |||
51 | /// List of live in virtual registers or physical register units. |
||
52 | SmallVector<RegisterMaskPair,8> LiveInRegs; |
||
53 | SmallVector<RegisterMaskPair,8> LiveOutRegs; |
||
54 | |||
55 | void dump(const TargetRegisterInfo *TRI) const; |
||
56 | }; |
||
57 | |||
58 | /// RegisterPressure computed within a region of instructions delimited by |
||
59 | /// TopIdx and BottomIdx. During pressure computation, the maximum pressure per |
||
60 | /// register pressure set is increased. Once pressure within a region is fully |
||
61 | /// computed, the live-in and live-out sets are recorded. |
||
62 | /// |
||
63 | /// This is preferable to RegionPressure when LiveIntervals are available, |
||
64 | /// because delimiting regions by SlotIndex is more robust and convenient than |
||
65 | /// holding block iterators. The block contents can change without invalidating |
||
66 | /// the pressure result. |
||
67 | struct IntervalPressure : RegisterPressure { |
||
68 | /// Record the boundary of the region being tracked. |
||
69 | SlotIndex TopIdx; |
||
70 | SlotIndex BottomIdx; |
||
71 | |||
72 | void reset(); |
||
73 | |||
74 | void openTop(SlotIndex NextTop); |
||
75 | |||
76 | void openBottom(SlotIndex PrevBottom); |
||
77 | }; |
||
78 | |||
79 | /// RegisterPressure computed within a region of instructions delimited by |
||
80 | /// TopPos and BottomPos. This is a less precise version of IntervalPressure for |
||
81 | /// use when LiveIntervals are unavailable. |
||
82 | struct RegionPressure : RegisterPressure { |
||
83 | /// Record the boundary of the region being tracked. |
||
84 | MachineBasicBlock::const_iterator TopPos; |
||
85 | MachineBasicBlock::const_iterator BottomPos; |
||
86 | |||
87 | void reset(); |
||
88 | |||
89 | void openTop(MachineBasicBlock::const_iterator PrevTop); |
||
90 | |||
91 | void openBottom(MachineBasicBlock::const_iterator PrevBottom); |
||
92 | }; |
||
93 | |||
94 | /// Capture a change in pressure for a single pressure set. UnitInc may be |
||
95 | /// expressed in terms of upward or downward pressure depending on the client |
||
96 | /// and will be dynamically adjusted for current liveness. |
||
97 | /// |
||
98 | /// Pressure increments are tiny, typically 1-2 units, and this is only for |
||
99 | /// heuristics, so we don't check UnitInc overflow. Instead, we may have a |
||
100 | /// higher level assert that pressure is consistent within a region. We also |
||
101 | /// effectively ignore dead defs which don't affect heuristics much. |
||
102 | class PressureChange { |
||
103 | uint16_t PSetID = 0; // ID+1. 0=Invalid. |
||
104 | int16_t UnitInc = 0; |
||
105 | |||
106 | public: |
||
107 | PressureChange() = default; |
||
108 | PressureChange(unsigned id): PSetID(id + 1) { |
||
109 | assert(id < std::numeric_limits<uint16_t>::max() && "PSetID overflow."); |
||
110 | } |
||
111 | |||
112 | bool isValid() const { return PSetID > 0; } |
||
113 | |||
114 | unsigned getPSet() const { |
||
115 | assert(isValid() && "invalid PressureChange"); |
||
116 | return PSetID - 1; |
||
117 | } |
||
118 | |||
119 | // If PSetID is invalid, return UINT16_MAX to give it lowest priority. |
||
120 | unsigned getPSetOrMax() const { |
||
121 | return (PSetID - 1) & std::numeric_limits<uint16_t>::max(); |
||
122 | } |
||
123 | |||
124 | int getUnitInc() const { return UnitInc; } |
||
125 | |||
126 | void setUnitInc(int Inc) { UnitInc = Inc; } |
||
127 | |||
128 | bool operator==(const PressureChange &RHS) const { |
||
129 | return PSetID == RHS.PSetID && UnitInc == RHS.UnitInc; |
||
130 | } |
||
131 | |||
132 | void dump() const; |
||
133 | }; |
||
134 | |||
135 | /// List of PressureChanges in order of increasing, unique PSetID. |
||
136 | /// |
||
137 | /// Use a small fixed number, because we can fit more PressureChanges in an |
||
138 | /// empty SmallVector than ever need to be tracked per register class. If more |
||
139 | /// PSets are affected, then we only track the most constrained. |
||
140 | class PressureDiff { |
||
141 | // The initial design was for MaxPSets=4, but that requires PSet partitions, |
||
142 | // which are not yet implemented. (PSet partitions are equivalent PSets given |
||
143 | // the register classes actually in use within the scheduling region.) |
||
144 | enum { MaxPSets = 16 }; |
||
145 | |||
146 | PressureChange PressureChanges[MaxPSets]; |
||
147 | |||
148 | using iterator = PressureChange *; |
||
149 | |||
150 | iterator nonconst_begin() { return &PressureChanges[0]; } |
||
151 | iterator nonconst_end() { return &PressureChanges[MaxPSets]; } |
||
152 | |||
153 | public: |
||
154 | using const_iterator = const PressureChange *; |
||
155 | |||
156 | const_iterator begin() const { return &PressureChanges[0]; } |
||
157 | const_iterator end() const { return &PressureChanges[MaxPSets]; } |
||
158 | |||
159 | void addPressureChange(Register RegUnit, bool IsDec, |
||
160 | const MachineRegisterInfo *MRI); |
||
161 | |||
162 | void dump(const TargetRegisterInfo &TRI) const; |
||
163 | }; |
||
164 | |||
165 | /// List of registers defined and used by a machine instruction. |
||
166 | class RegisterOperands { |
||
167 | public: |
||
168 | /// List of virtual registers and register units read by the instruction. |
||
169 | SmallVector<RegisterMaskPair, 8> Uses; |
||
170 | /// List of virtual registers and register units defined by the |
||
171 | /// instruction which are not dead. |
||
172 | SmallVector<RegisterMaskPair, 8> Defs; |
||
173 | /// List of virtual registers and register units defined by the |
||
174 | /// instruction but dead. |
||
175 | SmallVector<RegisterMaskPair, 8> DeadDefs; |
||
176 | |||
177 | /// Analyze the given instruction \p MI and fill in the Uses, Defs and |
||
178 | /// DeadDefs list based on the MachineOperand flags. |
||
179 | void collect(const MachineInstr &MI, const TargetRegisterInfo &TRI, |
||
180 | const MachineRegisterInfo &MRI, bool TrackLaneMasks, |
||
181 | bool IgnoreDead); |
||
182 | |||
183 | /// Use liveness information to find dead defs not marked with a dead flag |
||
184 | /// and move them to the DeadDefs vector. |
||
185 | void detectDeadDefs(const MachineInstr &MI, const LiveIntervals &LIS); |
||
186 | |||
187 | /// Use liveness information to find out which uses/defs are partially |
||
188 | /// undefined/dead and adjust the RegisterMaskPairs accordingly. |
||
189 | /// If \p AddFlagsMI is given then missing read-undef and dead flags will be |
||
190 | /// added to the instruction. |
||
191 | void adjustLaneLiveness(const LiveIntervals &LIS, |
||
192 | const MachineRegisterInfo &MRI, SlotIndex Pos, |
||
193 | MachineInstr *AddFlagsMI = nullptr); |
||
194 | }; |
||
195 | |||
196 | /// Array of PressureDiffs. |
||
197 | class PressureDiffs { |
||
198 | PressureDiff *PDiffArray = nullptr; |
||
199 | unsigned Size = 0; |
||
200 | unsigned Max = 0; |
||
201 | |||
202 | public: |
||
203 | PressureDiffs() = default; |
||
204 | ~PressureDiffs() { free(PDiffArray); } |
||
205 | |||
206 | void clear() { Size = 0; } |
||
207 | |||
208 | void init(unsigned N); |
||
209 | |||
210 | PressureDiff &operator[](unsigned Idx) { |
||
211 | assert(Idx < Size && "PressureDiff index out of bounds"); |
||
212 | return PDiffArray[Idx]; |
||
213 | } |
||
214 | const PressureDiff &operator[](unsigned Idx) const { |
||
215 | return const_cast<PressureDiffs*>(this)->operator[](Idx); |
||
216 | } |
||
217 | |||
218 | /// Record pressure difference induced by the given operand list to |
||
219 | /// node with index \p Idx. |
||
220 | void addInstruction(unsigned Idx, const RegisterOperands &RegOpers, |
||
221 | const MachineRegisterInfo &MRI); |
||
222 | }; |
||
223 | |||
224 | /// Store the effects of a change in pressure on things that MI scheduler cares |
||
225 | /// about. |
||
226 | /// |
||
227 | /// Excess records the value of the largest difference in register units beyond |
||
228 | /// the target's pressure limits across the affected pressure sets, where |
||
229 | /// largest is defined as the absolute value of the difference. Negative |
||
230 | /// ExcessUnits indicates a reduction in pressure that had already exceeded the |
||
231 | /// target's limits. |
||
232 | /// |
||
233 | /// CriticalMax records the largest increase in the tracker's max pressure that |
||
234 | /// exceeds the critical limit for some pressure set determined by the client. |
||
235 | /// |
||
236 | /// CurrentMax records the largest increase in the tracker's max pressure that |
||
237 | /// exceeds the current limit for some pressure set determined by the client. |
||
238 | struct RegPressureDelta { |
||
239 | PressureChange Excess; |
||
240 | PressureChange CriticalMax; |
||
241 | PressureChange CurrentMax; |
||
242 | |||
243 | RegPressureDelta() = default; |
||
244 | |||
245 | bool operator==(const RegPressureDelta &RHS) const { |
||
246 | return Excess == RHS.Excess && CriticalMax == RHS.CriticalMax |
||
247 | && CurrentMax == RHS.CurrentMax; |
||
248 | } |
||
249 | bool operator!=(const RegPressureDelta &RHS) const { |
||
250 | return !operator==(RHS); |
||
251 | } |
||
252 | void dump() const; |
||
253 | }; |
||
254 | |||
255 | /// A set of live virtual registers and physical register units. |
||
256 | /// |
||
257 | /// This is a wrapper around a SparseSet which deals with mapping register unit |
||
258 | /// and virtual register indexes to an index usable by the sparse set. |
||
259 | class LiveRegSet { |
||
260 | private: |
||
261 | struct IndexMaskPair { |
||
262 | unsigned Index; |
||
263 | LaneBitmask LaneMask; |
||
264 | |||
265 | IndexMaskPair(unsigned Index, LaneBitmask LaneMask) |
||
266 | : Index(Index), LaneMask(LaneMask) {} |
||
267 | |||
268 | unsigned getSparseSetIndex() const { |
||
269 | return Index; |
||
270 | } |
||
271 | }; |
||
272 | |||
273 | using RegSet = SparseSet<IndexMaskPair>; |
||
274 | RegSet Regs; |
||
275 | unsigned NumRegUnits; |
||
276 | |||
277 | unsigned getSparseIndexFromReg(Register Reg) const { |
||
278 | if (Reg.isVirtual()) |
||
279 | return Register::virtReg2Index(Reg) + NumRegUnits; |
||
280 | assert(Reg < NumRegUnits); |
||
281 | return Reg; |
||
282 | } |
||
283 | |||
284 | Register getRegFromSparseIndex(unsigned SparseIndex) const { |
||
285 | if (SparseIndex >= NumRegUnits) |
||
286 | return Register::index2VirtReg(SparseIndex - NumRegUnits); |
||
287 | return Register(SparseIndex); |
||
288 | } |
||
289 | |||
290 | public: |
||
291 | void clear(); |
||
292 | void init(const MachineRegisterInfo &MRI); |
||
293 | |||
294 | LaneBitmask contains(Register Reg) const { |
||
295 | unsigned SparseIndex = getSparseIndexFromReg(Reg); |
||
296 | RegSet::const_iterator I = Regs.find(SparseIndex); |
||
297 | if (I == Regs.end()) |
||
298 | return LaneBitmask::getNone(); |
||
299 | return I->LaneMask; |
||
300 | } |
||
301 | |||
302 | /// Mark the \p Pair.LaneMask lanes of \p Pair.Reg as live. |
||
303 | /// Returns the previously live lanes of \p Pair.Reg. |
||
304 | LaneBitmask insert(RegisterMaskPair Pair) { |
||
305 | unsigned SparseIndex = getSparseIndexFromReg(Pair.RegUnit); |
||
306 | auto InsertRes = Regs.insert(IndexMaskPair(SparseIndex, Pair.LaneMask)); |
||
307 | if (!InsertRes.second) { |
||
308 | LaneBitmask PrevMask = InsertRes.first->LaneMask; |
||
309 | InsertRes.first->LaneMask |= Pair.LaneMask; |
||
310 | return PrevMask; |
||
311 | } |
||
312 | return LaneBitmask::getNone(); |
||
313 | } |
||
314 | |||
315 | /// Clears the \p Pair.LaneMask lanes of \p Pair.Reg (mark them as dead). |
||
316 | /// Returns the previously live lanes of \p Pair.Reg. |
||
317 | LaneBitmask erase(RegisterMaskPair Pair) { |
||
318 | unsigned SparseIndex = getSparseIndexFromReg(Pair.RegUnit); |
||
319 | RegSet::iterator I = Regs.find(SparseIndex); |
||
320 | if (I == Regs.end()) |
||
321 | return LaneBitmask::getNone(); |
||
322 | LaneBitmask PrevMask = I->LaneMask; |
||
323 | I->LaneMask &= ~Pair.LaneMask; |
||
324 | return PrevMask; |
||
325 | } |
||
326 | |||
327 | size_t size() const { |
||
328 | return Regs.size(); |
||
329 | } |
||
330 | |||
331 | template<typename ContainerT> |
||
332 | void appendTo(ContainerT &To) const { |
||
333 | for (const IndexMaskPair &P : Regs) { |
||
334 | Register Reg = getRegFromSparseIndex(P.Index); |
||
335 | if (P.LaneMask.any()) |
||
336 | To.push_back(RegisterMaskPair(Reg, P.LaneMask)); |
||
337 | } |
||
338 | } |
||
339 | }; |
||
340 | |||
341 | /// Track the current register pressure at some position in the instruction |
||
342 | /// stream, and remember the high water mark within the region traversed. This |
||
343 | /// does not automatically consider live-through ranges. The client may |
||
344 | /// independently adjust for global liveness. |
||
345 | /// |
||
346 | /// Each RegPressureTracker only works within a MachineBasicBlock. Pressure can |
||
347 | /// be tracked across a larger region by storing a RegisterPressure result at |
||
348 | /// each block boundary and explicitly adjusting pressure to account for block |
||
349 | /// live-in and live-out register sets. |
||
350 | /// |
||
351 | /// RegPressureTracker holds a reference to a RegisterPressure result that it |
||
352 | /// computes incrementally. During downward tracking, P.BottomIdx or P.BottomPos |
||
353 | /// is invalid until it reaches the end of the block or closeRegion() is |
||
354 | /// explicitly called. Similarly, P.TopIdx is invalid during upward |
||
355 | /// tracking. Changing direction has the side effect of closing region, and |
||
356 | /// traversing past TopIdx or BottomIdx reopens it. |
||
357 | class RegPressureTracker { |
||
358 | const MachineFunction *MF = nullptr; |
||
359 | const TargetRegisterInfo *TRI = nullptr; |
||
360 | const RegisterClassInfo *RCI = nullptr; |
||
361 | const MachineRegisterInfo *MRI; |
||
362 | const LiveIntervals *LIS = nullptr; |
||
363 | |||
364 | /// We currently only allow pressure tracking within a block. |
||
365 | const MachineBasicBlock *MBB = nullptr; |
||
366 | |||
367 | /// Track the max pressure within the region traversed so far. |
||
368 | RegisterPressure &P; |
||
369 | |||
370 | /// Run in two modes dependending on whether constructed with IntervalPressure |
||
371 | /// or RegisterPressure. If requireIntervals is false, LIS are ignored. |
||
372 | bool RequireIntervals; |
||
373 | |||
374 | /// True if UntiedDefs will be populated. |
||
375 | bool TrackUntiedDefs = false; |
||
376 | |||
377 | /// True if lanemasks should be tracked. |
||
378 | bool TrackLaneMasks = false; |
||
379 | |||
380 | /// Register pressure corresponds to liveness before this instruction |
||
381 | /// iterator. It may point to the end of the block or a DebugValue rather than |
||
382 | /// an instruction. |
||
383 | MachineBasicBlock::const_iterator CurrPos; |
||
384 | |||
385 | /// Pressure map indexed by pressure set ID, not class ID. |
||
386 | std::vector<unsigned> CurrSetPressure; |
||
387 | |||
388 | /// Set of live registers. |
||
389 | LiveRegSet LiveRegs; |
||
390 | |||
391 | /// Set of vreg defs that start a live range. |
||
392 | SparseSet<Register, VirtReg2IndexFunctor> UntiedDefs; |
||
393 | /// Live-through pressure. |
||
394 | std::vector<unsigned> LiveThruPressure; |
||
395 | |||
396 | public: |
||
397 | RegPressureTracker(IntervalPressure &rp) : P(rp), RequireIntervals(true) {} |
||
398 | RegPressureTracker(RegionPressure &rp) : P(rp), RequireIntervals(false) {} |
||
399 | |||
400 | void reset(); |
||
401 | |||
402 | void init(const MachineFunction *mf, const RegisterClassInfo *rci, |
||
403 | const LiveIntervals *lis, const MachineBasicBlock *mbb, |
||
404 | MachineBasicBlock::const_iterator pos, |
||
405 | bool TrackLaneMasks, bool TrackUntiedDefs); |
||
406 | |||
407 | /// Force liveness of virtual registers or physical register |
||
408 | /// units. Particularly useful to initialize the livein/out state of the |
||
409 | /// tracker before the first call to advance/recede. |
||
410 | void addLiveRegs(ArrayRef<RegisterMaskPair> Regs); |
||
411 | |||
412 | /// Get the MI position corresponding to this register pressure. |
||
413 | MachineBasicBlock::const_iterator getPos() const { return CurrPos; } |
||
414 | |||
415 | // Reset the MI position corresponding to the register pressure. This allows |
||
416 | // schedulers to move instructions above the RegPressureTracker's |
||
417 | // CurrPos. Since the pressure is computed before CurrPos, the iterator |
||
418 | // position changes while pressure does not. |
||
419 | void setPos(MachineBasicBlock::const_iterator Pos) { CurrPos = Pos; } |
||
420 | |||
421 | /// Recede across the previous instruction. |
||
422 | void recede(SmallVectorImpl<RegisterMaskPair> *LiveUses = nullptr); |
||
423 | |||
424 | /// Recede across the previous instruction. |
||
425 | /// This "low-level" variant assumes that recedeSkipDebugValues() was |
||
426 | /// called previously and takes precomputed RegisterOperands for the |
||
427 | /// instruction. |
||
428 | void recede(const RegisterOperands &RegOpers, |
||
429 | SmallVectorImpl<RegisterMaskPair> *LiveUses = nullptr); |
||
430 | |||
431 | /// Recede until we find an instruction which is not a DebugValue. |
||
432 | void recedeSkipDebugValues(); |
||
433 | |||
434 | /// Advance across the current instruction. |
||
435 | void advance(); |
||
436 | |||
437 | /// Advance across the current instruction. |
||
438 | /// This is a "low-level" variant of advance() which takes precomputed |
||
439 | /// RegisterOperands of the instruction. |
||
440 | void advance(const RegisterOperands &RegOpers); |
||
441 | |||
442 | /// Finalize the region boundaries and recored live ins and live outs. |
||
443 | void closeRegion(); |
||
444 | |||
445 | /// Initialize the LiveThru pressure set based on the untied defs found in |
||
446 | /// RPTracker. |
||
447 | void initLiveThru(const RegPressureTracker &RPTracker); |
||
448 | |||
449 | /// Copy an existing live thru pressure result. |
||
450 | void initLiveThru(ArrayRef<unsigned> PressureSet) { |
||
451 | LiveThruPressure.assign(PressureSet.begin(), PressureSet.end()); |
||
452 | } |
||
453 | |||
454 | ArrayRef<unsigned> getLiveThru() const { return LiveThruPressure; } |
||
455 | |||
456 | /// Get the resulting register pressure over the traversed region. |
||
457 | /// This result is complete if closeRegion() was explicitly invoked. |
||
458 | RegisterPressure &getPressure() { return P; } |
||
459 | const RegisterPressure &getPressure() const { return P; } |
||
460 | |||
461 | /// Get the register set pressure at the current position, which may be less |
||
462 | /// than the pressure across the traversed region. |
||
463 | const std::vector<unsigned> &getRegSetPressureAtPos() const { |
||
464 | return CurrSetPressure; |
||
465 | } |
||
466 | |||
467 | bool isTopClosed() const; |
||
468 | bool isBottomClosed() const; |
||
469 | |||
470 | void closeTop(); |
||
471 | void closeBottom(); |
||
472 | |||
473 | /// Consider the pressure increase caused by traversing this instruction |
||
474 | /// bottom-up. Find the pressure set with the most change beyond its pressure |
||
475 | /// limit based on the tracker's current pressure, and record the number of |
||
476 | /// excess register units of that pressure set introduced by this instruction. |
||
477 | void getMaxUpwardPressureDelta(const MachineInstr *MI, |
||
478 | PressureDiff *PDiff, |
||
479 | RegPressureDelta &Delta, |
||
480 | ArrayRef<PressureChange> CriticalPSets, |
||
481 | ArrayRef<unsigned> MaxPressureLimit); |
||
482 | |||
483 | void getUpwardPressureDelta(const MachineInstr *MI, |
||
484 | /*const*/ PressureDiff &PDiff, |
||
485 | RegPressureDelta &Delta, |
||
486 | ArrayRef<PressureChange> CriticalPSets, |
||
487 | ArrayRef<unsigned> MaxPressureLimit) const; |
||
488 | |||
489 | /// Consider the pressure increase caused by traversing this instruction |
||
490 | /// top-down. Find the pressure set with the most change beyond its pressure |
||
491 | /// limit based on the tracker's current pressure, and record the number of |
||
492 | /// excess register units of that pressure set introduced by this instruction. |
||
493 | void getMaxDownwardPressureDelta(const MachineInstr *MI, |
||
494 | RegPressureDelta &Delta, |
||
495 | ArrayRef<PressureChange> CriticalPSets, |
||
496 | ArrayRef<unsigned> MaxPressureLimit); |
||
497 | |||
498 | /// Find the pressure set with the most change beyond its pressure limit after |
||
499 | /// traversing this instruction either upward or downward depending on the |
||
500 | /// closed end of the current region. |
||
501 | void getMaxPressureDelta(const MachineInstr *MI, |
||
502 | RegPressureDelta &Delta, |
||
503 | ArrayRef<PressureChange> CriticalPSets, |
||
504 | ArrayRef<unsigned> MaxPressureLimit) { |
||
505 | if (isTopClosed()) |
||
506 | return getMaxDownwardPressureDelta(MI, Delta, CriticalPSets, |
||
507 | MaxPressureLimit); |
||
508 | |||
509 | assert(isBottomClosed() && "Uninitialized pressure tracker"); |
||
510 | return getMaxUpwardPressureDelta(MI, nullptr, Delta, CriticalPSets, |
||
511 | MaxPressureLimit); |
||
512 | } |
||
513 | |||
514 | /// Get the pressure of each PSet after traversing this instruction bottom-up. |
||
515 | void getUpwardPressure(const MachineInstr *MI, |
||
516 | std::vector<unsigned> &PressureResult, |
||
517 | std::vector<unsigned> &MaxPressureResult); |
||
518 | |||
519 | /// Get the pressure of each PSet after traversing this instruction top-down. |
||
520 | void getDownwardPressure(const MachineInstr *MI, |
||
521 | std::vector<unsigned> &PressureResult, |
||
522 | std::vector<unsigned> &MaxPressureResult); |
||
523 | |||
524 | void getPressureAfterInst(const MachineInstr *MI, |
||
525 | std::vector<unsigned> &PressureResult, |
||
526 | std::vector<unsigned> &MaxPressureResult) { |
||
527 | if (isTopClosed()) |
||
528 | return getUpwardPressure(MI, PressureResult, MaxPressureResult); |
||
529 | |||
530 | assert(isBottomClosed() && "Uninitialized pressure tracker"); |
||
531 | return getDownwardPressure(MI, PressureResult, MaxPressureResult); |
||
532 | } |
||
533 | |||
534 | bool hasUntiedDef(Register VirtReg) const { |
||
535 | return UntiedDefs.count(VirtReg); |
||
536 | } |
||
537 | |||
538 | void dump() const; |
||
539 | |||
540 | void increaseRegPressure(Register RegUnit, LaneBitmask PreviousMask, |
||
541 | LaneBitmask NewMask); |
||
542 | void decreaseRegPressure(Register RegUnit, LaneBitmask PreviousMask, |
||
543 | LaneBitmask NewMask); |
||
544 | |||
545 | protected: |
||
546 | /// Add Reg to the live out set and increase max pressure. |
||
547 | void discoverLiveOut(RegisterMaskPair Pair); |
||
548 | /// Add Reg to the live in set and increase max pressure. |
||
549 | void discoverLiveIn(RegisterMaskPair Pair); |
||
550 | |||
551 | /// Get the SlotIndex for the first nondebug instruction including or |
||
552 | /// after the current position. |
||
553 | SlotIndex getCurrSlot() const; |
||
554 | |||
555 | void bumpDeadDefs(ArrayRef<RegisterMaskPair> DeadDefs); |
||
556 | |||
557 | void bumpUpwardPressure(const MachineInstr *MI); |
||
558 | void bumpDownwardPressure(const MachineInstr *MI); |
||
559 | |||
560 | void discoverLiveInOrOut(RegisterMaskPair Pair, |
||
561 | SmallVectorImpl<RegisterMaskPair> &LiveInOrOut); |
||
562 | |||
563 | LaneBitmask getLastUsedLanes(Register RegUnit, SlotIndex Pos) const; |
||
564 | LaneBitmask getLiveLanesAt(Register RegUnit, SlotIndex Pos) const; |
||
565 | LaneBitmask getLiveThroughAt(Register RegUnit, SlotIndex Pos) const; |
||
566 | }; |
||
567 | |||
568 | void dumpRegSetPressure(ArrayRef<unsigned> SetPressure, |
||
569 | const TargetRegisterInfo *TRI); |
||
570 | |||
571 | } // end namespace llvm |
||
572 | |||
573 | #endif // LLVM_CODEGEN_REGISTERPRESSURE_H |