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
30namespace llvm {
31
32class LiveIntervals;
33class MachineFunction;
34class MachineInstr;
35class MachineRegisterInfo;
36class RegisterClassInfo;
37
38struct 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.
47struct 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.
67struct 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.
82struct 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.
102class PressureChange {
103 uint16_t PSetID = 0; // ID+1. 0=Invalid.
104 int16_t UnitInc = 0;
105
106public:
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.
140class 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
153public:
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.
166class RegisterOperands {
167public:
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.
197class PressureDiffs {
198 PressureDiff *PDiffArray = nullptr;
199 unsigned Size = 0;
200 unsigned Max = 0;
201
202public:
203 PressureDiffs() = default;
204 PressureDiffs &operator=(const PressureDiffs &other) = delete;
205 PressureDiffs(const PressureDiffs &other) = delete;
206 ~PressureDiffs() { free(ptr: PDiffArray); }
207
208 void clear() { Size = 0; }
209
210 void init(unsigned N);
211
212 PressureDiff &operator[](unsigned Idx) {
213 assert(Idx < Size && "PressureDiff index out of bounds");
214 return PDiffArray[Idx];
215 }
216 const PressureDiff &operator[](unsigned Idx) const {
217 return const_cast<PressureDiffs*>(this)->operator[](Idx);
218 }
219
220 /// Record pressure difference induced by the given operand list to
221 /// node with index \p Idx.
222 void addInstruction(unsigned Idx, const RegisterOperands &RegOpers,
223 const MachineRegisterInfo &MRI);
224};
225
226/// Store the effects of a change in pressure on things that MI scheduler cares
227/// about.
228///
229/// Excess records the value of the largest difference in register units beyond
230/// the target's pressure limits across the affected pressure sets, where
231/// largest is defined as the absolute value of the difference. Negative
232/// ExcessUnits indicates a reduction in pressure that had already exceeded the
233/// target's limits.
234///
235/// CriticalMax records the largest increase in the tracker's max pressure that
236/// exceeds the critical limit for some pressure set determined by the client.
237///
238/// CurrentMax records the largest increase in the tracker's max pressure that
239/// exceeds the current limit for some pressure set determined by the client.
240struct RegPressureDelta {
241 PressureChange Excess;
242 PressureChange CriticalMax;
243 PressureChange CurrentMax;
244
245 RegPressureDelta() = default;
246
247 bool operator==(const RegPressureDelta &RHS) const {
248 return Excess == RHS.Excess && CriticalMax == RHS.CriticalMax
249 && CurrentMax == RHS.CurrentMax;
250 }
251 bool operator!=(const RegPressureDelta &RHS) const {
252 return !operator==(RHS);
253 }
254 void dump() const;
255};
256
257/// A set of live virtual registers and physical register units.
258///
259/// This is a wrapper around a SparseSet which deals with mapping register unit
260/// and virtual register indexes to an index usable by the sparse set.
261class LiveRegSet {
262private:
263 struct IndexMaskPair {
264 unsigned Index;
265 LaneBitmask LaneMask;
266
267 IndexMaskPair(unsigned Index, LaneBitmask LaneMask)
268 : Index(Index), LaneMask(LaneMask) {}
269
270 unsigned getSparseSetIndex() const {
271 return Index;
272 }
273 };
274
275 using RegSet = SparseSet<IndexMaskPair>;
276 RegSet Regs;
277 unsigned NumRegUnits = 0u;
278
279 unsigned getSparseIndexFromReg(Register Reg) const {
280 if (Reg.isVirtual())
281 return Register::virtReg2Index(Reg) + NumRegUnits;
282 assert(Reg < NumRegUnits);
283 return Reg;
284 }
285
286 Register getRegFromSparseIndex(unsigned SparseIndex) const {
287 if (SparseIndex >= NumRegUnits)
288 return Register::index2VirtReg(Index: SparseIndex - NumRegUnits);
289 return Register(SparseIndex);
290 }
291
292public:
293 void clear();
294 void init(const MachineRegisterInfo &MRI);
295
296 LaneBitmask contains(Register Reg) const {
297 unsigned SparseIndex = getSparseIndexFromReg(Reg);
298 RegSet::const_iterator I = Regs.find(Key: SparseIndex);
299 if (I == Regs.end())
300 return LaneBitmask::getNone();
301 return I->LaneMask;
302 }
303
304 /// Mark the \p Pair.LaneMask lanes of \p Pair.Reg as live.
305 /// Returns the previously live lanes of \p Pair.Reg.
306 LaneBitmask insert(RegisterMaskPair Pair) {
307 unsigned SparseIndex = getSparseIndexFromReg(Reg: Pair.RegUnit);
308 auto InsertRes = Regs.insert(Val: IndexMaskPair(SparseIndex, Pair.LaneMask));
309 if (!InsertRes.second) {
310 LaneBitmask PrevMask = InsertRes.first->LaneMask;
311 InsertRes.first->LaneMask |= Pair.LaneMask;
312 return PrevMask;
313 }
314 return LaneBitmask::getNone();
315 }
316
317 /// Clears the \p Pair.LaneMask lanes of \p Pair.Reg (mark them as dead).
318 /// Returns the previously live lanes of \p Pair.Reg.
319 LaneBitmask erase(RegisterMaskPair Pair) {
320 unsigned SparseIndex = getSparseIndexFromReg(Reg: Pair.RegUnit);
321 RegSet::iterator I = Regs.find(Key: SparseIndex);
322 if (I == Regs.end())
323 return LaneBitmask::getNone();
324 LaneBitmask PrevMask = I->LaneMask;
325 I->LaneMask &= ~Pair.LaneMask;
326 return PrevMask;
327 }
328
329 size_t size() const {
330 return Regs.size();
331 }
332
333 template<typename ContainerT>
334 void appendTo(ContainerT &To) const {
335 for (const IndexMaskPair &P : Regs) {
336 Register Reg = getRegFromSparseIndex(SparseIndex: P.Index);
337 if (P.LaneMask.any())
338 To.push_back(RegisterMaskPair(Reg, P.LaneMask));
339 }
340 }
341};
342
343/// Track the current register pressure at some position in the instruction
344/// stream, and remember the high water mark within the region traversed. This
345/// does not automatically consider live-through ranges. The client may
346/// independently adjust for global liveness.
347///
348/// Each RegPressureTracker only works within a MachineBasicBlock. Pressure can
349/// be tracked across a larger region by storing a RegisterPressure result at
350/// each block boundary and explicitly adjusting pressure to account for block
351/// live-in and live-out register sets.
352///
353/// RegPressureTracker holds a reference to a RegisterPressure result that it
354/// computes incrementally. During downward tracking, P.BottomIdx or P.BottomPos
355/// is invalid until it reaches the end of the block or closeRegion() is
356/// explicitly called. Similarly, P.TopIdx is invalid during upward
357/// tracking. Changing direction has the side effect of closing region, and
358/// traversing past TopIdx or BottomIdx reopens it.
359class RegPressureTracker {
360 const MachineFunction *MF = nullptr;
361 const TargetRegisterInfo *TRI = nullptr;
362 const RegisterClassInfo *RCI = nullptr;
363 const MachineRegisterInfo *MRI = nullptr;
364 const LiveIntervals *LIS = nullptr;
365
366 /// We currently only allow pressure tracking within a block.
367 const MachineBasicBlock *MBB = nullptr;
368
369 /// Track the max pressure within the region traversed so far.
370 RegisterPressure &P;
371
372 /// Run in two modes dependending on whether constructed with IntervalPressure
373 /// or RegisterPressure. If requireIntervals is false, LIS are ignored.
374 bool RequireIntervals;
375
376 /// True if UntiedDefs will be populated.
377 bool TrackUntiedDefs = false;
378
379 /// True if lanemasks should be tracked.
380 bool TrackLaneMasks = false;
381
382 /// Register pressure corresponds to liveness before this instruction
383 /// iterator. It may point to the end of the block or a DebugValue rather than
384 /// an instruction.
385 MachineBasicBlock::const_iterator CurrPos;
386
387 /// Pressure map indexed by pressure set ID, not class ID.
388 std::vector<unsigned> CurrSetPressure;
389
390 /// Set of live registers.
391 LiveRegSet LiveRegs;
392
393 /// Set of vreg defs that start a live range.
394 SparseSet<Register, VirtReg2IndexFunctor> UntiedDefs;
395 /// Live-through pressure.
396 std::vector<unsigned> LiveThruPressure;
397
398public:
399 RegPressureTracker(IntervalPressure &rp) : P(rp), RequireIntervals(true) {}
400 RegPressureTracker(RegionPressure &rp) : P(rp), RequireIntervals(false) {}
401
402 void reset();
403
404 void init(const MachineFunction *mf, const RegisterClassInfo *rci,
405 const LiveIntervals *lis, const MachineBasicBlock *mbb,
406 MachineBasicBlock::const_iterator pos,
407 bool TrackLaneMasks, bool TrackUntiedDefs);
408
409 /// Force liveness of virtual registers or physical register
410 /// units. Particularly useful to initialize the livein/out state of the
411 /// tracker before the first call to advance/recede.
412 void addLiveRegs(ArrayRef<RegisterMaskPair> Regs);
413
414 /// Get the MI position corresponding to this register pressure.
415 MachineBasicBlock::const_iterator getPos() const { return CurrPos; }
416
417 // Reset the MI position corresponding to the register pressure. This allows
418 // schedulers to move instructions above the RegPressureTracker's
419 // CurrPos. Since the pressure is computed before CurrPos, the iterator
420 // position changes while pressure does not.
421 void setPos(MachineBasicBlock::const_iterator Pos) { CurrPos = Pos; }
422
423 /// Recede across the previous instruction.
424 void recede(SmallVectorImpl<RegisterMaskPair> *LiveUses = nullptr);
425
426 /// Recede across the previous instruction.
427 /// This "low-level" variant assumes that recedeSkipDebugValues() was
428 /// called previously and takes precomputed RegisterOperands for the
429 /// instruction.
430 void recede(const RegisterOperands &RegOpers,
431 SmallVectorImpl<RegisterMaskPair> *LiveUses = nullptr);
432
433 /// Recede until we find an instruction which is not a DebugValue.
434 void recedeSkipDebugValues();
435
436 /// Advance across the current instruction.
437 void advance();
438
439 /// Advance across the current instruction.
440 /// This is a "low-level" variant of advance() which takes precomputed
441 /// RegisterOperands of the instruction.
442 void advance(const RegisterOperands &RegOpers);
443
444 /// Finalize the region boundaries and recored live ins and live outs.
445 void closeRegion();
446
447 /// Initialize the LiveThru pressure set based on the untied defs found in
448 /// RPTracker.
449 void initLiveThru(const RegPressureTracker &RPTracker);
450
451 /// Copy an existing live thru pressure result.
452 void initLiveThru(ArrayRef<unsigned> PressureSet) {
453 LiveThruPressure.assign(first: PressureSet.begin(), last: PressureSet.end());
454 }
455
456 ArrayRef<unsigned> getLiveThru() const { return LiveThruPressure; }
457
458 /// Get the resulting register pressure over the traversed region.
459 /// This result is complete if closeRegion() was explicitly invoked.
460 RegisterPressure &getPressure() { return P; }
461 const RegisterPressure &getPressure() const { return P; }
462
463 /// Get the register set pressure at the current position, which may be less
464 /// than the pressure across the traversed region.
465 const std::vector<unsigned> &getRegSetPressureAtPos() const {
466 return CurrSetPressure;
467 }
468
469 bool isTopClosed() const;
470 bool isBottomClosed() const;
471
472 void closeTop();
473 void closeBottom();
474
475 /// Consider the pressure increase caused by traversing this instruction
476 /// bottom-up. Find the pressure set with the most change beyond its pressure
477 /// limit based on the tracker's current pressure, and record the number of
478 /// excess register units of that pressure set introduced by this instruction.
479 void getMaxUpwardPressureDelta(const MachineInstr *MI,
480 PressureDiff *PDiff,
481 RegPressureDelta &Delta,
482 ArrayRef<PressureChange> CriticalPSets,
483 ArrayRef<unsigned> MaxPressureLimit);
484
485 void getUpwardPressureDelta(const MachineInstr *MI,
486 /*const*/ PressureDiff &PDiff,
487 RegPressureDelta &Delta,
488 ArrayRef<PressureChange> CriticalPSets,
489 ArrayRef<unsigned> MaxPressureLimit) const;
490
491 /// Consider the pressure increase caused by traversing this instruction
492 /// top-down. Find the pressure set with the most change beyond its pressure
493 /// limit based on the tracker's current pressure, and record the number of
494 /// excess register units of that pressure set introduced by this instruction.
495 void getMaxDownwardPressureDelta(const MachineInstr *MI,
496 RegPressureDelta &Delta,
497 ArrayRef<PressureChange> CriticalPSets,
498 ArrayRef<unsigned> MaxPressureLimit);
499
500 /// Find the pressure set with the most change beyond its pressure limit after
501 /// traversing this instruction either upward or downward depending on the
502 /// closed end of the current region.
503 void getMaxPressureDelta(const MachineInstr *MI,
504 RegPressureDelta &Delta,
505 ArrayRef<PressureChange> CriticalPSets,
506 ArrayRef<unsigned> MaxPressureLimit) {
507 if (isTopClosed())
508 return getMaxDownwardPressureDelta(MI, Delta, CriticalPSets,
509 MaxPressureLimit);
510
511 assert(isBottomClosed() && "Uninitialized pressure tracker");
512 return getMaxUpwardPressureDelta(MI, PDiff: nullptr, Delta, CriticalPSets,
513 MaxPressureLimit);
514 }
515
516 /// Get the pressure of each PSet after traversing this instruction bottom-up.
517 void getUpwardPressure(const MachineInstr *MI,
518 std::vector<unsigned> &PressureResult,
519 std::vector<unsigned> &MaxPressureResult);
520
521 /// Get the pressure of each PSet after traversing this instruction top-down.
522 void getDownwardPressure(const MachineInstr *MI,
523 std::vector<unsigned> &PressureResult,
524 std::vector<unsigned> &MaxPressureResult);
525
526 void getPressureAfterInst(const MachineInstr *MI,
527 std::vector<unsigned> &PressureResult,
528 std::vector<unsigned> &MaxPressureResult) {
529 if (isTopClosed())
530 return getUpwardPressure(MI, PressureResult, MaxPressureResult);
531
532 assert(isBottomClosed() && "Uninitialized pressure tracker");
533 return getDownwardPressure(MI, PressureResult, MaxPressureResult);
534 }
535
536 bool hasUntiedDef(Register VirtReg) const {
537 return UntiedDefs.count(Key: VirtReg);
538 }
539
540 void dump() const;
541
542 void increaseRegPressure(Register RegUnit, LaneBitmask PreviousMask,
543 LaneBitmask NewMask);
544 void decreaseRegPressure(Register RegUnit, LaneBitmask PreviousMask,
545 LaneBitmask NewMask);
546
547protected:
548 /// Add Reg to the live out set and increase max pressure.
549 void discoverLiveOut(RegisterMaskPair Pair);
550 /// Add Reg to the live in set and increase max pressure.
551 void discoverLiveIn(RegisterMaskPair Pair);
552
553 /// Get the SlotIndex for the first nondebug instruction including or
554 /// after the current position.
555 SlotIndex getCurrSlot() const;
556
557 void bumpDeadDefs(ArrayRef<RegisterMaskPair> DeadDefs);
558
559 void bumpUpwardPressure(const MachineInstr *MI);
560 void bumpDownwardPressure(const MachineInstr *MI);
561
562 void discoverLiveInOrOut(RegisterMaskPair Pair,
563 SmallVectorImpl<RegisterMaskPair> &LiveInOrOut);
564
565 LaneBitmask getLastUsedLanes(Register RegUnit, SlotIndex Pos) const;
566 LaneBitmask getLiveLanesAt(Register RegUnit, SlotIndex Pos) const;
567 LaneBitmask getLiveThroughAt(Register RegUnit, SlotIndex Pos) const;
568};
569
570void dumpRegSetPressure(ArrayRef<unsigned> SetPressure,
571 const TargetRegisterInfo *TRI);
572
573} // end namespace llvm
574
575#endif // LLVM_CODEGEN_REGISTERPRESSURE_H
576

source code of llvm/include/llvm/CodeGen/RegisterPressure.h