LLVM 22.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"
15#include "AMDGPU.h"
18
19using namespace llvm;
20
21#define DEBUG_TYPE "machine-scheduler"
22
24 const GCNRPTracker::LiveRegSet &S2) {
25 if (S1.size() != S2.size())
26 return false;
27
28 for (const auto &P : S1) {
29 auto I = S2.find(P.first);
30 if (I == S2.end() || I->second != P.second)
31 return false;
32 }
33 return true;
34}
35
36///////////////////////////////////////////////////////////////////////////////
37// GCNRegPressure
38
39unsigned GCNRegPressure::getRegKind(const TargetRegisterClass *RC,
40 const SIRegisterInfo *STI) {
41 return STI->isSGPRClass(RC)
42 ? SGPR
43 : (STI->isAGPRClass(RC)
44 ? AGPR
45 : (STI->isVectorSuperClass(RC) ? AVGPR : VGPR));
46}
47
48void GCNRegPressure::inc(unsigned Reg,
49 LaneBitmask PrevMask,
50 LaneBitmask NewMask,
51 const MachineRegisterInfo &MRI) {
52 unsigned NewNumCoveredRegs = SIRegisterInfo::getNumCoveredRegs(NewMask);
53 unsigned PrevNumCoveredRegs = SIRegisterInfo::getNumCoveredRegs(PrevMask);
54 if (NewNumCoveredRegs == PrevNumCoveredRegs)
55 return;
56
57 int Sign = 1;
58 if (NewMask < PrevMask) {
59 std::swap(NewMask, PrevMask);
60 std::swap(NewNumCoveredRegs, PrevNumCoveredRegs);
61 Sign = -1;
62 }
63 assert(PrevMask < NewMask && PrevNumCoveredRegs < NewNumCoveredRegs &&
64 "prev mask should always be lesser than new");
65
66 const TargetRegisterClass *RC = MRI.getRegClass(Reg);
67 const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo();
68 const SIRegisterInfo *STI = static_cast<const SIRegisterInfo *>(TRI);
69 unsigned RegKind = getRegKind(RC, STI);
70 if (TRI->getRegSizeInBits(*RC) != 32) {
71 // Reg is from a tuple register class.
72 if (PrevMask.none()) {
73 unsigned TupleIdx = TOTAL_KINDS + RegKind;
74 Value[TupleIdx] += Sign * TRI->getRegClassWeight(RC).RegWeight;
75 }
76 // Pressure scales with number of new registers covered by the new mask.
77 // Note when true16 is enabled, we can no longer safely use the following
78 // approach to calculate the difference in the number of 32-bit registers
79 // between two masks:
80 //
81 // Sign *= SIRegisterInfo::getNumCoveredRegs(~PrevMask & NewMask);
82 //
83 // The issue is that the mask calculation `~PrevMask & NewMask` doesn't
84 // properly account for partial usage of a 32-bit register when dealing with
85 // 16-bit registers.
86 //
87 // Consider this example:
88 // Assume PrevMask = 0b0010 and NewMask = 0b1111. Here, the correct register
89 // usage difference should be 1, because even though PrevMask uses only half
90 // of a 32-bit register, it should still be counted as a full register use.
91 // However, the mask calculation yields `~PrevMask & NewMask = 0b1101`, and
92 // calling `getNumCoveredRegs` returns 2 instead of 1. This incorrect
93 // calculation can lead to integer overflow when Sign = -1.
94 Sign *= NewNumCoveredRegs - PrevNumCoveredRegs;
95 }
96 Value[RegKind] += Sign;
97}
98
100 unsigned MaxOccupancy) const {
101 const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
102 unsigned DynamicVGPRBlockSize =
103 MF.getInfo<SIMachineFunctionInfo>()->getDynamicVGPRBlockSize();
104
105 const auto SGPROcc = std::min(MaxOccupancy,
106 ST.getOccupancyWithNumSGPRs(getSGPRNum()));
107 const auto VGPROcc = std::min(
108 MaxOccupancy, ST.getOccupancyWithNumVGPRs(getVGPRNum(ST.hasGFX90AInsts()),
109 DynamicVGPRBlockSize));
110 const auto OtherSGPROcc = std::min(MaxOccupancy,
111 ST.getOccupancyWithNumSGPRs(O.getSGPRNum()));
112 const auto OtherVGPROcc =
113 std::min(MaxOccupancy,
114 ST.getOccupancyWithNumVGPRs(O.getVGPRNum(ST.hasGFX90AInsts()),
115 DynamicVGPRBlockSize));
116
117 const auto Occ = std::min(SGPROcc, VGPROcc);
118 const auto OtherOcc = std::min(OtherSGPROcc, OtherVGPROcc);
119
120 // Give first precedence to the better occupancy.
121 if (Occ != OtherOcc)
122 return Occ > OtherOcc;
123
124 unsigned MaxVGPRs = ST.getMaxNumVGPRs(MF);
125 unsigned MaxSGPRs = ST.getMaxNumSGPRs(MF);
126
127 // SGPR excess pressure conditions
128 unsigned ExcessSGPR = std::max(static_cast<int>(getSGPRNum() - MaxSGPRs), 0);
129 unsigned OtherExcessSGPR =
130 std::max(static_cast<int>(O.getSGPRNum() - MaxSGPRs), 0);
131
132 auto WaveSize = ST.getWavefrontSize();
133 // The number of virtual VGPRs required to handle excess SGPR
134 unsigned VGPRForSGPRSpills = (ExcessSGPR + (WaveSize - 1)) / WaveSize;
135 unsigned OtherVGPRForSGPRSpills =
136 (OtherExcessSGPR + (WaveSize - 1)) / WaveSize;
137
138 unsigned MaxArchVGPRs = ST.getAddressableNumArchVGPRs();
139
140 // Unified excess pressure conditions, accounting for VGPRs used for SGPR
141 // spills
142 unsigned ExcessVGPR =
143 std::max(static_cast<int>(getVGPRNum(ST.hasGFX90AInsts()) +
144 VGPRForSGPRSpills - MaxVGPRs),
145 0);
146 unsigned OtherExcessVGPR =
147 std::max(static_cast<int>(O.getVGPRNum(ST.hasGFX90AInsts()) +
148 OtherVGPRForSGPRSpills - MaxVGPRs),
149 0);
150 // Arch VGPR excess pressure conditions, accounting for VGPRs used for SGPR
151 // spills
152 unsigned ExcessArchVGPR = std::max(
153 static_cast<int>(getVGPRNum(false) + VGPRForSGPRSpills - MaxArchVGPRs),
154 0);
155 unsigned OtherExcessArchVGPR =
156 std::max(static_cast<int>(O.getVGPRNum(false) + OtherVGPRForSGPRSpills -
157 MaxArchVGPRs),
158 0);
159 // AGPR excess pressure conditions
160 unsigned ExcessAGPR = std::max(
161 static_cast<int>(ST.hasGFX90AInsts() ? (getAGPRNum() - MaxArchVGPRs)
162 : (getAGPRNum() - MaxVGPRs)),
163 0);
164 unsigned OtherExcessAGPR = std::max(
165 static_cast<int>(ST.hasGFX90AInsts() ? (O.getAGPRNum() - MaxArchVGPRs)
166 : (O.getAGPRNum() - MaxVGPRs)),
167 0);
168
169 bool ExcessRP = ExcessSGPR || ExcessVGPR || ExcessArchVGPR || ExcessAGPR;
170 bool OtherExcessRP = OtherExcessSGPR || OtherExcessVGPR ||
171 OtherExcessArchVGPR || OtherExcessAGPR;
172
173 // Give second precedence to the reduced number of spills to hold the register
174 // pressure.
175 if (ExcessRP || OtherExcessRP) {
176 // The difference in excess VGPR pressure, after including VGPRs used for
177 // SGPR spills
178 int VGPRDiff = ((OtherExcessVGPR + OtherExcessArchVGPR + OtherExcessAGPR) -
179 (ExcessVGPR + ExcessArchVGPR + ExcessAGPR));
180
181 int SGPRDiff = OtherExcessSGPR - ExcessSGPR;
182
183 if (VGPRDiff != 0)
184 return VGPRDiff > 0;
185 if (SGPRDiff != 0) {
186 unsigned PureExcessVGPR =
187 std::max(static_cast<int>(getVGPRNum(ST.hasGFX90AInsts()) - MaxVGPRs),
188 0) +
189 std::max(static_cast<int>(getVGPRNum(false) - MaxArchVGPRs), 0);
190 unsigned OtherPureExcessVGPR =
191 std::max(
192 static_cast<int>(O.getVGPRNum(ST.hasGFX90AInsts()) - MaxVGPRs),
193 0) +
194 std::max(static_cast<int>(O.getVGPRNum(false) - MaxArchVGPRs), 0);
195
196 // If we have a special case where there is a tie in excess VGPR, but one
197 // of the pressures has VGPR usage from SGPR spills, prefer the pressure
198 // with SGPR spills.
199 if (PureExcessVGPR != OtherPureExcessVGPR)
200 return SGPRDiff < 0;
201 // If both pressures have the same excess pressure before and after
202 // accounting for SGPR spills, prefer fewer SGPR spills.
203 return SGPRDiff > 0;
204 }
205 }
206
207 bool SGPRImportant = SGPROcc < VGPROcc;
208 const bool OtherSGPRImportant = OtherSGPROcc < OtherVGPROcc;
209
210 // If both pressures disagree on what is more important compare vgprs.
211 if (SGPRImportant != OtherSGPRImportant) {
212 SGPRImportant = false;
213 }
214
215 // Give third precedence to lower register tuple pressure.
216 bool SGPRFirst = SGPRImportant;
217 for (int I = 2; I > 0; --I, SGPRFirst = !SGPRFirst) {
218 if (SGPRFirst) {
219 auto SW = getSGPRTuplesWeight();
220 auto OtherSW = O.getSGPRTuplesWeight();
221 if (SW != OtherSW)
222 return SW < OtherSW;
223 } else {
224 auto VW = getVGPRTuplesWeight();
225 auto OtherVW = O.getVGPRTuplesWeight();
226 if (VW != OtherVW)
227 return VW < OtherVW;
228 }
229 }
230
231 // Give final precedence to lower general RP.
232 return SGPRImportant ? (getSGPRNum() < O.getSGPRNum()):
233 (getVGPRNum(ST.hasGFX90AInsts()) <
234 O.getVGPRNum(ST.hasGFX90AInsts()));
235}
236
238 unsigned DynamicVGPRBlockSize) {
239 return Printable([&RP, ST, DynamicVGPRBlockSize](raw_ostream &OS) {
240 OS << "VGPRs: " << RP.getArchVGPRNum() << ' '
241 << "AGPRs: " << RP.getAGPRNum();
242 if (ST)
243 OS << "(O"
244 << ST->getOccupancyWithNumVGPRs(RP.getVGPRNum(ST->hasGFX90AInsts()),
245 DynamicVGPRBlockSize)
246 << ')';
247 OS << ", SGPRs: " << RP.getSGPRNum();
248 if (ST)
249 OS << "(O" << ST->getOccupancyWithNumSGPRs(RP.getSGPRNum()) << ')';
250 OS << ", LVGPR WT: " << RP.getVGPRTuplesWeight()
251 << ", LSGPR WT: " << RP.getSGPRTuplesWeight();
252 if (ST)
253 OS << " -> Occ: " << RP.getOccupancy(*ST, DynamicVGPRBlockSize);
254 OS << '\n';
255 });
256}
257
259 const MachineRegisterInfo &MRI) {
260 assert(MO.isDef() && MO.isReg() && MO.getReg().isVirtual());
261
262 // We don't rely on read-undef flag because in case of tentative schedule
263 // tracking it isn't set correctly yet. This works correctly however since
264 // use mask has been tracked before using LIS.
265 return MO.getSubReg() == 0 ?
266 MRI.getMaxLaneMaskForVReg(MO.getReg()) :
267 MRI.getTargetRegisterInfo()->getSubRegIndexLaneMask(MO.getSubReg());
268}
269
270static void
272 const MachineInstr &MI, const LiveIntervals &LIS,
274
275 auto &TRI = *MRI.getTargetRegisterInfo();
276 for (const auto &MO : MI.operands()) {
277 if (!MO.isReg() || !MO.getReg().isVirtual())
278 continue;
279 if (!MO.isUse() || !MO.readsReg())
280 continue;
281
282 Register Reg = MO.getReg();
283 auto I = llvm::find_if(VRegMaskOrUnits, [Reg](const VRegMaskOrUnit &RM) {
284 return RM.RegUnit == Reg;
285 });
286
287 auto &P = I == VRegMaskOrUnits.end()
288 ? VRegMaskOrUnits.emplace_back(Reg, LaneBitmask::getNone())
289 : *I;
290
291 P.LaneMask |= MO.getSubReg() ? TRI.getSubRegIndexLaneMask(MO.getSubReg())
292 : MRI.getMaxLaneMaskForVReg(Reg);
293 }
294
295 SlotIndex InstrSI;
296 for (auto &P : VRegMaskOrUnits) {
297 auto &LI = LIS.getInterval(P.RegUnit);
298 if (!LI.hasSubRanges())
299 continue;
300
301 // For a tentative schedule LIS isn't updated yet but livemask should
302 // remain the same on any schedule. Subreg defs can be reordered but they
303 // all must dominate uses anyway.
304 if (!InstrSI)
305 InstrSI = LIS.getInstructionIndex(MI).getBaseIndex();
306
307 P.LaneMask = getLiveLaneMask(LI, InstrSI, MRI, P.LaneMask);
308 }
309}
310
311/// Mostly copy/paste from CodeGen/RegisterPressure.cpp
313 const LiveIntervals &LIS, const MachineRegisterInfo &MRI,
314 bool TrackLaneMasks, Register RegUnit, SlotIndex Pos,
315 LaneBitmask SafeDefault,
316 function_ref<bool(const LiveRange &LR, SlotIndex Pos)> Property) {
317 if (RegUnit.isVirtual()) {
318 const LiveInterval &LI = LIS.getInterval(RegUnit);
319 LaneBitmask Result;
320 if (TrackLaneMasks && LI.hasSubRanges()) {
321 for (const LiveInterval::SubRange &SR : LI.subranges()) {
322 if (Property(SR, Pos))
323 Result |= SR.LaneMask;
324 }
325 } else if (Property(LI, Pos)) {
326 Result = TrackLaneMasks ? MRI.getMaxLaneMaskForVReg(RegUnit)
328 }
329
330 return Result;
331 }
332
333 const LiveRange *LR = LIS.getCachedRegUnit(RegUnit);
334 if (LR == nullptr)
335 return SafeDefault;
336 return Property(*LR, Pos) ? LaneBitmask::getAll() : LaneBitmask::getNone();
337}
338
339/// Mostly copy/paste from CodeGen/RegisterPressure.cpp
340/// Helper to find a vreg use between two indices {PriorUseIdx, NextUseIdx}.
341/// The query starts with a lane bitmask which gets lanes/bits removed for every
342/// use we find.
343static LaneBitmask findUseBetween(unsigned Reg, LaneBitmask LastUseMask,
344 SlotIndex PriorUseIdx, SlotIndex NextUseIdx,
346 const SIRegisterInfo *TRI,
347 const LiveIntervals *LIS,
348 bool Upward = false) {
349 for (const MachineOperand &MO : MRI.use_nodbg_operands(Reg)) {
350 if (MO.isUndef())
351 continue;
352 const MachineInstr *MI = MO.getParent();
353 SlotIndex InstSlot = LIS->getInstructionIndex(*MI).getRegSlot();
354 bool InRange = Upward ? (InstSlot > PriorUseIdx && InstSlot <= NextUseIdx)
355 : (InstSlot >= PriorUseIdx && InstSlot < NextUseIdx);
356 if (!InRange)
357 continue;
358
359 unsigned SubRegIdx = MO.getSubReg();
360 LaneBitmask UseMask = TRI->getSubRegIndexLaneMask(SubRegIdx);
361 LastUseMask &= ~UseMask;
362 if (LastUseMask.none())
363 return LaneBitmask::getNone();
364 }
365 return LastUseMask;
366}
367
368////////////////////////////////////////////////////////////////////////////////
369// GCNRPTarget
370
372 : GCNRPTarget(RP, MF) {
373 const Function &F = MF.getFunction();
374 const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
375 setTarget(ST.getMaxNumSGPRs(F), ST.getMaxNumVGPRs(F));
376}
377
378GCNRPTarget::GCNRPTarget(unsigned NumSGPRs, unsigned NumVGPRs,
379 const MachineFunction &MF, const GCNRegPressure &RP)
380 : GCNRPTarget(RP, MF) {
381 setTarget(NumSGPRs, NumVGPRs);
382}
383
384GCNRPTarget::GCNRPTarget(unsigned Occupancy, const MachineFunction &MF,
385 const GCNRegPressure &RP)
386 : GCNRPTarget(RP, MF) {
387 const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
388 unsigned DynamicVGPRBlockSize =
389 MF.getInfo<SIMachineFunctionInfo>()->getDynamicVGPRBlockSize();
390 setTarget(ST.getMaxNumSGPRs(Occupancy, /*Addressable=*/false),
391 ST.getMaxNumVGPRs(Occupancy, DynamicVGPRBlockSize));
392}
393
394void GCNRPTarget::setTarget(unsigned NumSGPRs, unsigned NumVGPRs) {
395 const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
396 MaxSGPRs = std::min(ST.getAddressableNumSGPRs(), NumSGPRs);
397 MaxVGPRs = std::min(ST.getAddressableNumArchVGPRs(), NumVGPRs);
398 if (UnifiedRF) {
399 unsigned DynamicVGPRBlockSize =
400 MF.getInfo<SIMachineFunctionInfo>()->getDynamicVGPRBlockSize();
401 MaxUnifiedVGPRs =
402 std::min(ST.getAddressableNumVGPRs(DynamicVGPRBlockSize), NumVGPRs);
403 } else {
404 MaxUnifiedVGPRs = 0;
405 }
406}
407
409 const MachineRegisterInfo &MRI = MF.getRegInfo();
410 const TargetRegisterClass *RC = MRI.getRegClass(Reg);
411 const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo();
412 const SIRegisterInfo *SRI = static_cast<const SIRegisterInfo *>(TRI);
413
414 if (SRI->isSGPRClass(RC))
415 return RP.getSGPRNum() > MaxSGPRs;
416 unsigned NumVGPRs =
417 SRI->isAGPRClass(RC) ? RP.getAGPRNum() : RP.getArchVGPRNum();
418 // The addressable limit must always be respected.
419 if (NumVGPRs > MaxVGPRs)
420 return true;
421 // For unified RFs, combined VGPR usage limit must be respected as well.
422 return UnifiedRF && RP.getVGPRNum(true) > MaxUnifiedVGPRs;
423}
424
426 if (RP.getSGPRNum() > MaxSGPRs || RP.getVGPRNum(false) > MaxVGPRs)
427 return false;
428 if (UnifiedRF && RP.getVGPRNum(true) > MaxUnifiedVGPRs)
429 return false;
430 return true;
431}
432
433///////////////////////////////////////////////////////////////////////////////
434// GCNRPTracker
435
437 const LiveIntervals &LIS,
439 LaneBitmask LaneMaskFilter) {
440 return getLiveLaneMask(LIS.getInterval(Reg), SI, MRI, LaneMaskFilter);
441}
442
445 LaneBitmask LaneMaskFilter) {
446 LaneBitmask LiveMask;
447 if (LI.hasSubRanges()) {
448 for (const auto &S : LI.subranges())
449 if ((S.LaneMask & LaneMaskFilter).any() && S.liveAt(SI)) {
450 LiveMask |= S.LaneMask;
451 assert(LiveMask == (LiveMask & MRI.getMaxLaneMaskForVReg(LI.reg())));
452 }
453 } else if (LI.liveAt(SI)) {
454 LiveMask = MRI.getMaxLaneMaskForVReg(LI.reg());
455 }
456 LiveMask &= LaneMaskFilter;
457 return LiveMask;
458}
459
461 const LiveIntervals &LIS,
462 const MachineRegisterInfo &MRI) {
464 for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
465 auto Reg = Register::index2VirtReg(I);
466 if (!LIS.hasInterval(Reg))
467 continue;
468 auto LiveMask = getLiveLaneMask(Reg, SI, LIS, MRI);
469 if (LiveMask.any())
470 LiveRegs[Reg] = LiveMask;
471 }
472 return LiveRegs;
473}
474
476 const LiveRegSet *LiveRegsCopy,
477 bool After) {
478 const MachineFunction &MF = *MI.getMF();
479 MRI = &MF.getRegInfo();
480 if (LiveRegsCopy) {
481 if (&LiveRegs != LiveRegsCopy)
482 LiveRegs = *LiveRegsCopy;
483 } else {
484 LiveRegs = After ? getLiveRegsAfter(MI, LIS)
486 }
487
489}
490
492 const LiveRegSet &LiveRegs_) {
493 MRI = &MRI_;
494 LiveRegs = LiveRegs_;
495 LastTrackedMI = nullptr;
496 MaxPressure = CurPressure = getRegPressure(MRI_, LiveRegs_);
497}
498
499/// Mostly copy/paste from CodeGen/RegisterPressure.cpp
501 SlotIndex Pos) const {
503 LIS, *MRI, true, RegUnit, Pos.getBaseIndex(), LaneBitmask::getNone(),
504 [](const LiveRange &LR, SlotIndex Pos) {
505 const LiveRange::Segment *S = LR.getSegmentContaining(Pos);
506 return S != nullptr && S->end == Pos.getRegSlot();
507 });
508}
509
510////////////////////////////////////////////////////////////////////////////////
511// GCNUpwardRPTracker
512
514 assert(MRI && "call reset first");
515
516 LastTrackedMI = &MI;
517
518 if (MI.isDebugInstr())
519 return;
520
521 // Kill all defs.
522 GCNRegPressure DefPressure, ECDefPressure;
523 bool HasECDefs = false;
524 for (const MachineOperand &MO : MI.all_defs()) {
525 if (!MO.getReg().isVirtual())
526 continue;
527
528 Register Reg = MO.getReg();
529 LaneBitmask DefMask = getDefRegMask(MO, *MRI);
530
531 // Treat a def as fully live at the moment of definition: keep a record.
532 if (MO.isEarlyClobber()) {
533 ECDefPressure.inc(Reg, LaneBitmask::getNone(), DefMask, *MRI);
534 HasECDefs = true;
535 } else
536 DefPressure.inc(Reg, LaneBitmask::getNone(), DefMask, *MRI);
537
538 auto I = LiveRegs.find(Reg);
539 if (I == LiveRegs.end())
540 continue;
541
542 LaneBitmask &LiveMask = I->second;
543 LaneBitmask PrevMask = LiveMask;
544 LiveMask &= ~DefMask;
545 CurPressure.inc(Reg, PrevMask, LiveMask, *MRI);
546 if (LiveMask.none())
547 LiveRegs.erase(I);
548 }
549
550 // Update MaxPressure with defs pressure.
551 DefPressure += CurPressure;
552 if (HasECDefs)
553 DefPressure += ECDefPressure;
554 MaxPressure = max(DefPressure, MaxPressure);
555
556 // Make uses alive.
558 collectVirtualRegUses(RegUses, MI, LIS, *MRI);
559 for (const VRegMaskOrUnit &U : RegUses) {
560 LaneBitmask &LiveMask = LiveRegs[U.RegUnit];
561 LaneBitmask PrevMask = LiveMask;
562 LiveMask |= U.LaneMask;
563 CurPressure.inc(U.RegUnit, PrevMask, LiveMask, *MRI);
564 }
565
566 // Update MaxPressure with uses plus early-clobber defs pressure.
567 MaxPressure = HasECDefs ? max(CurPressure + ECDefPressure, MaxPressure)
569
570 assert(CurPressure == getRegPressure(*MRI, LiveRegs));
571}
572
573////////////////////////////////////////////////////////////////////////////////
574// GCNDownwardRPTracker
575
577 const LiveRegSet *LiveRegsCopy) {
578 MRI = &MI.getParent()->getParent()->getRegInfo();
579 LastTrackedMI = nullptr;
580 MBBEnd = MI.getParent()->end();
581 NextMI = &MI;
582 NextMI = skipDebugInstructionsForward(NextMI, MBBEnd);
583 if (NextMI == MBBEnd)
584 return false;
585 GCNRPTracker::reset(*NextMI, LiveRegsCopy, false);
586 return true;
587}
588
590 bool UseInternalIterator) {
591 assert(MRI && "call reset first");
592 SlotIndex SI;
593 const MachineInstr *CurrMI;
594 if (UseInternalIterator) {
595 if (!LastTrackedMI)
596 return NextMI == MBBEnd;
597
598 assert(NextMI == MBBEnd || !NextMI->isDebugInstr());
599 CurrMI = LastTrackedMI;
600
601 SI = NextMI == MBBEnd
602 ? LIS.getInstructionIndex(*LastTrackedMI).getDeadSlot()
604 } else { //! UseInternalIterator
606 CurrMI = MI;
607 }
608
609 assert(SI.isValid());
610
611 // Remove dead registers or mask bits.
612 SmallSet<Register, 8> SeenRegs;
613 for (auto &MO : CurrMI->operands()) {
614 if (!MO.isReg() || !MO.getReg().isVirtual())
615 continue;
616 if (MO.isUse() && !MO.readsReg())
617 continue;
618 if (!UseInternalIterator && MO.isDef())
619 continue;
620 if (!SeenRegs.insert(MO.getReg()).second)
621 continue;
622 const LiveInterval &LI = LIS.getInterval(MO.getReg());
623 if (LI.hasSubRanges()) {
624 auto It = LiveRegs.end();
625 for (const auto &S : LI.subranges()) {
626 if (!S.liveAt(SI)) {
627 if (It == LiveRegs.end()) {
628 It = LiveRegs.find(MO.getReg());
629 if (It == LiveRegs.end())
630 llvm_unreachable("register isn't live");
631 }
632 auto PrevMask = It->second;
633 It->second &= ~S.LaneMask;
634 CurPressure.inc(MO.getReg(), PrevMask, It->second, *MRI);
635 }
636 }
637 if (It != LiveRegs.end() && It->second.none())
638 LiveRegs.erase(It);
639 } else if (!LI.liveAt(SI)) {
640 auto It = LiveRegs.find(MO.getReg());
641 if (It == LiveRegs.end())
642 llvm_unreachable("register isn't live");
643 CurPressure.inc(MO.getReg(), It->second, LaneBitmask::getNone(), *MRI);
644 LiveRegs.erase(It);
645 }
646 }
647
649
650 LastTrackedMI = nullptr;
651
652 return UseInternalIterator && (NextMI == MBBEnd);
653}
654
656 bool UseInternalIterator) {
657 if (UseInternalIterator) {
658 LastTrackedMI = &*NextMI++;
659 NextMI = skipDebugInstructionsForward(NextMI, MBBEnd);
660 } else {
662 }
663
664 const MachineInstr *CurrMI = LastTrackedMI;
665
666 // Add new registers or mask bits.
667 for (const auto &MO : CurrMI->all_defs()) {
668 Register Reg = MO.getReg();
669 if (!Reg.isVirtual())
670 continue;
671 auto &LiveMask = LiveRegs[Reg];
672 auto PrevMask = LiveMask;
673 LiveMask |= getDefRegMask(MO, *MRI);
674 CurPressure.inc(Reg, PrevMask, LiveMask, *MRI);
675 }
676
678}
679
680bool GCNDownwardRPTracker::advance(MachineInstr *MI, bool UseInternalIterator) {
681 if (UseInternalIterator && NextMI == MBBEnd)
682 return false;
683
684 advanceBeforeNext(MI, UseInternalIterator);
685 advanceToNext(MI, UseInternalIterator);
686 if (!UseInternalIterator) {
687 // We must remove any dead def lanes from the current RP
688 advanceBeforeNext(MI, true);
689 }
690 return true;
691}
692
694 while (NextMI != End)
695 if (!advance()) return false;
696 return true;
697}
698
701 const LiveRegSet *LiveRegsCopy) {
702 reset(*Begin, LiveRegsCopy);
703 return advance(End);
704}
705
707 const GCNRPTracker::LiveRegSet &TrackedLR,
708 const TargetRegisterInfo *TRI, StringRef Pfx) {
709 return Printable([&LISLR, &TrackedLR, TRI, Pfx](raw_ostream &OS) {
710 for (auto const &P : TrackedLR) {
711 auto I = LISLR.find(P.first);
712 if (I == LISLR.end()) {
713 OS << Pfx << printReg(P.first, TRI) << ":L" << PrintLaneMask(P.second)
714 << " isn't found in LIS reported set\n";
715 } else if (I->second != P.second) {
716 OS << Pfx << printReg(P.first, TRI)
717 << " masks doesn't match: LIS reported " << PrintLaneMask(I->second)
718 << ", tracked " << PrintLaneMask(P.second) << '\n';
719 }
720 }
721 for (auto const &P : LISLR) {
722 auto I = TrackedLR.find(P.first);
723 if (I == TrackedLR.end()) {
724 OS << Pfx << printReg(P.first, TRI) << ":L" << PrintLaneMask(P.second)
725 << " isn't found in tracked set\n";
726 }
727 }
728 });
729}
730
733 const SIRegisterInfo *TRI) const {
734 assert(!MI->isDebugOrPseudoInstr() && "Expect a nondebug instruction.");
735
736 SlotIndex SlotIdx;
737 SlotIdx = LIS.getInstructionIndex(*MI).getRegSlot();
738
739 // Account for register pressure similar to RegPressureTracker::recede().
740 RegisterOperands RegOpers;
741 RegOpers.collect(*MI, *TRI, *MRI, true, /*IgnoreDead=*/false);
742 RegOpers.adjustLaneLiveness(LIS, *MRI, SlotIdx);
743 GCNRegPressure TempPressure = CurPressure;
744
745 for (const VRegMaskOrUnit &Use : RegOpers.Uses) {
746 Register Reg = Use.RegUnit;
747 if (!Reg.isVirtual())
748 continue;
749 LaneBitmask LastUseMask = getLastUsedLanes(Reg, SlotIdx);
750 if (LastUseMask.none())
751 continue;
752 // The LastUseMask is queried from the liveness information of instruction
753 // which may be further down the schedule. Some lanes may actually not be
754 // last uses for the current position.
755 // FIXME: allow the caller to pass in the list of vreg uses that remain
756 // to be bottom-scheduled to avoid searching uses at each query.
757 SlotIndex CurrIdx;
758 const MachineBasicBlock *MBB = MI->getParent();
761 if (IdxPos == MBB->end()) {
762 CurrIdx = LIS.getMBBEndIdx(MBB);
763 } else {
764 CurrIdx = LIS.getInstructionIndex(*IdxPos).getRegSlot();
765 }
766
767 LastUseMask =
768 findUseBetween(Reg, LastUseMask, CurrIdx, SlotIdx, *MRI, TRI, &LIS);
769 if (LastUseMask.none())
770 continue;
771
772 auto It = LiveRegs.find(Reg);
773 LaneBitmask LiveMask = It != LiveRegs.end() ? It->second : LaneBitmask(0);
774 LaneBitmask NewMask = LiveMask & ~LastUseMask;
775 TempPressure.inc(Reg, LiveMask, NewMask, *MRI);
776 }
777
778 // Generate liveness for defs.
779 for (const VRegMaskOrUnit &Def : RegOpers.Defs) {
780 Register Reg = Def.RegUnit;
781 if (!Reg.isVirtual())
782 continue;
783 auto It = LiveRegs.find(Reg);
784 LaneBitmask LiveMask = It != LiveRegs.end() ? It->second : LaneBitmask(0);
785 LaneBitmask NewMask = LiveMask | Def.LaneMask;
786 TempPressure.inc(Reg, LiveMask, NewMask, *MRI);
787 }
788
789 return TempPressure;
790}
791
793 const auto &SI = LIS.getInstructionIndex(*LastTrackedMI).getBaseIndex();
794 const auto LISLR = llvm::getLiveRegs(SI, LIS, *MRI);
795 const auto &TrackedLR = LiveRegs;
796
797 if (!isEqual(LISLR, TrackedLR)) {
798 dbgs() << "\nGCNUpwardRPTracker error: Tracked and"
799 " LIS reported livesets mismatch:\n"
800 << print(LISLR, *MRI);
801 reportMismatch(LISLR, TrackedLR, MRI->getTargetRegisterInfo());
802 return false;
803 }
804
805 auto LISPressure = getRegPressure(*MRI, LISLR);
806 if (LISPressure != CurPressure) {
807 dbgs() << "GCNUpwardRPTracker error: Pressure sets different\nTracked: "
808 << print(CurPressure) << "LIS rpt: " << print(LISPressure);
809 return false;
810 }
811 return true;
812}
813
815 const MachineRegisterInfo &MRI) {
816 return Printable([&LiveRegs, &MRI](raw_ostream &OS) {
817 const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo();
818 for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
819 Register Reg = Register::index2VirtReg(I);
820 auto It = LiveRegs.find(Reg);
821 if (It != LiveRegs.end() && It->second.any())
822 OS << ' ' << printVRegOrUnit(Reg, TRI) << ':'
823 << PrintLaneMask(It->second);
824 }
825 OS << '\n';
826 });
827}
828
829void GCNRegPressure::dump() const { dbgs() << print(*this); }
830
832 "amdgpu-print-rp-downward",
833 cl::desc("Use GCNDownwardRPTracker for GCNRegPressurePrinter pass"),
834 cl::init(false), cl::Hidden);
835
838
839INITIALIZE_PASS(GCNRegPressurePrinter, "amdgpu-print-rp", "", true, true)
840
841// Return lanemask of Reg's subregs that are live-through at [Begin, End] and
842// are fully covered by Mask.
843static LaneBitmask
845 Register Reg, SlotIndex Begin, SlotIndex End,
846 LaneBitmask Mask = LaneBitmask::getAll()) {
847
848 auto IsInOneSegment = [Begin, End](const LiveRange &LR) -> bool {
849 auto *Segment = LR.getSegmentContaining(Begin);
850 return Segment && Segment->contains(End);
851 };
852
853 LaneBitmask LiveThroughMask;
854 const LiveInterval &LI = LIS.getInterval(Reg);
855 if (LI.hasSubRanges()) {
856 for (auto &SR : LI.subranges()) {
857 if ((SR.LaneMask & Mask) == SR.LaneMask && IsInOneSegment(SR))
858 LiveThroughMask |= SR.LaneMask;
859 }
860 } else {
861 LaneBitmask RegMask = MRI.getMaxLaneMaskForVReg(Reg);
862 if ((RegMask & Mask) == RegMask && IsInOneSegment(LI))
863 LiveThroughMask = RegMask;
864 }
865
866 return LiveThroughMask;
867}
868
870 const MachineRegisterInfo &MRI = MF.getRegInfo();
871 const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo();
872 const LiveIntervals &LIS = getAnalysis<LiveIntervalsWrapperPass>().getLIS();
873
874 auto &OS = dbgs();
875
876// Leading spaces are important for YAML syntax.
877#define PFX " "
878
879 OS << "---\nname: " << MF.getName() << "\nbody: |\n";
880
881 auto printRP = [](const GCNRegPressure &RP) {
882 return Printable([&RP](raw_ostream &OS) {
883 OS << format(PFX " %-5d", RP.getSGPRNum())
884 << format(" %-5d", RP.getVGPRNum(false));
885 });
886 };
887
888 auto ReportLISMismatchIfAny = [&](const GCNRPTracker::LiveRegSet &TrackedLR,
889 const GCNRPTracker::LiveRegSet &LISLR) {
890 if (LISLR != TrackedLR) {
891 OS << PFX " mis LIS: " << llvm::print(LISLR, MRI)
892 << reportMismatch(LISLR, TrackedLR, TRI, PFX " ");
893 }
894 };
895
896 // Register pressure before and at an instruction (in program order).
898
899 for (auto &MBB : MF) {
900 RP.clear();
901 RP.reserve(MBB.size());
902
903 OS << PFX;
905 OS << ":\n";
906
907 SlotIndex MBBStartSlot = LIS.getSlotIndexes()->getMBBStartIdx(&MBB);
908 SlotIndex MBBEndSlot = LIS.getSlotIndexes()->getMBBEndIdx(&MBB);
909
910 GCNRPTracker::LiveRegSet LiveIn, LiveOut;
911 GCNRegPressure RPAtMBBEnd;
912
913 if (UseDownwardTracker) {
914 if (MBB.empty()) {
915 LiveIn = LiveOut = getLiveRegs(MBBStartSlot, LIS, MRI);
916 RPAtMBBEnd = getRegPressure(MRI, LiveIn);
917 } else {
918 GCNDownwardRPTracker RPT(LIS);
919 RPT.reset(MBB.front());
920
921 LiveIn = RPT.getLiveRegs();
922
923 while (!RPT.advanceBeforeNext()) {
924 GCNRegPressure RPBeforeMI = RPT.getPressure();
925 RPT.advanceToNext();
926 RP.emplace_back(RPBeforeMI, RPT.getPressure());
927 }
928
929 LiveOut = RPT.getLiveRegs();
930 RPAtMBBEnd = RPT.getPressure();
931 }
932 } else {
933 GCNUpwardRPTracker RPT(LIS);
934 RPT.reset(MRI, MBBEndSlot);
935
936 LiveOut = RPT.getLiveRegs();
937 RPAtMBBEnd = RPT.getPressure();
938
939 for (auto &MI : reverse(MBB)) {
940 RPT.resetMaxPressure();
941 RPT.recede(MI);
942 if (!MI.isDebugInstr())
943 RP.emplace_back(RPT.getPressure(), RPT.getMaxPressure());
944 }
945
946 LiveIn = RPT.getLiveRegs();
947 }
948
949 OS << PFX " Live-in: " << llvm::print(LiveIn, MRI);
951 ReportLISMismatchIfAny(LiveIn, getLiveRegs(MBBStartSlot, LIS, MRI));
952
953 OS << PFX " SGPR VGPR\n";
954 int I = 0;
955 for (auto &MI : MBB) {
956 if (!MI.isDebugInstr()) {
957 auto &[RPBeforeInstr, RPAtInstr] =
958 RP[UseDownwardTracker ? I : (RP.size() - 1 - I)];
959 ++I;
960 OS << printRP(RPBeforeInstr) << '\n' << printRP(RPAtInstr) << " ";
961 } else
962 OS << PFX " ";
963 MI.print(OS);
964 }
965 OS << printRP(RPAtMBBEnd) << '\n';
966
967 OS << PFX " Live-out:" << llvm::print(LiveOut, MRI);
969 ReportLISMismatchIfAny(LiveOut, getLiveRegs(MBBEndSlot, LIS, MRI));
970
971 GCNRPTracker::LiveRegSet LiveThrough;
972 for (auto [Reg, Mask] : LiveIn) {
973 LaneBitmask MaskIntersection = Mask & LiveOut.lookup(Reg);
974 if (MaskIntersection.any()) {
976 MRI, LIS, Reg, MBBStartSlot, MBBEndSlot, MaskIntersection);
977 if (LTMask.any())
978 LiveThrough[Reg] = LTMask;
979 }
980 }
981 OS << PFX " Live-thr:" << llvm::print(LiveThrough, MRI);
982 OS << printRP(getRegPressure(MRI, LiveThrough)) << '\n';
983 }
984 OS << "...\n";
985 return false;
986
987#undef PFX
988}
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
aarch64 promote const
constexpr LLT S1
MachineBasicBlock & MBB
bool End
Definition: ELF_riscv.cpp:480
static void collectVirtualRegUses(SmallVectorImpl< VRegMaskOrUnit > &VRegMaskOrUnits, const MachineInstr &MI, const LiveIntervals &LIS, const MachineRegisterInfo &MRI)
#define PFX
static cl::opt< bool > UseDownwardTracker("amdgpu-print-rp-downward", cl::desc("Use GCNDownwardRPTracker for GCNRegPressurePrinter pass"), cl::init(false), cl::Hidden)
static LaneBitmask getDefRegMask(const MachineOperand &MO, const MachineRegisterInfo &MRI)
static LaneBitmask getRegLiveThroughMask(const MachineRegisterInfo &MRI, const LiveIntervals &LIS, Register Reg, SlotIndex Begin, SlotIndex End, LaneBitmask Mask=LaneBitmask::getAll())
This file defines the GCNRegPressure class, which tracks registry pressure by bookkeeping number of S...
IRTranslator LLVM IR MI
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
Register const TargetRegisterInfo * TRI
static bool InRange(int64_t Value, unsigned short Shift, int LBound, int HBound)
#define P(N)
if(PassOpts->AAPipeline)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:56
static LaneBitmask findUseBetween(unsigned Reg, LaneBitmask LastUseMask, SlotIndex PriorUseIdx, SlotIndex NextUseIdx, const MachineRegisterInfo &MRI, const LiveIntervals *LIS)
Helper to find a vreg use between two indices [PriorUseIdx, NextUseIdx).
static LaneBitmask getLanesWithProperty(const LiveIntervals &LIS, const MachineRegisterInfo &MRI, bool TrackLaneMasks, Register RegUnit, SlotIndex Pos, LaneBitmask SafeDefault, bool(*Property)(const LiveRange &LR, SlotIndex Pos))
raw_pwrite_stream & OS
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
Definition: DenseMap.h:203
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:177
unsigned size() const
Definition: DenseMap.h:120
iterator end()
Definition: DenseMap.h:87
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 ...
bool reset(const MachineInstr &MI, const LiveRegSet *LiveRegs=nullptr)
Reset tracker to the point before the MI filling LiveRegs upon this point using LIS.
void advanceToNext(MachineInstr *MI=nullptr, bool UseInternalIterator=true)
Move to the state at the MI, advanceBeforeNext has to be called first.
Models a register pressure target, allowing to evaluate and track register savings against that targe...
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 ...
bool isSaveBeneficial(Register Reg) const
Determines whether saving virtual register Reg will be beneficial towards achieving the RP target.
bool satisfied() const
Whether the current RP is at or below the defined pressure target.
void setTarget(unsigned NumSGPRs, unsigned NumVGPRs)
Changes the target (same semantics as constructor).
GCNRegPressure getPressure() const
const decltype(LiveRegs) & getLiveRegs() const
const MachineInstr * LastTrackedMI
GCNRegPressure CurPressure
GCNRegPressure MaxPressure
void reset(const MachineInstr &MI, const LiveRegSet *LiveRegsCopy, bool After)
LaneBitmask getLastUsedLanes(Register RegUnit, SlotIndex Pos) const
Mostly copy/paste from CodeGen/RegisterPressure.cpp.
const MachineRegisterInfo * MRI
const LiveIntervals & LIS
void reset(const MachineRegisterInfo &MRI, SlotIndex SI)
reset tracker at the specified slot index SI.
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.
A live range for subregisters.
Definition: LiveInterval.h:697
LiveInterval - This class represents the liveness of a register, or stack slot.
Definition: LiveInterval.h:690
Register reg() const
Definition: LiveInterval.h:721
bool hasSubRanges() const
Returns true if subregister liveness information is available.
Definition: LiveInterval.h:813
iterator_range< subrange_iterator > subranges()
Definition: LiveInterval.h:785
bool hasInterval(Register Reg) const
SlotIndexes * getSlotIndexes() const
SlotIndex getInstructionIndex(const MachineInstr &Instr) const
Returns the base index of the given instruction.
SlotIndex getMBBEndIdx(const MachineBasicBlock *mbb) const
Return the last index in the given basic block.
LiveRange * getCachedRegUnit(unsigned Unit)
Return the live range for register unit Unit if it has already been computed, or nullptr if it hasn't...
LiveInterval & getInterval(Register Reg)
This class represents the liveness of a register, stack slot, etc.
Definition: LiveInterval.h:158
bool liveAt(SlotIndex index) const
Definition: LiveInterval.h:403
iterator end()
Definition: LiveInterval.h:217
LLVM_ABI void printName(raw_ostream &os, unsigned printNameFlags=PrintNameIr, ModuleSlotTracker *moduleSlotTracker=nullptr) const
Print the basic block's name as:
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Representation of each machine instruction.
Definition: MachineInstr.h:72
filtered_mop_range all_defs()
Returns an iterator range over all operands that are (explicit or implicit) register defs.
Definition: MachineInstr.h:754
mop_range operands()
Definition: MachineInstr.h:693
MachineOperand class - Representation of each machine instruction operand.
unsigned getSubReg() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
const TargetRegisterInfo * getTargetRegisterInfo() const
virtual void print(raw_ostream &OS, const Module *M) const
print - Print out the internal state of the pass.
Definition: Pass.cpp:140
Simple wrapper around std::function<void(raw_ostream&)>.
Definition: Printable.h:38
List of registers defined and used by a machine instruction.
SmallVector< VRegMaskOrUnit, 8 > Defs
List of virtual registers and register units defined by the instruction which are not dead.
LLVM_ABI void collect(const MachineInstr &MI, const TargetRegisterInfo &TRI, const MachineRegisterInfo &MRI, bool TrackLaneMasks, bool IgnoreDead)
Analyze the given instruction MI and fill in the Uses, Defs and DeadDefs list based on the MachineOpe...
LLVM_ABI void adjustLaneLiveness(const LiveIntervals &LIS, const MachineRegisterInfo &MRI, SlotIndex Pos, MachineInstr *AddFlagsMI=nullptr)
Use liveness information to find out which uses/defs are partially undefined/dead and adjust the VReg...
SmallVector< VRegMaskOrUnit, 8 > Uses
List of virtual registers and register units read by the instruction.
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:67
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Definition: Register.h:74
This class keeps track of the SPI_SP_INPUT_ADDR config register, which tells the hardware which inter...
static unsigned getNumCoveredRegs(LaneBitmask LM)
bool isVectorSuperClass(const TargetRegisterClass *RC) const
static bool isSGPRClass(const TargetRegisterClass *RC)
static bool isAGPRClass(const TargetRegisterClass *RC)
SlotIndex - An opaque wrapper around machine indexes.
Definition: SlotIndexes.h:66
SlotIndex getDeadSlot() const
Returns the dead def kill slot for the current instruction.
Definition: SlotIndexes.h:243
SlotIndex getBaseIndex() const
Returns the base index for associated with this index.
Definition: SlotIndexes.h:225
SlotIndex getRegSlot(bool EC=false) const
Returns the register use/def slot in the current instruction for a normal or early-clobber def.
Definition: SlotIndexes.h:238
SlotIndex getMBBEndIdx(unsigned Num) const
Returns the last index in the given basic block number.
Definition: SlotIndexes.h:471
SlotIndex getMBBStartIdx(unsigned Num) const
Returns the first index in the given basic block number.
Definition: SlotIndexes.h:461
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition: SmallSet.h:134
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:182
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:574
reference emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:938
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
A Use represents the edge between a Value definition and its users.
Definition: Use.h:35
LLVM Value Representation.
Definition: Value.h:75
An efficient, type-erasing, non-owning reference to a callable.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:444
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
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)
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)
auto reverse(ContainerTy &&C)
Definition: STLExtras.h:428
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:207
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition: Format.h:126
char & GCNRegPressurePrinterID
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:1777
GCNRPTracker::LiveRegSet getLiveRegsBefore(const MachineInstr &MI, const LiveIntervals &LIS)
Printable reportMismatch(const GCNRPTracker::LiveRegSet &LISLR, const GCNRPTracker::LiveRegSet &TrackedL, const TargetRegisterInfo *TRI, StringRef Pfx=" ")
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:858
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
friend Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST, unsigned DynamicVGPRBlockSize)
unsigned getVGPRTuplesWeight() const
unsigned getVGPRNum(bool UnifiedVGPRFile) 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 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
constexpr bool none() const
Definition: LaneBitmask.h:52
constexpr bool any() const
Definition: LaneBitmask.h:53
static constexpr LaneBitmask getNone()
Definition: LaneBitmask.h:81