LLVM 24.0.0git
GCNRegPressure.h
Go to the documentation of this file.
1//===- GCNRegPressure.h -----------------------------------------*- 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/// \file
10/// This file defines the GCNRegPressure class, which tracks registry pressure
11/// by bookkeeping number of SGPR/VGPRs used, weights for large SGPR/VGPRs. It
12/// also implements a compare function, which compares different register
13/// pressures, and declares one with max occupancy as winner.
14///
15//===----------------------------------------------------------------------===//
16
17#ifndef LLVM_LIB_TARGET_AMDGPU_GCNREGPRESSURE_H
18#define LLVM_LIB_TARGET_AMDGPU_GCNREGPRESSURE_H
19
20#include "GCNSubtarget.h"
23#include <algorithm>
24#include <array>
25#include <functional>
26
27namespace llvm {
28
30class raw_ostream;
31class SlotIndex;
32
35
36 static constexpr const char *getName(RegKind Kind) {
37 const char *Names[] = {"SGPR", "VGPR", "AGPR", "AVGPR"};
38 assert(Kind < TOTAL_KINDS);
39 return Names[Kind];
40 }
41
43 clear();
44 }
45
46 bool empty() const {
47 return !Value[SGPR] && !Value[VGPR] && !Value[AGPR] && !Value[AVGPR];
48 }
49
50 void clear() { Value.fill(0); }
51
52 unsigned getNumRegs(RegKind Kind) const {
53 assert(Kind < TOTAL_KINDS);
54 return Value[Kind];
55 }
56
57 /// \returns the SGPR32 pressure
58 unsigned getSGPRNum() const { return Value[SGPR]; }
59 /// \returns the aggregated ArchVGPR32, AccVGPR32, and Pseudo AVGPR pressure
60 /// dependent upon \p UnifiedVGPRFile
61 unsigned getVGPRNum(bool UnifiedVGPRFile) const {
62 if (UnifiedVGPRFile) {
63 return Value[AGPR]
64 ? getUnifiedVGPRNum(Value[VGPR], Value[AGPR], Value[AVGPR])
65 : Value[VGPR] + Value[AVGPR];
66 }
67 // AVGPR assignment priority is based on the width of the register. Account
68 // AVGPR pressure as VGPR.
69 return std::max(Value[VGPR] + Value[AVGPR], Value[AGPR]);
70 }
71
72 /// Returns the aggregated VGPR pressure, assuming \p NumArchVGPRs ArchVGPRs
73 /// \p NumAGPRs AGPRS, and \p NumAVGPRs AVGPRs for a target with a unified
74 /// VGPR file.
75 inline static unsigned getUnifiedVGPRNum(unsigned NumArchVGPRs,
76 unsigned NumAGPRs,
77 unsigned NumAVGPRs) {
78
79 // Assume AVGPRs will be assigned as VGPRs.
80 return alignTo(NumArchVGPRs + NumAVGPRs,
82 NumAGPRs;
83 }
84
85 /// \returns the ArchVGPR32 pressure, plus the AVGPRS which we assume will be
86 /// allocated as VGPR
87 unsigned getArchVGPRNum() const { return Value[VGPR] + Value[AVGPR]; }
88 /// \returns the AccVGPR32 pressure
89 unsigned getAGPRNum() const { return Value[AGPR]; }
90
91 unsigned getVGPRTuplesWeight() const {
92 return std::max(Value[TOTAL_KINDS + VGPR] + Value[TOTAL_KINDS + AVGPR],
93 Value[TOTAL_KINDS + AGPR]);
94 }
95 unsigned getSGPRTuplesWeight() const { return Value[TOTAL_KINDS + SGPR]; }
96
97 unsigned getOccupancy(const GCNSubtarget &ST,
98 unsigned DynamicVGPRBlockSize) const {
99 return std::min(ST.getOccupancyWithNumSGPRs(getSGPRNum()),
100 ST.getOccupancyWithNumVGPRs(getVGPRNum(ST.hasGFX90AInsts()),
101 DynamicVGPRBlockSize));
102 }
103
104 unsigned getVGPRSpills(MachineFunction &MF, unsigned ArchVGPRThreshold,
105 unsigned AGPRThreshold, unsigned CombinedThreshold) {
106 const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
107 if (!ST.hasGFX90AInsts())
108 return 0;
109
110 unsigned ArchPressure = getArchVGPRNum();
111 unsigned AGPRPressure = getAGPRNum();
112
113 unsigned ArchSpill = ArchPressure > ArchVGPRThreshold
114 ? (ArchPressure - ArchVGPRThreshold)
115 : 0;
116 unsigned AGPRSpill =
117 AGPRPressure > AGPRThreshold ? (AGPRPressure - AGPRThreshold) : 0;
118
119 unsigned UnifiedPressure = getVGPRNum(/*UnifiedVGPRFile=*/true);
120 unsigned UnifiedSpill = UnifiedPressure > CombinedThreshold
121 ? (UnifiedPressure - CombinedThreshold)
122 : 0;
123
124 return std::max(UnifiedSpill, ArchSpill + AGPRSpill);
125 }
126
127 void inc(unsigned Reg,
128 LaneBitmask PrevMask,
129 LaneBitmask NewMask,
130 const MachineRegisterInfo &MRI);
131
132 /// Compares \p this GCNRegpressure to \p O, returning true if \p this is
133 /// less. Since GCNRegpressure contains different types of pressures, and due
134 /// to target-specific pecularities (e.g. we care about occupancy rather than
135 /// raw register usage), we determine if \p this GCNRegPressure is less than
136 /// \p O based on the following tiered comparisons (in order order of
137 /// precedence):
138 /// 1. Better occupancy
139 /// 2. Less spilling (first preference to VGPR spills, then to SGPR spills)
140 /// 3. Less tuple register pressure (first preference to VGPR tuples if we
141 /// determine that SGPR pressure is not important)
142 /// 4. Less raw register pressure (first preference to VGPR tuples if we
143 /// determine that SGPR pressure is not important)
144 bool less(const MachineFunction &MF, const GCNRegPressure &O,
145 unsigned MaxOccupancy = std::numeric_limits<unsigned>::max()) const;
146
147 bool operator==(const GCNRegPressure &O) const { return Value == O.Value; }
148
149 bool operator!=(const GCNRegPressure &O) const {
150 return !(*this == O);
151 }
152
154 for (unsigned I = 0; I < ValueArraySize; ++I)
155 Value[I] += RHS.Value[I];
156 return *this;
157 }
158
160 for (unsigned I = 0; I < ValueArraySize; ++I)
161 Value[I] -= RHS.Value[I];
162 return *this;
163 }
164
165 void dump() const;
166
167 static RegKind getRegKind(unsigned Reg, const MachineRegisterInfo &MRI) {
168 const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo();
169 const SIRegisterInfo *STI = static_cast<const SIRegisterInfo *>(TRI);
170 return (RegKind)getRegKind(MRI.getRegClass(Reg), STI);
171 }
172
173private:
174 static constexpr unsigned ValueArraySize = TOTAL_KINDS * 2;
175
176 /// Pressure for all register kinds (first all regular registers kinds, then
177 /// all tuple register kinds).
178 std::array<unsigned, ValueArraySize> Value;
179
180 static unsigned getRegKind(const TargetRegisterClass *RC,
181 const SIRegisterInfo *STI);
182
184 const GCNRegPressure &P2);
185
186 friend Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST,
187 unsigned DynamicVGPRBlockSize);
188};
189
190/// \returns the maximum of \p P1 and \p P2 for each register file. The VGPR and
191/// AVGPR components are queried as one sum, so both come from the operand with
192/// the larger sum. The AGPR maximum stays separate also for a unified VGPR
193/// file: ArchVGPRs and AGPRs use separate ranges of it, so the unified pressure
194/// is the sum of both peaks even when they are at different points.
196 const GCNRegPressure &P2) {
197 GCNRegPressure Res;
198 // Value holds the register counts, then the tuple weights, in the same
199 // RegKind order.
200 for (unsigned I = 0; I < GCNRegPressure::ValueArraySize; ++I) {
201 switch (I % GCNRegPressure::TOTAL_KINDS) {
204 const GCNRegPressure &From =
205 P1.Value[I] + P1.Value[AV] >= P2.Value[I] + P2.Value[AV] ? P1 : P2;
206 Res.Value[I] = From.Value[I];
207 Res.Value[AV] = From.Value[AV];
208 break;
209 }
211 // Already set with VGPR, which comes first in RegKind.
212 break;
213 default:
214 Res.Value[I] = std::max(P1.Value[I], P2.Value[I]);
215 }
216 }
217 return Res;
218}
219
221 const GCNRegPressure &P2) {
222 GCNRegPressure Sum = P1;
223 Sum += P2;
224 return Sum;
225}
226
228 const GCNRegPressure &P2) {
229 GCNRegPressure Diff = P1;
230 Diff -= P2;
231 return Diff;
232}
233
234////////////////////////////////////////////////////////////////////////////////
235// GCNRPTarget
236
237/// Models a register pressure target, allowing to evaluate and track register
238/// savings against that target from a starting \ref GCNRegPressure.
240public:
241 /// Sets up the target such that the register pressure starting at \p RP does
242 /// not show register spilling on function \p MF (w.r.t. the function's
243 /// mininum target occupancy).
244 GCNRPTarget(const MachineFunction &MF, const GCNRegPressure &RP);
245
246 /// Sets up the target such that the register pressure starting at \p RP does
247 /// not use more than \p NumSGPRs SGPRs and \p NumVGPRs VGPRs on function \p
248 /// MF.
249 GCNRPTarget(unsigned NumSGPRs, unsigned NumVGPRs, const MachineFunction &MF,
250 const GCNRegPressure &RP);
251
252 /// Sets up the target such that the register pressure starting at \p RP does
253 /// not prevent achieving an occupancy of at least \p Occupancy on function
254 /// \p MF.
255 GCNRPTarget(unsigned Occupancy, const MachineFunction &MF,
256 const GCNRegPressure &RP);
257
258 /// Changes the target (same semantics as constructor).
259 void setTarget(unsigned NumSGPRs, unsigned NumVGPRs);
260
261 const GCNRegPressure &getCurrentRP() const { return RP; }
262
263 void setRP(const GCNRegPressure &NewRP) { RP = NewRP; }
264
265 /// Determines whether saving virtual register \p Reg will be beneficial
266 /// towards achieving the RP target.
267 bool isSaveBeneficial(Register Reg) const;
268
269 /// Returns whether the benefit that saving \p SaveRP represents will be
270 /// beneficial towards achieving the RP target.
271 bool isSaveBeneficial(const GCNRegPressure &SaveRP) const;
272
273 /// Returns the benefit towards achieving the RP target that saving \p SaveRP
274 /// represents, in total number of registers saved across all classes.
275 unsigned getNumRegsBenefit(const GCNRegPressure &SaveRP) const;
276
277 /// Saves a total pressure of \p SaveRP.
278 void saveRP(const GCNRegPressure &SaveRP) {
279 assert(!RP.less(MF, SaveRP) && "saving beyond current RP");
280 RP -= SaveRP;
281 }
282
283 /// Whether \p TestRP is at or below the defined pressure target.
284 bool satisfied(const GCNRegPressure &TestRP) const;
285 /// Whether the current RP is at or below the defined pressure target.
286 bool satisfied() const { return satisfied(RP); }
287 bool hasVectorRegisterExcess() const;
288
289 unsigned getMaxSGPRs() const { return MaxSGPRs; }
290 unsigned getMaxVGPRs() const {
291 return UnifiedRF ? MaxUnifiedVGPRs : MaxVGPRs;
292 }
293
294#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
296 OS << "Actual/Target: " << Target.RP.getSGPRNum() << '/' << Target.MaxSGPRs
297 << " SGPRs, " << Target.RP.getArchVGPRNum() << '/' << Target.MaxVGPRs
298 << " ArchVGPRs, " << Target.RP.getAGPRNum() << '/' << Target.MaxVGPRs
299 << " AGPRs";
300
301 if (Target.MaxUnifiedVGPRs) {
302 OS << ", " << Target.RP.getVGPRNum(true) << '/' << Target.MaxUnifiedVGPRs
303 << " VGPRs (unified)";
304 }
305 return OS;
306 }
307#endif
308
309private:
310 const MachineFunction &MF;
311 const bool UnifiedRF;
312
313 /// Current register pressure.
315
316 /// Target number of SGPRs.
317 unsigned MaxSGPRs = 0;
318 /// Target number of ArchVGPRs and AGPRs.
319 unsigned MaxVGPRs = 0;
320 /// Target number of overall VGPRs for subtargets with unified RFs. Always 0
321 /// for subtargets with non-unified RFs.
322 unsigned MaxUnifiedVGPRs = 0;
323
324 GCNRPTarget(const GCNRegPressure &RP, const MachineFunction &MF)
325 : MF(MF), UnifiedRF(MF.getSubtarget<GCNSubtarget>().hasGFX90AInsts()),
326 RP(RP) {}
327};
328
329///////////////////////////////////////////////////////////////////////////////
330// GCNRPTracker
331
333public:
335
336protected:
341 mutable const MachineRegisterInfo *MRI = nullptr;
342 std::function<void(const GCNRegPressure &)> PressureCallback;
343
345
346 /// Folds the pressure \p RP of one program point into MaxPressure and passes
347 /// it to the pressure callback.
353
354 /// Resets tracker before or \p After the provided \p MI, which can be a debug
355 /// instruction.
356 void reset(const MachineInstr &MI, bool After);
357
358 /// Resets tracker at the start or \p End of the \p MBB.
359 void reset(const MachineBasicBlock &MBB, bool End);
360
361 /// Resets tracker at the specified slot index \p SI.
363
365
366public:
367 /// Resets tracker with the provided \p LiveRegs.
368 void reset(const MachineRegisterInfo &MRI, const LiveRegSet &LiveRegs);
369
370 // live regs for the current state
371 const decltype(LiveRegs) &getLiveRegs() const { return LiveRegs; }
373 return LastTrackedMI.isValid() ? &*LastTrackedMI : nullptr;
374 }
375
376 void clearMaxPressure() { MaxPressure.clear(); }
377
378 const GCNRegPressure &getMaxPressure() const { return MaxPressure; }
379
381
382 /// Sets a function that the tracker calls with the pressure of every program
383 /// point that it folds into the maximum pressure. A user can compute there a
384 /// maximum that maxPerRegFile() does not keep, e.g. of one register kind.
385 void setPressureCallback(std::function<void(const GCNRegPressure &)> CB) {
386 PressureCallback = std::move(CB);
387 }
388
390
391 decltype(LiveRegs) moveLiveRegs() {
392 return std::move(LiveRegs);
393 }
394};
395
397getLiveRegs(SlotIndex SI, const LiveIntervals &LIS,
398 const MachineRegisterInfo &MRI,
400
401////////////////////////////////////////////////////////////////////////////////
402// GCNUpwardRPTracker
403
405public:
407
409
410 /// Resets tracker to the point just after \p MI (in program order), which can
411 /// be a debug instruction.
412 void reset(const MachineInstr &MI) { reset(MI, /*After=*/true); }
413
414 /// Move to the state of RP just before the \p MI.
415 void recede(const MachineInstr &MI);
416
417 /// \p returns whether the tracker's state after receding MI corresponds
418 /// to reported by LIS.
419 bool isValid() const;
420
426};
427
428////////////////////////////////////////////////////////////////////////////////
429// GCNDownwardRPTracker
430
431/// Common behavior for downward RP trackers. Unconstructible directly.
433public:
434 /// Mostly copy/paste from CodeGen/RegisterPressure.cpp
435 /// Calculate the impact \p MI will have on CurPressure and \return the
436 /// speculated pressure. In order to support RP Speculation, this does not
437 /// rely on the implicit program ordering in the LiveIntervals.
439 const SIRegisterInfo *TRI) const;
440
441protected:
443
444 /// Retires the lanes of \p MI's used registers that die at \p MI, mirroring
445 /// RegPressureTracker::advance(). Early-clobber defs of \p MI are accounted
446 /// in \ref MaxPressure as live together with all of its uses. The uses of a
447 /// PHI are not retired since they do not die there.
448 void retireDeadUses(const MachineInstr &MI);
449
450 /// Retires the lanes defined by \p MI that are dead at \p SI, according to
451 /// LIS.
453
454 /// Adds all lanes (dead or not) defined by \p MI's register operands to \ref
455 /// CurPressure.
456 void addDefs(const MachineInstr &MI);
457
458private:
459 /// Drop the lanes of \p Reg that are no longer live at \p SI, decreasing
460 /// CurPressure accordingly. \p Reg must be a virtual register that is
461 /// currently tracked as live.
462 void retireVirtReg(Register Reg, SlotIndex SI);
463};
464
465/// Downward RP tracker that relies on program order to advance down the
466/// instruction stream.
468private:
469 /// Next MI to advance over.
471 /// End iterator for basic block being advanced in.
473
474public:
476
479
480 /// Returns the next MI that will be advanced over.
482
483 /// \p return MaxPressure and clear it.
485 auto Res = MaxPressure;
486 MaxPressure.clear();
487 return Res;
488 }
489
490 /// Reset tracker to the point before the \p MI (filling \ref LiveRegs upon
491 /// this point using \p LiveRegsCopy if provided or LIS otherwise) point using
492 /// LIS. \p End must be between the MI and the end of its parent block
493 /// (inclusive). \p returns false if the range [MI, End) is empty except debug
494 /// values.
496 const LiveRegSet *LiveRegsCopy = nullptr);
497
498 /// Move to the state right before \ref NextMI or the end of the MBB. This
499 /// retires defs of \ref LastTrackedMI that are dead after the instruction.
500 /// Its dead uses were already retired by \ref advanceToNext. \p returns
501 /// false if it reached the end of the block.
502 bool advanceBeforeNext();
503
504 /// Move to the state at \ref NextMI. This retires the uses that die at \p
505 /// NextMI, then adds the register lanes it defines to \ref CurPressure. Has
506 /// to be called after \ref advanceBeforeNext.
507 void advanceToNext();
508
509 /// Advance to the state at the next MI in program order. \p returns false if
510 /// it reached end of block.
511 bool advance();
512
513 /// Advance in program order until before \p End. Returns whether it actually
514 /// had to advance to reach \p End.
516
517 /// Reset tracker to \p Begin (filling \ref LiveRegs upon this point using \p
518 /// LiveRegsCopy if provided or LIS otherwise) and advance to \p End, which
519 /// must be between \p Begin and the end of its parent block (inclusive). \p
520 /// returns false if the range [Begin, End) is empty except debug values.
523 const LiveRegSet *LiveRegsCopy = nullptr);
524};
525
526/// Downward RP tracker that relies on the user to provide the next instruction
527/// down the instruction stream. It still uses LIS for liveness queries.
529public:
532
534
535 /// Advances to the state after \p MI.
536 void advance(const MachineInstr &MI);
537};
538
539/// \returns the LaneMask of live lanes of \p Reg at position \p SI. Only the
540/// active lanes of \p LaneMaskFilter will be set in the return value. This is
541/// used, for example, to limit the live lanes to a specific subreg when
542/// calculating use masks.
543LaneBitmask getLiveLaneMask(unsigned Reg, SlotIndex SI,
544 const LiveIntervals &LIS,
545 const MachineRegisterInfo &MRI,
546 LaneBitmask LaneMaskFilter = LaneBitmask::getAll());
547
548LaneBitmask getLiveLaneMask(const LiveInterval &LI, SlotIndex SI,
549 const MachineRegisterInfo &MRI,
550 LaneBitmask LaneMaskFilter = LaneBitmask::getAll());
551
552/// creates a map MachineInstr -> LiveRegSet
553/// R - range of iterators on instructions
554/// After - upon entry or exit of every instruction
555/// Note: there is no entry in the map for instructions with empty live reg set
556/// Complexity = O(NumVirtRegs * averageLiveRangeSegmentsPerReg * lg(R))
557template <typename Range>
558DenseMap<MachineInstr*, GCNRPTracker::LiveRegSet>
559getLiveRegMap(Range &&R, bool After, LiveIntervals &LIS) {
560 std::vector<SlotIndex> Indexes;
561 Indexes.reserve(llvm::size(R));
562 auto &SII = *LIS.getSlotIndexes();
563 for (MachineInstr *I : R) {
564 auto SI = SII.getInstructionIndex(*I);
565 Indexes.push_back(After ? SI.getDeadSlot() : SI.getBaseIndex());
566 }
567 llvm::sort(Indexes);
568
569 auto &MRI = (*R.begin())->getMF()->getRegInfo();
571 SmallVector<SlotIndex, 32> LiveIdxs, SRLiveIdxs;
572 for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
574 if (!LIS.hasInterval(Reg))
575 continue;
576 auto &LI = LIS.getInterval(Reg);
577 LiveIdxs.clear();
578 if (!LI.findIndexesLiveAt(Indexes, std::back_inserter(LiveIdxs)))
579 continue;
580 if (!LI.hasSubRanges()) {
581 for (auto SI : LiveIdxs)
582 LiveRegMap[SII.getInstructionFromIndex(SI)][Reg] =
583 MRI.getMaxLaneMaskForVReg(Reg);
584 } else
585 for (const auto &S : LI.subranges()) {
586 // constrain search for subranges by indexes live at main range
587 SRLiveIdxs.clear();
588 S.findIndexesLiveAt(LiveIdxs, std::back_inserter(SRLiveIdxs));
589 for (auto SI : SRLiveIdxs)
590 LiveRegMap[SII.getInstructionFromIndex(SI)][Reg] |= S.LaneMask;
591 }
592 }
593 return LiveRegMap;
594}
595
597 const LiveIntervals &LIS) {
599 MI.getMF()->getRegInfo());
600}
601
603 const LiveIntervals &LIS) {
605 MI.getMF()->getRegInfo());
606}
607
608template <typename Range>
610 Range &&LiveRegs) {
611 GCNRegPressure Res;
612 for (const auto &RM : LiveRegs)
613 Res.inc(RM.first, LaneBitmask::getNone(), RM.second, MRI);
614 return Res;
615}
616
618 const GCNRPTracker::LiveRegSet &S2);
619
620Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST = nullptr,
621 unsigned DynamicVGPRBlockSize = 0);
622
624 const MachineRegisterInfo &MRI);
625
626Printable reportMismatch(const GCNRPTracker::LiveRegSet &LISLR,
627 const GCNRPTracker::LiveRegSet &TrackedL,
628 const TargetRegisterInfo *TRI, StringRef Pfx = " ");
629
631 static char ID;
632
633public:
635
636 bool runOnMachineFunction(MachineFunction &MF) override;
637
643};
644
647 LiveIntervals &LIS,
648 const MachineLoopInfo *MLI);
649
650/// Estimate VGPR pressure using greedy, non-splitting register allocation
651/// simulation, accounting for live interval interference.
652/// \param RegionBegin Start iterator of the region
653/// \param RegionEnd End iterator of the region
654/// \param LiveIns Live-in registers for the region
655/// \returns estimated VGPR pressure
659 const GCNRPTracker::LiveRegSet &LiveIns, const LiveIntervals &LIS,
660 const MachineRegisterInfo &MRI, const SIRegisterInfo &TRI);
661
662} // end namespace llvm
663
664#endif // LLVM_LIB_TARGET_AMDGPU_GCNREGPRESSURE_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
constexpr LLT S1
MachineBasicBlock & MBB
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_ABI
Definition Compiler.h:211
AMD GCN specific subclass of TargetSubtarget.
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition MD5.cpp:57
Register Reg
Register const TargetRegisterInfo * TRI
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
StandardInstrumentations SI(Mod->getContext(), Debug, VerifyEach)
MachineRegisterInfo & MRI
Value * RHS
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
void setPreservesAll()
Set by analyses that do not transform their input at all.
void retireDeadDefs(const MachineInstr &MI, SlotIndex SI)
Retires the lanes defined by MI that are dead at SI, according to LIS.
GCNDownwardRPTrackerBase(LiveIntervals &LIS)
GCNRegPressure bumpDownwardPressure(const MachineInstr *MI, const SIRegisterInfo *TRI) const
Mostly copy/paste from CodeGen/RegisterPressure.cpp Calculate the impact MI will have on CurPressure ...
void retireDeadUses(const MachineInstr &MI)
Retires the lanes of MI's used registers that die at MI, mirroring RegPressureTracker::advance().
void addDefs(const MachineInstr &MI)
Adds all lanes (dead or not) defined by MI's register operands to CurPressure.
bool advance()
Advance to the state at the next MI in program order.
GCNRegPressure moveMaxPressure()
return MaxPressure and clear it.
GCNDownwardRPTracker(LiveIntervals &LIS)
MachineBasicBlock::const_iterator getNext() const
Returns the next MI that will be advanced over.
void advanceToNext()
Move to the state at NextMI.
bool advanceBeforeNext()
Move to the state right before NextMI or the end of the MBB.
bool reset(const MachineInstr &MI, MachineBasicBlock::const_iterator End, const LiveRegSet *LiveRegsCopy=nullptr)
Reset tracker to the point before the MI (filling LiveRegs upon this point using LiveRegsCopy if prov...
GCNManualDownwardRPTracker(LiveIntervals &LIS)
void advance(const MachineInstr &MI)
Advances to the state after MI.
GCNRPTarget(const MachineFunction &MF, const GCNRegPressure &RP)
Sets up the target such that the register pressure starting at RP does not show register spilling on ...
unsigned getMaxVGPRs() const
bool isSaveBeneficial(Register Reg) const
Determines whether saving virtual register Reg will be beneficial towards achieving the RP target.
bool hasVectorRegisterExcess() const
void setRP(const GCNRegPressure &NewRP)
bool satisfied() const
Whether the current RP is at or below the defined pressure target.
unsigned getMaxSGPRs() const
const GCNRegPressure & getCurrentRP() const
void setTarget(unsigned NumSGPRs, unsigned NumVGPRs)
Changes the target (same semantics as constructor).
friend raw_ostream & operator<<(raw_ostream &OS, const GCNRPTarget &Target)
void saveRP(const GCNRegPressure &SaveRP)
Saves a total pressure of SaveRP.
unsigned getNumRegsBenefit(const GCNRegPressure &SaveRP) const
Returns the benefit towards achieving the RP target that saving SaveRP represents,...
const GCNRegPressure & getMaxPressure() const
GCNRegPressure getPressure() const
const decltype(LiveRegs) & getLiveRegs() const
decltype(LiveRegs) moveLiveRegs()
GCNRegPressure CurPressure
GCNRPTracker(LiveIntervals &LIS_)
DenseMap< unsigned, LaneBitmask > LiveRegSet
std::function< void(const GCNRegPressure &)> PressureCallback
LiveIntervals & LIS
MachineBasicBlock::const_iterator LastTrackedMI
LaneBitmask getLastUsedLanes(Register Reg, SlotIndex Pos) const
Mostly copy/paste from CodeGen/RegisterPressure.cpp.
void updateMaxPressure(const GCNRegPressure &RP)
Folds the pressure RP of one program point into MaxPressure and passes it to the pressure callback.
GCNRegPressure MaxPressure
const MachineInstr * getLastTrackedMI() const
const MachineRegisterInfo * MRI
void setPressureCallback(std::function< void(const GCNRegPressure &)> CB)
Sets a function that the tracker calls with the pressure of every program point that it folds into th...
void reset(const MachineInstr &MI, bool After)
Resets tracker before or After the provided MI, which can be a debug instruction.
GCNRegPressure getMaxPressureAndReset()
GCNUpwardRPTracker(LiveIntervals &LIS_)
void recede(const MachineInstr &MI)
Move to the state of RP just before the MI.
bool isValid() const
returns whether the tracker's state after receding MI corresponds to reported by LIS.
void reset(const MachineInstr &MI)
Resets tracker to the point just after MI (in program order), which can be a debug instruction.
bool hasInterval(Register Reg) const
SlotIndexes * getSlotIndexes() const
SlotIndex getInstructionIndex(const MachineInstr &Instr) const
Returns the base index of the given instruction.
LiveInterval & getInterval(Register Reg)
A set of live virtual registers and physical register units.
MachineInstrBundleIterator< const MachineInstr > const_iterator
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Representation of each machine instruction.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Simple wrapper around std::function<void(raw_ostream&)>.
Definition Printable.h:38
Wrapper class representing virtual and physical registers.
Definition Register.h:20
static Register index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
Definition Register.h:72
SlotIndex - An opaque wrapper around machine indexes.
Definition SlotIndexes.h:70
SlotIndex getDeadSlot() const
Returns the dead def kill slot for the current instruction.
SlotIndex getBaseIndex() const
Returns the base index for associated with this index.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Target - Wrapper for Target specific information.
LLVM Value Representation.
Definition Value.h:75
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
unsigned getArchVGPRAllocGranule()
For subtargets with a unified VGPR file and mixed ArchVGPR/AGPR usage, returns the allocation granule...
This is an optimization pass for GlobalISel generic memory operations.
LaneBitmask getLiveLaneMask(unsigned Reg, SlotIndex SI, const LiveIntervals &LIS, const MachineRegisterInfo &MRI, LaneBitmask LaneMaskFilter=LaneBitmask::getAll())
bool isEqual(const GCNRPTracker::LiveRegSet &S1, const GCNRPTracker::LiveRegSet &S2)
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition STLExtras.h:1685
GCNRPTracker::LiveRegSet getLiveRegs(SlotIndex SI, const LiveIntervals &LIS, const MachineRegisterInfo &MRI, GCNRegPressure::RegKind RegKind=GCNRegPressure::TOTAL_KINDS)
GCNRegPressure getRegPressure(const MachineRegisterInfo &MRI, Range &&LiveRegs)
GCNRPTracker::LiveRegSet getLiveRegsAfter(const MachineInstr &MI, const LiveIntervals &LIS)
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1652
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:149
GCNRegPressure maxPerRegFile(const GCNRegPressure &P1, const GCNRegPressure &P2)
APInt operator-(APInt)
Definition APInt.h:2214
DenseMap< MachineInstr *, GCNRPTracker::LiveRegSet > getLiveRegMap(Range &&R, bool After, LiveIntervals &LIS)
creates a map MachineInstr -> LiveRegSet R - range of iterators on instructions After - upon entry or...
APInt operator+(APInt a, const APInt &b)
Definition APInt.h:2219
GCNRPTracker::LiveRegSet getLiveRegsBefore(const MachineInstr &MI, const LiveIntervals &LIS)
LLVM_ABI void dumpMaxRegPressure(MachineFunction &MF, GCNRegPressure::RegKind Kind, LiveIntervals &LIS, const MachineLoopInfo *MLI)
@ End
Run the machine verifier once, at the end of the pipeline.
Definition CodeGen.h:320
unsigned estimateGreedyVGPRPressure(MachineBasicBlock::const_iterator RegionBegin, MachineBasicBlock::const_iterator RegionEnd, const GCNRPTracker::LiveRegSet &LiveIns, const LiveIntervals &LIS, const MachineRegisterInfo &MRI, const SIRegisterInfo &TRI)
Estimate VGPR pressure using greedy, non-splitting register allocation simulation,...
Printable reportMismatch(const GCNRPTracker::LiveRegSet &LISLR, const GCNRPTracker::LiveRegSet &TrackedL, const TargetRegisterInfo *TRI, StringRef Pfx=" ")
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
static RegKind getRegKind(unsigned Reg, const MachineRegisterInfo &MRI)
static constexpr const char * getName(RegKind Kind)
bool operator!=(const GCNRegPressure &O) const
GCNRegPressure & operator+=(const GCNRegPressure &RHS)
friend GCNRegPressure maxPerRegFile(const GCNRegPressure &P1, const GCNRegPressure &P2)
unsigned getNumRegs(RegKind Kind) const
unsigned getVGPRTuplesWeight() const
GCNRegPressure & operator-=(const GCNRegPressure &RHS)
unsigned getVGPRSpills(MachineFunction &MF, unsigned ArchVGPRThreshold, unsigned AGPRThreshold, unsigned CombinedThreshold)
unsigned getVGPRNum(bool UnifiedVGPRFile) const
friend Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST, unsigned DynamicVGPRBlockSize)
unsigned getOccupancy(const GCNSubtarget &ST, unsigned DynamicVGPRBlockSize) const
void inc(unsigned Reg, LaneBitmask PrevMask, LaneBitmask NewMask, const MachineRegisterInfo &MRI)
unsigned getArchVGPRNum() const
unsigned getAGPRNum() const
unsigned getSGPRNum() const
unsigned getSGPRTuplesWeight() const
bool operator==(const GCNRegPressure &O) const
static unsigned getUnifiedVGPRNum(unsigned NumArchVGPRs, unsigned NumAGPRs, unsigned NumAVGPRs)
Returns the aggregated VGPR pressure, assuming NumArchVGPRs ArchVGPRs NumAGPRs AGPRS,...
bool less(const MachineFunction &MF, const GCNRegPressure &O, unsigned MaxOccupancy=std::numeric_limits< unsigned >::max()) const
Compares this GCNRegpressure to O, returning true if this is less.
static constexpr LaneBitmask getAll()
Definition LaneBitmask.h:82
static constexpr LaneBitmask getNone()
Definition LaneBitmask.h:81