LLVM 17.0.0git
GCNRegPressure.cpp
Go to the documentation of this file.
1//===- GCNRegPressure.cpp -------------------------------------------------===//
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 implements the GCNRegPressure class.
11///
12//===----------------------------------------------------------------------===//
13
14#include "GCNRegPressure.h"
16
17using namespace llvm;
18
19#define DEBUG_TYPE "machine-scheduler"
20
22 const GCNRPTracker::LiveRegSet &S2) {
23 if (S1.size() != S2.size())
24 return false;
25
26 for (const auto &P : S1) {
27 auto I = S2.find(P.first);
28 if (I == S2.end() || I->second != P.second)
29 return false;
30 }
31 return true;
32}
33
34
35///////////////////////////////////////////////////////////////////////////////
36// GCNRegPressure
37
38unsigned GCNRegPressure::getRegKind(Register Reg,
39 const MachineRegisterInfo &MRI) {
40 assert(Reg.isVirtual());
41 const auto RC = MRI.getRegClass(Reg);
42 auto STI = static_cast<const SIRegisterInfo*>(MRI.getTargetRegisterInfo());
43 return STI->isSGPRClass(RC)
44 ? (STI->getRegSizeInBits(*RC) == 32 ? SGPR32 : SGPR_TUPLE)
45 : STI->isAGPRClass(RC)
46 ? (STI->getRegSizeInBits(*RC) == 32 ? AGPR32 : AGPR_TUPLE)
47 : (STI->getRegSizeInBits(*RC) == 32 ? VGPR32 : VGPR_TUPLE);
48}
49
50void GCNRegPressure::inc(unsigned Reg,
51 LaneBitmask PrevMask,
52 LaneBitmask NewMask,
53 const MachineRegisterInfo &MRI) {
56 return;
57
58 int Sign = 1;
59 if (NewMask < PrevMask) {
60 std::swap(NewMask, PrevMask);
61 Sign = -1;
62 }
63
64 switch (auto Kind = getRegKind(Reg, MRI)) {
65 case SGPR32:
66 case VGPR32:
67 case AGPR32:
68 Value[Kind] += Sign;
69 break;
70
71 case SGPR_TUPLE:
72 case VGPR_TUPLE:
73 case AGPR_TUPLE:
74 assert(PrevMask < NewMask);
75
76 Value[Kind == SGPR_TUPLE ? SGPR32 : Kind == AGPR_TUPLE ? AGPR32 : VGPR32] +=
77 Sign * SIRegisterInfo::getNumCoveredRegs(~PrevMask & NewMask);
78
79 if (PrevMask.none()) {
80 assert(NewMask.any());
81 Value[Kind] += Sign * MRI.getPressureSets(Reg).getWeight();
82 }
83 break;
84
85 default: llvm_unreachable("Unknown register kind");
86 }
87}
88
90 const GCNRegPressure& O,
91 unsigned MaxOccupancy) const {
92 const auto SGPROcc = std::min(MaxOccupancy,
93 ST.getOccupancyWithNumSGPRs(getSGPRNum()));
94 const auto VGPROcc =
95 std::min(MaxOccupancy,
96 ST.getOccupancyWithNumVGPRs(getVGPRNum(ST.hasGFX90AInsts())));
97 const auto OtherSGPROcc = std::min(MaxOccupancy,
98 ST.getOccupancyWithNumSGPRs(O.getSGPRNum()));
99 const auto OtherVGPROcc =
100 std::min(MaxOccupancy,
101 ST.getOccupancyWithNumVGPRs(O.getVGPRNum(ST.hasGFX90AInsts())));
102
103 const auto Occ = std::min(SGPROcc, VGPROcc);
104 const auto OtherOcc = std::min(OtherSGPROcc, OtherVGPROcc);
105 if (Occ != OtherOcc)
106 return Occ > OtherOcc;
107
108 bool SGPRImportant = SGPROcc < VGPROcc;
109 const bool OtherSGPRImportant = OtherSGPROcc < OtherVGPROcc;
110
111 // if both pressures disagree on what is more important compare vgprs
112 if (SGPRImportant != OtherSGPRImportant) {
113 SGPRImportant = false;
114 }
115
116 // compare large regs pressure
117 bool SGPRFirst = SGPRImportant;
118 for (int I = 2; I > 0; --I, SGPRFirst = !SGPRFirst) {
119 if (SGPRFirst) {
120 auto SW = getSGPRTuplesWeight();
121 auto OtherSW = O.getSGPRTuplesWeight();
122 if (SW != OtherSW)
123 return SW < OtherSW;
124 } else {
125 auto VW = getVGPRTuplesWeight();
126 auto OtherVW = O.getVGPRTuplesWeight();
127 if (VW != OtherVW)
128 return VW < OtherVW;
129 }
130 }
131 return SGPRImportant ? (getSGPRNum() < O.getSGPRNum()):
132 (getVGPRNum(ST.hasGFX90AInsts()) <
133 O.getVGPRNum(ST.hasGFX90AInsts()));
134}
135
136#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
139 return Printable([&RP, ST](raw_ostream &OS) {
140 OS << "VGPRs: " << RP.Value[GCNRegPressure::VGPR32] << ' '
141 << "AGPRs: " << RP.getAGPRNum();
142 if (ST)
143 OS << "(O"
144 << ST->getOccupancyWithNumVGPRs(RP.getVGPRNum(ST->hasGFX90AInsts()))
145 << ')';
146 OS << ", SGPRs: " << RP.getSGPRNum();
147 if (ST)
148 OS << "(O" << ST->getOccupancyWithNumSGPRs(RP.getSGPRNum()) << ')';
149 OS << ", LVGPR WT: " << RP.getVGPRTuplesWeight()
150 << ", LSGPR WT: " << RP.getSGPRTuplesWeight();
151 if (ST)
152 OS << " -> Occ: " << RP.getOccupancy(*ST);
153 OS << '\n';
154 });
155}
156#endif
157
159 const MachineRegisterInfo &MRI) {
160 assert(MO.isDef() && MO.isReg() && MO.getReg().isVirtual());
161
162 // We don't rely on read-undef flag because in case of tentative schedule
163 // tracking it isn't set correctly yet. This works correctly however since
164 // use mask has been tracked before using LIS.
165 return MO.getSubReg() == 0 ?
166 MRI.getMaxLaneMaskForVReg(MO.getReg()) :
167 MRI.getTargetRegisterInfo()->getSubRegIndexLaneMask(MO.getSubReg());
168}
169
172 const LiveIntervals &LIS) {
173 assert(MO.isUse() && MO.isReg() && MO.getReg().isVirtual());
174
175 if (auto SubReg = MO.getSubReg())
176 return MRI.getTargetRegisterInfo()->getSubRegIndexLaneMask(SubReg);
177
178 auto MaxMask = MRI.getMaxLaneMaskForVReg(MO.getReg());
179 if (SIRegisterInfo::getNumCoveredRegs(MaxMask) > 1) // cannot have subregs
180 return MaxMask;
181
182 // For a tentative schedule LIS isn't updated yet but livemask should remain
183 // the same on any schedule. Subreg defs can be reordered but they all must
184 // dominate uses anyway.
185 auto SI = LIS.getInstructionIndex(*MO.getParent()).getBaseIndex();
186 return getLiveLaneMask(MO.getReg(), SI, LIS, MRI);
187}
188
191 const MachineRegisterInfo &MRI) {
193 for (const auto &MO : MI.operands()) {
194 if (!MO.isReg() || !MO.getReg().isVirtual())
195 continue;
196 if (!MO.isUse() || !MO.readsReg())
197 continue;
198
199 auto const UsedMask = getUsedRegMask(MO, MRI, LIS);
200
201 auto Reg = MO.getReg();
202 auto I = llvm::find_if(
203 Res, [Reg](const RegisterMaskPair &RM) { return RM.RegUnit == Reg; });
204 if (I != Res.end())
205 I->LaneMask |= UsedMask;
206 else
207 Res.push_back(RegisterMaskPair(Reg, UsedMask));
208 }
209 return Res;
210}
211
212///////////////////////////////////////////////////////////////////////////////
213// GCNRPTracker
214
216 SlotIndex SI,
217 const LiveIntervals &LIS,
218 const MachineRegisterInfo &MRI) {
219 LaneBitmask LiveMask;
220 const auto &LI = LIS.getInterval(Reg);
221 if (LI.hasSubRanges()) {
222 for (const auto &S : LI.subranges())
223 if (S.liveAt(SI)) {
224 LiveMask |= S.LaneMask;
225 assert(LiveMask < MRI.getMaxLaneMaskForVReg(Reg) ||
226 LiveMask == MRI.getMaxLaneMaskForVReg(Reg));
227 }
228 } else if (LI.liveAt(SI)) {
229 LiveMask = MRI.getMaxLaneMaskForVReg(Reg);
230 }
231 return LiveMask;
232}
233
235 const LiveIntervals &LIS,
236 const MachineRegisterInfo &MRI) {
238 for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
239 auto Reg = Register::index2VirtReg(I);
240 if (!LIS.hasInterval(Reg))
241 continue;
242 auto LiveMask = getLiveLaneMask(Reg, SI, LIS, MRI);
243 if (LiveMask.any())
244 LiveRegs[Reg] = LiveMask;
245 }
246 return LiveRegs;
247}
248
250 const LiveRegSet *LiveRegsCopy,
251 bool After) {
252 const MachineFunction &MF = *MI.getMF();
253 MRI = &MF.getRegInfo();
254 if (LiveRegsCopy) {
255 if (&LiveRegs != LiveRegsCopy)
256 LiveRegs = *LiveRegsCopy;
257 } else {
258 LiveRegs = After ? getLiveRegsAfter(MI, LIS)
260 }
261
263}
264
266 const LiveRegSet *LiveRegsCopy) {
267 GCNRPTracker::reset(MI, LiveRegsCopy, true);
268}
269
271 assert(MRI && "call reset first");
272
273 LastTrackedMI = &MI;
274
275 if (MI.isDebugInstr())
276 return;
277
278 auto const RegUses = collectVirtualRegUses(MI, LIS, *MRI);
279
280 // calc pressure at the MI (defs + uses)
281 auto AtMIPressure = CurPressure;
282 for (const auto &U : RegUses) {
283 auto LiveMask = LiveRegs[U.RegUnit];
284 AtMIPressure.inc(U.RegUnit, LiveMask, LiveMask | U.LaneMask, *MRI);
285 }
286 // update max pressure
287 MaxPressure = max(AtMIPressure, MaxPressure);
288
289 for (const auto &MO : MI.operands()) {
290 if (!MO.isReg() || !MO.isDef() || !MO.getReg().isVirtual() || MO.isDead())
291 continue;
292
293 auto Reg = MO.getReg();
294 auto I = LiveRegs.find(Reg);
295 if (I == LiveRegs.end())
296 continue;
297 auto &LiveMask = I->second;
298 auto PrevMask = LiveMask;
299 LiveMask &= ~getDefRegMask(MO, *MRI);
300 CurPressure.inc(Reg, PrevMask, LiveMask, *MRI);
301 if (LiveMask.none())
303 }
304 for (const auto &U : RegUses) {
305 auto &LiveMask = LiveRegs[U.RegUnit];
306 auto PrevMask = LiveMask;
307 LiveMask |= U.LaneMask;
308 CurPressure.inc(U.RegUnit, PrevMask, LiveMask, *MRI);
309 }
311}
312
314 const LiveRegSet *LiveRegsCopy) {
315 MRI = &MI.getParent()->getParent()->getRegInfo();
316 LastTrackedMI = nullptr;
317 MBBEnd = MI.getParent()->end();
318 NextMI = &MI;
319 NextMI = skipDebugInstructionsForward(NextMI, MBBEnd);
320 if (NextMI == MBBEnd)
321 return false;
322 GCNRPTracker::reset(*NextMI, LiveRegsCopy, false);
323 return true;
324}
325
327 assert(MRI && "call reset first");
328 if (!LastTrackedMI)
329 return NextMI == MBBEnd;
330
331 assert(NextMI == MBBEnd || !NextMI->isDebugInstr());
332
333 SlotIndex SI = NextMI == MBBEnd
334 ? LIS.getInstructionIndex(*LastTrackedMI).getDeadSlot()
336 assert(SI.isValid());
337
338 // Remove dead registers or mask bits.
339 SmallSet<Register, 8> SeenRegs;
340 for (auto &MO : LastTrackedMI->operands()) {
341 if (!MO.isReg() || !MO.getReg().isVirtual())
342 continue;
343 if (MO.isUse() && !MO.readsReg())
344 continue;
345 if (!SeenRegs.insert(MO.getReg()).second)
346 continue;
347 const LiveInterval &LI = LIS.getInterval(MO.getReg());
348 if (LI.hasSubRanges()) {
349 auto It = LiveRegs.end();
350 for (const auto &S : LI.subranges()) {
351 if (!S.liveAt(SI)) {
352 if (It == LiveRegs.end()) {
353 It = LiveRegs.find(MO.getReg());
354 if (It == LiveRegs.end())
355 llvm_unreachable("register isn't live");
356 }
357 auto PrevMask = It->second;
358 It->second &= ~S.LaneMask;
359 CurPressure.inc(MO.getReg(), PrevMask, It->second, *MRI);
360 }
361 }
362 if (It != LiveRegs.end() && It->second.none())
363 LiveRegs.erase(It);
364 } else if (!LI.liveAt(SI)) {
365 auto It = LiveRegs.find(MO.getReg());
366 if (It == LiveRegs.end())
367 llvm_unreachable("register isn't live");
368 CurPressure.inc(MO.getReg(), It->second, LaneBitmask::getNone(), *MRI);
369 LiveRegs.erase(It);
370 }
371 }
372
374
375 LastTrackedMI = nullptr;
376
377 return NextMI == MBBEnd;
378}
379
381 LastTrackedMI = &*NextMI++;
382 NextMI = skipDebugInstructionsForward(NextMI, MBBEnd);
383
384 // Add new registers or mask bits.
385 for (const auto &MO : LastTrackedMI->operands()) {
386 if (!MO.isReg() || !MO.isDef())
387 continue;
388 Register Reg = MO.getReg();
389 if (!Reg.isVirtual())
390 continue;
391 auto &LiveMask = LiveRegs[Reg];
392 auto PrevMask = LiveMask;
393 LiveMask |= getDefRegMask(MO, *MRI);
394 CurPressure.inc(Reg, PrevMask, LiveMask, *MRI);
395 }
396
398}
399
401 if (NextMI == MBBEnd)
402 return false;
405 return true;
406}
407
409 while (NextMI != End)
410 if (!advance()) return false;
411 return true;
412}
413
416 const LiveRegSet *LiveRegsCopy) {
417 reset(*Begin, LiveRegsCopy);
418 return advance(End);
419}
420
421#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
424 const GCNRPTracker::LiveRegSet &TrackedLR,
425 const TargetRegisterInfo *TRI) {
426 return Printable([&LISLR, &TrackedLR, TRI](raw_ostream &OS) {
427 for (auto const &P : TrackedLR) {
428 auto I = LISLR.find(P.first);
429 if (I == LISLR.end()) {
430 OS << " " << printReg(P.first, TRI) << ":L" << PrintLaneMask(P.second)
431 << " isn't found in LIS reported set\n";
432 } else if (I->second != P.second) {
433 OS << " " << printReg(P.first, TRI)
434 << " masks doesn't match: LIS reported " << PrintLaneMask(I->second)
435 << ", tracked " << PrintLaneMask(P.second) << '\n';
436 }
437 }
438 for (auto const &P : LISLR) {
439 auto I = TrackedLR.find(P.first);
440 if (I == TrackedLR.end()) {
441 OS << " " << printReg(P.first, TRI) << ":L" << PrintLaneMask(P.second)
442 << " isn't found in tracked set\n";
443 }
444 }
445 });
446}
447
449 const auto &SI = LIS.getInstructionIndex(*LastTrackedMI).getBaseIndex();
450 const auto LISLR = llvm::getLiveRegs(SI, LIS, *MRI);
451 const auto &TrackedLR = LiveRegs;
452
453 if (!isEqual(LISLR, TrackedLR)) {
454 dbgs() << "\nGCNUpwardRPTracker error: Tracked and"
455 " LIS reported livesets mismatch:\n"
456 << print(LISLR, *MRI);
457 reportMismatch(LISLR, TrackedLR, MRI->getTargetRegisterInfo());
458 return false;
459 }
460
461 auto LISPressure = getRegPressure(*MRI, LISLR);
462 if (LISPressure != CurPressure) {
463 dbgs() << "GCNUpwardRPTracker error: Pressure sets different\nTracked: "
464 << print(CurPressure) << "LIS rpt: " << print(LISPressure);
465 return false;
466 }
467 return true;
468}
469
472 const MachineRegisterInfo &MRI) {
473 return Printable([&LiveRegs, &MRI](raw_ostream &OS) {
474 const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo();
475 for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
476 Register Reg = Register::index2VirtReg(I);
477 auto It = LiveRegs.find(Reg);
478 if (It != LiveRegs.end() && It->second.any())
479 OS << ' ' << printVRegOrUnit(Reg, TRI) << ':'
480 << PrintLaneMask(It->second);
481 }
482 OS << '\n';
483 });
484}
485
487void GCNRegPressure::dump() const { dbgs() << print(*this); }
488
489#endif
unsigned SubReg
unsigned const MachineRegisterInfo * MRI
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition: Compiler.h:492
static LaneBitmask getDefRegMask(const MachineOperand &MO, const MachineRegisterInfo &MRI)
static LaneBitmask getUsedRegMask(const MachineOperand &MO, const MachineRegisterInfo &MRI, const LiveIntervals &LIS)
static SmallVector< RegisterMaskPair, 8 > collectVirtualRegUses(const MachineInstr &MI, const LiveIntervals &LIS, const MachineRegisterInfo &MRI)
This file defines the GCNRegPressure class, which tracks registry pressure by bookkeeping number of S...
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition: MD5.cpp:58
unsigned const TargetRegisterInfo * TRI
#define P(N)
if(VerifyEach)
@ SI
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:155
bool erase(const KeyT &Val)
Definition: DenseMap.h:315
unsigned size() const
Definition: DenseMap.h:99
iterator end()
Definition: DenseMap.h:84
bool reset(const MachineInstr &MI, const LiveRegSet *LiveRegs=nullptr)
const MachineInstr * LastTrackedMI
GCNRegPressure CurPressure
GCNRegPressure MaxPressure
void reset(const MachineInstr &MI, const LiveRegSet *LiveRegsCopy, bool After)
const MachineRegisterInfo * MRI
const LiveIntervals & LIS
void reset(const MachineInstr &MI, const LiveRegSet *LiveRegs=nullptr)
void recede(const MachineInstr &MI)
LiveInterval - This class represents the liveness of a register, or stack slot.
Definition: LiveInterval.h:686
bool hasSubRanges() const
Returns true if subregister liveness information is available.
Definition: LiveInterval.h:803
iterator_range< subrange_iterator > subranges()
Definition: LiveInterval.h:775
bool hasInterval(Register Reg) const
SlotIndex getInstructionIndex(const MachineInstr &Instr) const
Returns the base index of the given instruction.
LiveInterval & getInterval(Register Reg)
bool liveAt(SlotIndex index) const
Definition: LiveInterval.h:401
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Representation of each machine instruction.
Definition: MachineInstr.h:68
iterator_range< mop_iterator > operands()
Definition: MachineInstr.h:641
MachineOperand class - Representation of each machine instruction operand.
unsigned getSubReg() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
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:19
static Register index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
Definition: Register.h:84
bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Definition: Register.h:91
static unsigned getNumCoveredRegs(LaneBitmask LM)
static bool isSGPRClass(const TargetRegisterClass *RC)
SlotIndex - An opaque wrapper around machine indexes.
Definition: SlotIndexes.h:82
SlotIndex getDeadSlot() const
Returns the dead def kill slot for the current instruction.
Definition: SlotIndexes.h:264
SlotIndex getBaseIndex() const
Returns the base index for associated with this index.
Definition: SlotIndexes.h:246
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition: SmallSet.h:135
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
Definition: SmallSet.h:177
void push_back(const T &Elt)
Definition: SmallVector.h:416
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1200
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
LLVM Value Representation.
Definition: Value.h:74
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
bool isEqual(const GCNRPTracker::LiveRegSet &S1, const GCNRPTracker::LiveRegSet &S2)
GCNRegPressure getRegPressure(const MachineRegisterInfo &MRI, Range &&LiveRegs)
IterT skipDebugInstructionsForward(IterT It, IterT End, bool SkipPseudoOp=true)
Increment It until it points to a non-debug instruction or to End and return the resulting iterator.
GCNRPTracker::LiveRegSet getLiveRegs(SlotIndex SI, const LiveIntervals &LIS, const MachineRegisterInfo &MRI)
GCNRPTracker::LiveRegSet getLiveRegsAfter(const MachineInstr &MI, const LiveIntervals &LIS)
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
LaneBitmask getLiveLaneMask(unsigned Reg, SlotIndex SI, const LiveIntervals &LIS, const MachineRegisterInfo &MRI)
Printable reportMismatch(const GCNRPTracker::LiveRegSet &LISLR, const GCNRPTracker::LiveRegSet &TrackedL, const TargetRegisterInfo *TRI)
Expected< ExpressionValue > max(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
Definition: FileCheck.cpp:337
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1809
GCNRPTracker::LiveRegSet getLiveRegsBefore(const MachineInstr &MI, const LiveIntervals &LIS)
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:853
unsigned getVGPRTuplesWeight() const
unsigned getVGPRNum(bool UnifiedVGPRFile) const
void inc(unsigned Reg, LaneBitmask PrevMask, LaneBitmask NewMask, const MachineRegisterInfo &MRI)
unsigned getSGPRNum() const
bool less(const GCNSubtarget &ST, const GCNRegPressure &O, unsigned MaxOccupancy=std::numeric_limits< unsigned >::max()) const
unsigned getSGPRTuplesWeight() const
friend Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST)
constexpr bool none() const
Definition: LaneBitmask.h:52
static constexpr LaneBitmask getNone()
Definition: LaneBitmask.h:81