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
26namespace llvm {
27
29class raw_ostream;
30class SlotIndex;
31
34
35 static constexpr const char *getName(RegKind Kind) {
36 const char *Names[] = {"SGPR", "VGPR", "AGPR", "AVGPR"};
37 assert(Kind < TOTAL_KINDS);
38 return Names[Kind];
39 }
40
42 clear();
43 }
44
45 bool empty() const {
46 return !Value[SGPR] && !Value[VGPR] && !Value[AGPR] && !Value[AVGPR];
47 }
48
49 void clear() { Value.fill(0); }
50
51 unsigned getNumRegs(RegKind Kind) const {
52 assert(Kind < TOTAL_KINDS);
53 return Value[Kind];
54 }
55
56 /// \returns the SGPR32 pressure
57 unsigned getSGPRNum() const { return Value[SGPR]; }
58 /// \returns the aggregated ArchVGPR32, AccVGPR32, and Pseudo AVGPR pressure
59 /// dependent upon \p UnifiedVGPRFile
60 unsigned getVGPRNum(bool UnifiedVGPRFile) const {
61 if (UnifiedVGPRFile) {
62 return Value[AGPR]
63 ? getUnifiedVGPRNum(Value[VGPR], Value[AGPR], Value[AVGPR])
64 : Value[VGPR] + Value[AVGPR];
65 }
66 // AVGPR assignment priority is based on the width of the register. Account
67 // AVGPR pressure as VGPR.
68 return std::max(Value[VGPR] + Value[AVGPR], Value[AGPR]);
69 }
70
71 /// Returns the aggregated VGPR pressure, assuming \p NumArchVGPRs ArchVGPRs
72 /// \p NumAGPRs AGPRS, and \p NumAVGPRs AVGPRs for a target with a unified
73 /// VGPR file.
74 inline static unsigned getUnifiedVGPRNum(unsigned NumArchVGPRs,
75 unsigned NumAGPRs,
76 unsigned NumAVGPRs) {
77
78 // Assume AVGPRs will be assigned as VGPRs.
79 return alignTo(NumArchVGPRs + NumAVGPRs,
81 NumAGPRs;
82 }
83
84 /// \returns the ArchVGPR32 pressure, plus the AVGPRS which we assume will be
85 /// allocated as VGPR
86 unsigned getArchVGPRNum() const { return Value[VGPR] + Value[AVGPR]; }
87 /// \returns the AccVGPR32 pressure
88 unsigned getAGPRNum() const { return Value[AGPR]; }
89 /// \returns the AVGPR32 pressure
90 unsigned getAVGPRNum() const { return Value[AVGPR]; }
91
92 unsigned getVGPRTuplesWeight() const {
93 return std::max(Value[TOTAL_KINDS + VGPR] + Value[TOTAL_KINDS + AVGPR],
94 Value[TOTAL_KINDS + AGPR]);
95 }
96 unsigned getSGPRTuplesWeight() const { return Value[TOTAL_KINDS + SGPR]; }
97
98 unsigned getOccupancy(const GCNSubtarget &ST,
99 unsigned DynamicVGPRBlockSize) const {
100 return std::min(ST.getOccupancyWithNumSGPRs(getSGPRNum()),
101 ST.getOccupancyWithNumVGPRs(getVGPRNum(ST.hasGFX90AInsts()),
102 DynamicVGPRBlockSize));
103 }
104
105 unsigned getVGPRSpills(MachineFunction &MF, unsigned ArchVGPRThreshold,
106 unsigned AGPRThreshold, unsigned CombinedThreshold) {
107 const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
108 if (!ST.hasGFX90AInsts())
109 return 0;
110
111 unsigned ArchPressure = getArchVGPRNum();
112 unsigned AGPRPressure = getAGPRNum();
113
114 unsigned ArchSpill = ArchPressure > ArchVGPRThreshold
115 ? (ArchPressure - ArchVGPRThreshold)
116 : 0;
117 unsigned AGPRSpill =
118 AGPRPressure > AGPRThreshold ? (AGPRPressure - AGPRThreshold) : 0;
119
120 unsigned UnifiedPressure = getVGPRNum(/*UnifiedVGPRFile=*/true);
121 unsigned UnifiedSpill = UnifiedPressure > CombinedThreshold
122 ? (UnifiedPressure - CombinedThreshold)
123 : 0;
124
125 return std::max(UnifiedSpill, ArchSpill + AGPRSpill);
126 }
127
128 void inc(unsigned Reg,
129 LaneBitmask PrevMask,
130 LaneBitmask NewMask,
131 const MachineRegisterInfo &MRI);
132
134 unsigned DynamicVGPRBlockSize) const {
135 return getOccupancy(ST, DynamicVGPRBlockSize) >
136 O.getOccupancy(ST, DynamicVGPRBlockSize);
137 }
138
139 /// Compares \p this GCNRegpressure to \p O, returning true if \p this is
140 /// less. Since GCNRegpressure contains different types of pressures, and due
141 /// to target-specific pecularities (e.g. we care about occupancy rather than
142 /// raw register usage), we determine if \p this GCNRegPressure is less than
143 /// \p O based on the following tiered comparisons (in order order of
144 /// precedence):
145 /// 1. Better occupancy
146 /// 2. Less spilling (first preference to VGPR spills, then to SGPR spills)
147 /// 3. Less tuple register pressure (first preference to VGPR tuples if we
148 /// determine that SGPR pressure is not important)
149 /// 4. Less raw register pressure (first preference to VGPR tuples if we
150 /// determine that SGPR pressure is not important)
151 bool less(const MachineFunction &MF, const GCNRegPressure &O,
152 unsigned MaxOccupancy = std::numeric_limits<unsigned>::max()) const;
153
154 bool operator==(const GCNRegPressure &O) const { return Value == O.Value; }
155
156 bool operator!=(const GCNRegPressure &O) const {
157 return !(*this == O);
158 }
159
161 for (unsigned I = 0; I < ValueArraySize; ++I)
162 Value[I] += RHS.Value[I];
163 return *this;
164 }
165
167 for (unsigned I = 0; I < ValueArraySize; ++I)
168 Value[I] -= RHS.Value[I];
169 return *this;
170 }
171
172 void dump() const;
173
174 static RegKind getRegKind(unsigned Reg, const MachineRegisterInfo &MRI) {
176 const SIRegisterInfo *STI = static_cast<const SIRegisterInfo *>(TRI);
177 return (RegKind)getRegKind(MRI.getRegClass(Reg), STI);
178 }
179
180private:
181 static constexpr unsigned ValueArraySize = TOTAL_KINDS * 2;
182
183 /// Pressure for all register kinds (first all regular registers kinds, then
184 /// all tuple register kinds).
185 std::array<unsigned, ValueArraySize> Value;
186
187 static unsigned getRegKind(const TargetRegisterClass *RC,
188 const SIRegisterInfo *STI);
189
190 friend GCNRegPressure max(const GCNRegPressure &P1,
191 const GCNRegPressure &P2);
192
193 friend Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST,
194 unsigned DynamicVGPRBlockSize);
195};
196
197inline GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2) {
198 GCNRegPressure Res;
199 for (unsigned I = 0; I < GCNRegPressure::ValueArraySize; ++I)
200 Res.Value[I] = std::max(P1.Value[I], P2.Value[I]);
201 return Res;
202}
203
205 const GCNRegPressure &P2) {
206 GCNRegPressure Sum = P1;
207 Sum += P2;
208 return Sum;
209}
210
212 const GCNRegPressure &P2) {
213 GCNRegPressure Diff = P1;
214 Diff -= P2;
215 return Diff;
216}
217
218////////////////////////////////////////////////////////////////////////////////
219// GCNRPTarget
220
221/// Models a register pressure target, allowing to evaluate and track register
222/// savings against that target from a starting \ref GCNRegPressure.
224public:
225 /// Sets up the target such that the register pressure starting at \p RP does
226 /// not show register spilling on function \p MF (w.r.t. the function's
227 /// mininum target occupancy).
228 GCNRPTarget(const MachineFunction &MF, const GCNRegPressure &RP);
229
230 /// Sets up the target such that the register pressure starting at \p RP does
231 /// not use more than \p NumSGPRs SGPRs and \p NumVGPRs VGPRs on function \p
232 /// MF.
233 GCNRPTarget(unsigned NumSGPRs, unsigned NumVGPRs, const MachineFunction &MF,
234 const GCNRegPressure &RP);
235
236 /// Sets up the target such that the register pressure starting at \p RP does
237 /// not prevent achieving an occupancy of at least \p Occupancy on function
238 /// \p MF.
239 GCNRPTarget(unsigned Occupancy, const MachineFunction &MF,
240 const GCNRegPressure &RP);
241
242 /// Changes the target (same semantics as constructor).
243 void setTarget(unsigned NumSGPRs, unsigned NumVGPRs);
244
245 const GCNRegPressure &getCurrentRP() const { return RP; }
246
247 void setRP(const GCNRegPressure &NewRP) { RP = NewRP; }
248
249 /// Determines whether saving virtual register \p Reg will be beneficial
250 /// towards achieving the RP target.
251 bool isSaveBeneficial(Register Reg) const;
252
253 /// Returns whether the benefit that saving \p SaveRP represents will be
254 /// beneficial towards achieving the RP target.
255 bool isSaveBeneficial(const GCNRegPressure &SaveRP) const;
256
257 /// Saves virtual register \p Reg with lanemask \p Mask.
259 RP.inc(Reg, Mask, LaneBitmask::getNone(), MRI);
260 }
261
262 /// Returns the benefit towards achieving the RP target that saving \p SaveRP
263 /// represents, in total number of registers saved across all classes.
264 unsigned getNumRegsBenefit(const GCNRegPressure &SaveRP) const;
265
266 /// Saves a total pressure of \p SaveRP.
267 void saveRP(const GCNRegPressure &SaveRP) {
268 assert(!RP.less(MF, SaveRP) && "saving beyond current RP");
269 RP -= SaveRP;
270 }
271
272 /// Whether \p TestRP is at or below the defined pressure target.
273 bool satisfied(const GCNRegPressure &TestRP) const;
274 /// Whether the current RP is at or below the defined pressure target.
275 bool satisfied() const { return satisfied(RP); }
276 bool hasVectorRegisterExcess() const;
277
278 unsigned getMaxSGPRs() const { return MaxSGPRs; }
279 unsigned getMaxVGPRs() const {
280 return UnifiedRF ? MaxUnifiedVGPRs : MaxVGPRs;
281 }
282
283#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
285 OS << "Actual/Target: " << Target.RP.getSGPRNum() << '/' << Target.MaxSGPRs
286 << " SGPRs, " << Target.RP.getArchVGPRNum() << '/' << Target.MaxVGPRs
287 << " ArchVGPRs, " << Target.RP.getAGPRNum() << '/' << Target.MaxVGPRs
288 << " AGPRs";
289
290 if (Target.MaxUnifiedVGPRs) {
291 OS << ", " << Target.RP.getVGPRNum(true) << '/' << Target.MaxUnifiedVGPRs
292 << " VGPRs (unified)";
293 }
294 return OS;
295 }
296#endif
297
298private:
299 const MachineFunction &MF;
300 const bool UnifiedRF;
301
302 /// Current register pressure.
304
305 /// Target number of SGPRs.
306 unsigned MaxSGPRs = 0;
307 /// Target number of ArchVGPRs and AGPRs.
308 unsigned MaxVGPRs = 0;
309 /// Target number of overall VGPRs for subtargets with unified RFs. Always 0
310 /// for subtargets with non-unified RFs.
311 unsigned MaxUnifiedVGPRs = 0;
312
313 GCNRPTarget(const GCNRegPressure &RP, const MachineFunction &MF)
314 : MF(MF), UnifiedRF(MF.getSubtarget<GCNSubtarget>().hasGFX90AInsts()),
315 RP(RP) {}
316};
317
318///////////////////////////////////////////////////////////////////////////////
319// GCNRPTracker
320
322public:
324
325protected:
329 const MachineInstr *LastTrackedMI = nullptr;
330 mutable const MachineRegisterInfo *MRI = nullptr;
331
332 GCNRPTracker(const LiveIntervals &LIS_) : LIS(LIS_) {}
333
334 /// Resets tracker before or \p After the provided \p MI, which can be a debug
335 /// instruction.
336 void reset(const MachineInstr &MI, bool After);
337
338 /// Resets tracker at the start or \p End of the \p MBB.
339 void reset(const MachineBasicBlock &MBB, bool End);
340
341 /// Resets tracker at the specified slot index \p SI.
343
345
346public:
347 /// Resets tracker with the provided \p LiveRegs.
348 void reset(const MachineRegisterInfo &MRI, const LiveRegSet &LiveRegs);
349
350 // live regs for the current state
351 const decltype(LiveRegs) &getLiveRegs() const { return LiveRegs; }
352 const MachineInstr *getLastTrackedMI() const { return LastTrackedMI; }
353
354 void clearMaxPressure() { MaxPressure.clear(); }
355
357
358 decltype(LiveRegs) moveLiveRegs() {
359 return std::move(LiveRegs);
360 }
361};
362
364getLiveRegs(SlotIndex SI, const LiveIntervals &LIS,
365 const MachineRegisterInfo &MRI,
367
368////////////////////////////////////////////////////////////////////////////////
369// GCNUpwardRPTracker
370
372public:
374
376
377 /// Resets tracker to the point just after \p MI (in program order), which can
378 /// be a debug instruction.
379 void reset(const MachineInstr &MI) { reset(MI, /*After=*/true); }
380
381 /// Move to the state of RP just before the \p MI . If \p UseInternalIterator
382 /// is set, also update the internal iterators. Setting \p UseInternalIterator
383 /// to false allows for an externally managed iterator / program order.
384 void recede(const MachineInstr &MI);
385
386 /// \p returns whether the tracker's state after receding MI corresponds
387 /// to reported by LIS.
388 bool isValid() const;
389
390 const GCNRegPressure &getMaxPressure() const { return MaxPressure; }
391
393
399};
400
401////////////////////////////////////////////////////////////////////////////////
402// GCNDownwardRPTracker
403
405 // Last position of reset or advanceBeforeNext
407
409
410 /// Drop the lanes of \p Reg that are no longer live at \p SI, decreasing
411 /// CurPressure accordingly. \p Reg must be a virtual register that is
412 /// currently tracked as live.
413 void retireVirtReg(Register Reg, SlotIndex SI);
414
415public:
417
419
421
422 /// \p return MaxPressure and clear it.
424 auto Res = MaxPressure;
425 MaxPressure.clear();
426 return Res;
427 }
428
429 /// Reset tracker to the point before the \p MI filling \p LiveRegs upon this
430 /// point using LIS. \p End must be between the MI and the end of its parent
431 /// block (inclusive). \p returns false if the range [MI, End) is empty except
432 /// debug values.
434 const LiveRegSet *LiveRegs = nullptr);
435
436 /// Move to the state right before the next MI or after the end of MBB.
437 /// \p returns false if reached end of the block.
438 /// If \p UseInternalIterator is true, then internal iterators are used and
439 /// set to process in program order. If \p UseInternalIterator is false, then
440 /// it is assumed that the tracker is using an externally managed iterator,
441 /// and advance* calls will not update the state of the iterator. In such
442 /// cases, the tracker will move to the state right before the provided \p MI
443 /// and use LIS for RP calculations.
444 bool advanceBeforeNext(MachineInstr *MI = nullptr,
445 bool UseInternalIterator = true);
446
447 /// Move to the state at the MI, advanceBeforeNext has to be called first.
448 /// If \p UseInternalIterator is true, then internal iterators are used and
449 /// set to process in program order. If \p UseInternalIterator is false, then
450 /// it is assumed that the tracker is using an externally managed iterator,
451 /// and advance* calls will not update the state of the iterator. In such
452 /// cases, the tracker will move to the state at the provided \p MI .
453 void advanceToNext(MachineInstr *MI = nullptr,
454 bool UseInternalIterator = true);
455
456 /// Move to the state at the next MI. \p returns false if reached end of
457 /// block. If \p UseInternalIterator is true, then internal iterators are used
458 /// and set to process in program order. If \p UseInternalIterator is false,
459 /// then it is assumed that the tracker is using an externally managed
460 /// iterator, and advance* calls will not update the state of the iterator. In
461 /// such cases, the tracker will move to the state right before the provided
462 /// \p MI and use LIS for RP calculations.
463 bool advance(MachineInstr *MI = nullptr, bool UseInternalIterator = true);
464
465 /// Advance instructions until before \p End using internal iterators to
466 /// process instructions in program order. Returns whether iterators actually
467 /// had to advance to reach \p End.
469
470 /// Reset tracker to \p Begin (filling \p LiveRegs upon this point using LIS)
471 /// and advance to \p End, which must be between \p Begin and the end of its
472 /// parent block (inclusive). \p returns false if the range [Begin, End) is
473 /// empty except debug values.
476 const LiveRegSet *LiveRegsCopy = nullptr);
477
478 /// Mostly copy/paste from CodeGen/RegisterPressure.cpp
479 /// Calculate the impact \p MI will have on CurPressure and \return the
480 /// speculated pressure. In order to support RP Speculation, this does not
481 /// rely on the implicit program ordering in the LiveIntervals.
483 const SIRegisterInfo *TRI) const;
484};
485
486/// \returns the LaneMask of live lanes of \p Reg at position \p SI. Only the
487/// active lanes of \p LaneMaskFilter will be set in the return value. This is
488/// used, for example, to limit the live lanes to a specific subreg when
489/// calculating use masks.
490LaneBitmask getLiveLaneMask(unsigned Reg, SlotIndex SI,
491 const LiveIntervals &LIS,
492 const MachineRegisterInfo &MRI,
493 LaneBitmask LaneMaskFilter = LaneBitmask::getAll());
494
495LaneBitmask getLiveLaneMask(const LiveInterval &LI, SlotIndex SI,
496 const MachineRegisterInfo &MRI,
497 LaneBitmask LaneMaskFilter = LaneBitmask::getAll());
498
499/// creates a map MachineInstr -> LiveRegSet
500/// R - range of iterators on instructions
501/// After - upon entry or exit of every instruction
502/// Note: there is no entry in the map for instructions with empty live reg set
503/// Complexity = O(NumVirtRegs * averageLiveRangeSegmentsPerReg * lg(R))
504template <typename Range>
505DenseMap<MachineInstr*, GCNRPTracker::LiveRegSet>
506getLiveRegMap(Range &&R, bool After, LiveIntervals &LIS) {
507 std::vector<SlotIndex> Indexes;
508 Indexes.reserve(llvm::size(R));
509 auto &SII = *LIS.getSlotIndexes();
510 for (MachineInstr *I : R) {
511 auto SI = SII.getInstructionIndex(*I);
512 Indexes.push_back(After ? SI.getDeadSlot() : SI.getBaseIndex());
513 }
514 llvm::sort(Indexes);
515
516 auto &MRI = (*R.begin())->getMF()->getRegInfo();
518 SmallVector<SlotIndex, 32> LiveIdxs, SRLiveIdxs;
519 for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
521 if (!LIS.hasInterval(Reg))
522 continue;
523 auto &LI = LIS.getInterval(Reg);
524 LiveIdxs.clear();
525 if (!LI.findIndexesLiveAt(Indexes, std::back_inserter(LiveIdxs)))
526 continue;
527 if (!LI.hasSubRanges()) {
528 for (auto SI : LiveIdxs)
529 LiveRegMap[SII.getInstructionFromIndex(SI)][Reg] =
530 MRI.getMaxLaneMaskForVReg(Reg);
531 } else
532 for (const auto &S : LI.subranges()) {
533 // constrain search for subranges by indexes live at main range
534 SRLiveIdxs.clear();
535 S.findIndexesLiveAt(LiveIdxs, std::back_inserter(SRLiveIdxs));
536 for (auto SI : SRLiveIdxs)
537 LiveRegMap[SII.getInstructionFromIndex(SI)][Reg] |= S.LaneMask;
538 }
539 }
540 return LiveRegMap;
541}
542
544 const LiveIntervals &LIS) {
546 MI.getMF()->getRegInfo());
547}
548
550 const LiveIntervals &LIS) {
552 MI.getMF()->getRegInfo());
553}
554
555template <typename Range>
557 Range &&LiveRegs) {
558 GCNRegPressure Res;
559 for (const auto &RM : LiveRegs)
560 Res.inc(RM.first, LaneBitmask::getNone(), RM.second, MRI);
561 return Res;
562}
563
565 const GCNRPTracker::LiveRegSet &S2);
566
567Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST = nullptr,
568 unsigned DynamicVGPRBlockSize = 0);
569
571 const MachineRegisterInfo &MRI);
572
573Printable reportMismatch(const GCNRPTracker::LiveRegSet &LISLR,
574 const GCNRPTracker::LiveRegSet &TrackedL,
575 const TargetRegisterInfo *TRI, StringRef Pfx = " ");
576
578 static char ID;
579
580public:
582
583 bool runOnMachineFunction(MachineFunction &MF) override;
584
590};
591
594 LiveIntervals &LIS,
595 const MachineLoopInfo *MLI);
596
597/// Estimate VGPR pressure using greedy, non-splitting register allocation
598/// simulation, accounting for live interval interference.
599/// \param RegionBegin Start iterator of the region
600/// \param RegionEnd End iterator of the region
601/// \param LiveIns Live-in registers for the region
602/// \returns estimated VGPR pressure
606 const GCNRPTracker::LiveRegSet &LiveIns, const LiveIntervals &LIS,
607 const MachineRegisterInfo &MRI, const SIRegisterInfo &TRI);
608
609} // end namespace llvm
610
611#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:215
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)
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.
bool reset(const MachineInstr &MI, MachineBasicBlock::const_iterator End, const LiveRegSet *LiveRegs=nullptr)
Reset tracker to the point before the MI filling LiveRegs upon this point using LIS.
GCNRegPressure moveMaxPressure()
return MaxPressure and clear it.
bool advanceBeforeNext(MachineInstr *MI=nullptr, bool UseInternalIterator=true)
Move to the state right before the next MI or after the end of MBB.
bool advance(MachineInstr *MI=nullptr, bool UseInternalIterator=true)
Move to the state at the next MI.
GCNRegPressure bumpDownwardPressure(const MachineInstr *MI, const SIRegisterInfo *TRI) const
Mostly copy/paste from CodeGen/RegisterPressure.cpp Calculate the impact MI will have on CurPressure ...
MachineBasicBlock::const_iterator getNext() const
GCNDownwardRPTracker(const LiveIntervals &LIS_)
void advanceToNext(MachineInstr *MI=nullptr, bool UseInternalIterator=true)
Move to the state at the MI, advanceBeforeNext has to be called first.
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.
void saveReg(Register Reg, LaneBitmask Mask, const MachineRegisterInfo &MRI)
Saves virtual register Reg with lanemask Mask.
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,...
GCNRegPressure getPressure() const
const decltype(LiveRegs) & getLiveRegs() const
const MachineInstr * LastTrackedMI
decltype(LiveRegs) moveLiveRegs()
GCNRegPressure CurPressure
DenseMap< unsigned, LaneBitmask > LiveRegSet
LaneBitmask getLastUsedLanes(Register Reg, SlotIndex Pos) const
Mostly copy/paste from CodeGen/RegisterPressure.cpp.
GCNRPTracker(const LiveIntervals &LIS_)
GCNRegPressure MaxPressure
const MachineInstr * getLastTrackedMI() const
const MachineRegisterInfo * MRI
const LiveIntervals & LIS
void reset(const MachineInstr &MI, bool After)
Resets tracker before or After the provided MI, which can be a debug instruction.
GCNUpwardRPTracker(const LiveIntervals &LIS_)
GCNRegPressure getMaxPressureAndReset()
void recede(const MachineInstr &MI)
Move to the state of RP just before the MI .
const GCNRegPressure & getMaxPressure() const
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,...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
const TargetRegisterInfo * getTargetRegisterInfo() const
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:66
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:144
constexpr NextUseDistance max(NextUseDistance A, NextUseDistance B)
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)
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)
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
friend GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
void inc(unsigned Reg, LaneBitmask PrevMask, LaneBitmask NewMask, const MachineRegisterInfo &MRI)
bool higherOccupancy(const GCNSubtarget &ST, const GCNRegPressure &O, unsigned DynamicVGPRBlockSize) const
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,...
unsigned getAVGPRNum() const
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