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"
19
20using namespace llvm;
21
22#define DEBUG_TYPE "machine-scheduler"
23
25 const GCNRPTracker::LiveRegSet &S2) {
26 if (S1.size() != S2.size())
27 return false;
28
29 for (const auto &P : S1) {
30 auto I = S2.find(P.first);
31 if (I == S2.end() || I->second != P.second)
32 return false;
33 }
34 return true;
35}
36
37///////////////////////////////////////////////////////////////////////////////
38// GCNRegPressure
39
41 const SIRegisterInfo *STI) {
42 return STI->isSGPRClass(RC)
43 ? SGPR
44 : (STI->isAGPRClass(RC)
45 ? AGPR
46 : (STI->isVectorSuperClass(RC) ? AVGPR : VGPR));
47}
48
49void GCNRegPressure::inc(unsigned Reg,
50 LaneBitmask PrevMask,
51 LaneBitmask NewMask,
52 const MachineRegisterInfo &MRI) {
53 unsigned NewNumCoveredRegs = SIRegisterInfo::getNumCoveredRegs(NewMask);
54 unsigned PrevNumCoveredRegs = SIRegisterInfo::getNumCoveredRegs(PrevMask);
55 if (NewNumCoveredRegs == PrevNumCoveredRegs)
56 return;
57
58 int Sign = 1;
59 if (NewMask < PrevMask) {
60 std::swap(NewMask, PrevMask);
61 std::swap(NewNumCoveredRegs, PrevNumCoveredRegs);
62 Sign = -1;
63 }
64 assert(PrevMask < NewMask && PrevNumCoveredRegs < NewNumCoveredRegs &&
65 "prev mask should always be lesser than new");
66
67 const TargetRegisterClass *RC = MRI.getRegClass(Reg);
68 const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo();
69 const SIRegisterInfo *STI = static_cast<const SIRegisterInfo *>(TRI);
70 unsigned RegKind = getRegKind(RC, STI);
71 if (TRI->getRegSizeInBits(*RC) != 32) {
72 // Reg is from a tuple register class.
73 if (PrevMask.none()) {
74 unsigned TupleIdx = TOTAL_KINDS + RegKind;
75 Value[TupleIdx] += Sign * TRI->getRegClassWeight(RC).RegWeight;
76 }
77 // Pressure scales with number of new registers covered by the new mask.
78 // Note when true16 is enabled, we can no longer safely use the following
79 // approach to calculate the difference in the number of 32-bit registers
80 // between two masks:
81 //
82 // Sign *= SIRegisterInfo::getNumCoveredRegs(~PrevMask & NewMask);
83 //
84 // The issue is that the mask calculation `~PrevMask & NewMask` doesn't
85 // properly account for partial usage of a 32-bit register when dealing with
86 // 16-bit registers.
87 //
88 // Consider this example:
89 // Assume PrevMask = 0b0010 and NewMask = 0b1111. Here, the correct register
90 // usage difference should be 1, because even though PrevMask uses only half
91 // of a 32-bit register, it should still be counted as a full register use.
92 // However, the mask calculation yields `~PrevMask & NewMask = 0b1101`, and
93 // calling `getNumCoveredRegs` returns 2 instead of 1. This incorrect
94 // calculation can lead to integer overflow when Sign = -1.
95 Sign *= NewNumCoveredRegs - PrevNumCoveredRegs;
96 }
97 Value[RegKind] += Sign;
98}
99
101 unsigned MaxOccupancy) const {
102 const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
103 unsigned DynamicVGPRBlockSize =
104 MF.getInfo<SIMachineFunctionInfo>()->getDynamicVGPRBlockSize();
105
106 const auto SGPROcc = std::min(MaxOccupancy,
107 ST.getOccupancyWithNumSGPRs(getSGPRNum()));
108 const auto VGPROcc = std::min(
109 MaxOccupancy, ST.getOccupancyWithNumVGPRs(getVGPRNum(ST.hasGFX90AInsts()),
110 DynamicVGPRBlockSize));
111 const auto OtherSGPROcc = std::min(MaxOccupancy,
112 ST.getOccupancyWithNumSGPRs(O.getSGPRNum()));
113 const auto OtherVGPROcc =
114 std::min(MaxOccupancy,
115 ST.getOccupancyWithNumVGPRs(O.getVGPRNum(ST.hasGFX90AInsts()),
116 DynamicVGPRBlockSize));
117
118 const auto Occ = std::min(SGPROcc, VGPROcc);
119 const auto OtherOcc = std::min(OtherSGPROcc, OtherVGPROcc);
120
121 // Give first precedence to the better occupancy.
122 if (Occ != OtherOcc)
123 return Occ > OtherOcc;
124
125 unsigned MaxVGPRs = ST.getMaxNumVGPRs(MF);
126 unsigned MaxSGPRs = ST.getMaxNumSGPRs(MF);
127
128 // SGPR excess pressure conditions
129 unsigned ExcessSGPR = std::max(static_cast<int>(getSGPRNum() - MaxSGPRs), 0);
130 unsigned OtherExcessSGPR =
131 std::max(static_cast<int>(O.getSGPRNum() - MaxSGPRs), 0);
132
133 auto WaveSize = ST.getWavefrontSize();
134 // The number of virtual VGPRs required to handle excess SGPR
135 unsigned VGPRForSGPRSpills = (ExcessSGPR + (WaveSize - 1)) / WaveSize;
136 unsigned OtherVGPRForSGPRSpills =
137 (OtherExcessSGPR + (WaveSize - 1)) / WaveSize;
138
139 unsigned MaxArchVGPRs = ST.getAddressableNumArchVGPRs();
140
141 // Unified excess pressure conditions, accounting for VGPRs used for SGPR
142 // spills
143 unsigned ExcessVGPR =
144 std::max(static_cast<int>(getVGPRNum(ST.hasGFX90AInsts()) +
145 VGPRForSGPRSpills - MaxVGPRs),
146 0);
147 unsigned OtherExcessVGPR =
148 std::max(static_cast<int>(O.getVGPRNum(ST.hasGFX90AInsts()) +
149 OtherVGPRForSGPRSpills - MaxVGPRs),
150 0);
151 // Arch VGPR excess pressure conditions, accounting for VGPRs used for SGPR
152 // spills
153 unsigned ExcessArchVGPR = std::max(
154 static_cast<int>(getVGPRNum(false) + VGPRForSGPRSpills - MaxArchVGPRs),
155 0);
156 unsigned OtherExcessArchVGPR =
157 std::max(static_cast<int>(O.getVGPRNum(false) + OtherVGPRForSGPRSpills -
158 MaxArchVGPRs),
159 0);
160 // AGPR excess pressure conditions
161 unsigned ExcessAGPR = std::max(
162 static_cast<int>(ST.hasGFX90AInsts() ? (getAGPRNum() - MaxArchVGPRs)
163 : (getAGPRNum() - MaxVGPRs)),
164 0);
165 unsigned OtherExcessAGPR = std::max(
166 static_cast<int>(ST.hasGFX90AInsts() ? (O.getAGPRNum() - MaxArchVGPRs)
167 : (O.getAGPRNum() - MaxVGPRs)),
168 0);
169
170 bool ExcessRP = ExcessSGPR || ExcessVGPR || ExcessArchVGPR || ExcessAGPR;
171 bool OtherExcessRP = OtherExcessSGPR || OtherExcessVGPR ||
172 OtherExcessArchVGPR || OtherExcessAGPR;
173
174 // Give second precedence to the reduced number of spills to hold the register
175 // pressure.
176 if (ExcessRP || OtherExcessRP) {
177 // The difference in excess VGPR pressure, after including VGPRs used for
178 // SGPR spills
179 int VGPRDiff = ((OtherExcessVGPR + OtherExcessArchVGPR + OtherExcessAGPR) -
180 (ExcessVGPR + ExcessArchVGPR + ExcessAGPR));
181
182 int SGPRDiff = OtherExcessSGPR - ExcessSGPR;
183
184 if (VGPRDiff != 0)
185 return VGPRDiff > 0;
186 if (SGPRDiff != 0) {
187 unsigned PureExcessVGPR =
188 std::max(static_cast<int>(getVGPRNum(ST.hasGFX90AInsts()) - MaxVGPRs),
189 0) +
190 std::max(static_cast<int>(getVGPRNum(false) - MaxArchVGPRs), 0);
191 unsigned OtherPureExcessVGPR =
192 std::max(
193 static_cast<int>(O.getVGPRNum(ST.hasGFX90AInsts()) - MaxVGPRs),
194 0) +
195 std::max(static_cast<int>(O.getVGPRNum(false) - MaxArchVGPRs), 0);
196
197 // If we have a special case where there is a tie in excess VGPR, but one
198 // of the pressures has VGPR usage from SGPR spills, prefer the pressure
199 // with SGPR spills.
200 if (PureExcessVGPR != OtherPureExcessVGPR)
201 return SGPRDiff < 0;
202 // If both pressures have the same excess pressure before and after
203 // accounting for SGPR spills, prefer fewer SGPR spills.
204 return SGPRDiff > 0;
205 }
206 }
207
208 bool SGPRImportant = SGPROcc < VGPROcc;
209 const bool OtherSGPRImportant = OtherSGPROcc < OtherVGPROcc;
210
211 // If both pressures disagree on what is more important compare vgprs.
212 if (SGPRImportant != OtherSGPRImportant) {
213 SGPRImportant = false;
214 }
215
216 // Give third precedence to lower register tuple pressure.
217 bool SGPRFirst = SGPRImportant;
218 for (int I = 2; I > 0; --I, SGPRFirst = !SGPRFirst) {
219 if (SGPRFirst) {
220 auto SW = getSGPRTuplesWeight();
221 auto OtherSW = O.getSGPRTuplesWeight();
222 if (SW != OtherSW)
223 return SW < OtherSW;
224 } else {
225 auto VW = getVGPRTuplesWeight();
226 auto OtherVW = O.getVGPRTuplesWeight();
227 if (VW != OtherVW)
228 return VW < OtherVW;
229 }
230 }
231
232 // Give final precedence to lower general RP.
233 return SGPRImportant ? (getSGPRNum() < O.getSGPRNum()):
234 (getVGPRNum(ST.hasGFX90AInsts()) <
235 O.getVGPRNum(ST.hasGFX90AInsts()));
236}
237
239 unsigned DynamicVGPRBlockSize) {
240 return Printable([&RP, ST, DynamicVGPRBlockSize](raw_ostream &OS) {
241 OS << "VGPRs: " << RP.getArchVGPRNum() << ' '
242 << "AGPRs: " << RP.getAGPRNum();
243 if (ST)
244 OS << "(O"
245 << ST->getOccupancyWithNumVGPRs(RP.getVGPRNum(ST->hasGFX90AInsts()),
246 DynamicVGPRBlockSize)
247 << ')';
248 OS << ", SGPRs: " << RP.getSGPRNum();
249 if (ST)
250 OS << "(O" << ST->getOccupancyWithNumSGPRs(RP.getSGPRNum()) << ')';
251 OS << ", LVGPR WT: " << RP.getVGPRTuplesWeight()
252 << ", LSGPR WT: " << RP.getSGPRTuplesWeight();
253 if (ST)
254 OS << " -> Occ: " << RP.getOccupancy(*ST, DynamicVGPRBlockSize);
255 OS << '\n';
256 });
257}
258
260 const MachineRegisterInfo &MRI) {
261 assert(MO.isDef() && MO.isReg() && MO.getReg().isVirtual());
262
263 // We don't rely on read-undef flag because in case of tentative schedule
264 // tracking it isn't set correctly yet. This works correctly however since
265 // use mask has been tracked before using LIS.
266 return MO.getSubReg() == 0 ?
267 MRI.getMaxLaneMaskForVReg(MO.getReg()) :
268 MRI.getTargetRegisterInfo()->getSubRegIndexLaneMask(MO.getSubReg());
269}
270
271static void
273 const MachineInstr &MI, const LiveIntervals &LIS,
274 const MachineRegisterInfo &MRI) {
275
276 auto &TRI = *MRI.getTargetRegisterInfo();
277 for (const auto &MO : MI.operands()) {
278 if (!MO.isReg() || !MO.getReg().isVirtual())
279 continue;
280 if (!MO.isUse() || !MO.readsReg())
281 continue;
282
283 Register Reg = MO.getReg();
284 auto I = llvm::find_if(VRegMaskOrUnits, [Reg](const VRegMaskOrUnit &RM) {
285 return RM.VRegOrUnit.asVirtualReg() == Reg;
286 });
287
288 auto &P = I == VRegMaskOrUnits.end()
289 ? VRegMaskOrUnits.emplace_back(VirtRegOrUnit(Reg),
291 : *I;
292
293 P.LaneMask |= MO.getSubReg() ? TRI.getSubRegIndexLaneMask(MO.getSubReg())
294 : MRI.getMaxLaneMaskForVReg(Reg);
295 }
296
297 SlotIndex InstrSI;
298 for (auto &P : VRegMaskOrUnits) {
299 auto &LI = LIS.getInterval(P.VRegOrUnit.asVirtualReg());
300 if (!LI.hasSubRanges())
301 continue;
302
303 // For a tentative schedule LIS isn't updated yet but livemask should
304 // remain the same on any schedule. Subreg defs can be reordered but they
305 // all must dominate uses anyway.
306 if (!InstrSI)
307 InstrSI = LIS.getInstructionIndex(MI).getBaseIndex();
308
309 P.LaneMask = getLiveLaneMask(LI, InstrSI, MRI, P.LaneMask);
310 }
311}
312
313/// Mostly copy/paste from CodeGen/RegisterPressure.cpp
315 const LiveIntervals &LIS, const MachineRegisterInfo &MRI,
316 bool TrackLaneMasks, Register Reg, SlotIndex Pos,
317 function_ref<bool(const LiveRange &LR, SlotIndex Pos)> Property) {
318 assert(Reg.isVirtual());
319 const LiveInterval &LI = LIS.getInterval(Reg);
320 LaneBitmask Result;
321 if (TrackLaneMasks && LI.hasSubRanges()) {
322 for (const LiveInterval::SubRange &SR : LI.subranges()) {
323 if (Property(SR, Pos))
324 Result |= SR.LaneMask;
325 }
326 } else if (Property(LI, Pos)) {
327 Result =
328 TrackLaneMasks ? MRI.getMaxLaneMaskForVReg(Reg) : LaneBitmask::getAll();
329 }
330
331 return Result;
332}
333
334/// Mostly copy/paste from CodeGen/RegisterPressure.cpp
335/// Helper to find a vreg use between two indices {PriorUseIdx, NextUseIdx}.
336/// The query starts with a lane bitmask which gets lanes/bits removed for every
337/// use we find.
338static LaneBitmask findUseBetween(unsigned Reg, LaneBitmask LastUseMask,
339 SlotIndex PriorUseIdx, SlotIndex NextUseIdx,
341 const SIRegisterInfo *TRI,
342 const LiveIntervals *LIS,
343 bool Upward = false) {
344 for (const MachineOperand &MO : MRI.use_nodbg_operands(Reg)) {
345 if (MO.isUndef())
346 continue;
347 const MachineInstr *MI = MO.getParent();
348 SlotIndex InstSlot = LIS->getInstructionIndex(*MI).getRegSlot();
349 bool InRange = Upward ? (InstSlot > PriorUseIdx && InstSlot <= NextUseIdx)
350 : (InstSlot >= PriorUseIdx && InstSlot < NextUseIdx);
351 if (!InRange)
352 continue;
353
354 unsigned SubRegIdx = MO.getSubReg();
355 LaneBitmask UseMask = TRI->getSubRegIndexLaneMask(SubRegIdx);
356 LastUseMask &= ~UseMask;
357 if (LastUseMask.none())
358 return LaneBitmask::getNone();
359 }
360 return LastUseMask;
361}
362
363////////////////////////////////////////////////////////////////////////////////
364// GCNRPTarget
365
367 : GCNRPTarget(RP, MF) {
368 const Function &F = MF.getFunction();
369 const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
370 setTarget(ST.getMaxNumSGPRs(F), ST.getMaxNumVGPRs(F));
371}
372
373GCNRPTarget::GCNRPTarget(unsigned NumSGPRs, unsigned NumVGPRs,
374 const MachineFunction &MF, const GCNRegPressure &RP)
375 : GCNRPTarget(RP, MF) {
376 setTarget(NumSGPRs, NumVGPRs);
377}
378
379GCNRPTarget::GCNRPTarget(unsigned Occupancy, const MachineFunction &MF,
380 const GCNRegPressure &RP)
381 : GCNRPTarget(RP, MF) {
382 const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
383 unsigned DynamicVGPRBlockSize =
385 setTarget(ST.getMaxNumSGPRs(Occupancy, /*Addressable=*/false),
386 ST.getMaxNumVGPRs(Occupancy, DynamicVGPRBlockSize));
387}
388
389void GCNRPTarget::setTarget(unsigned NumSGPRs, unsigned NumVGPRs) {
390 const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
391 MaxSGPRs = std::min(ST.getAddressableNumSGPRs(), NumSGPRs);
392 MaxVGPRs = std::min(ST.getAddressableNumArchVGPRs(), NumVGPRs);
393 if (UnifiedRF) {
394 unsigned DynamicVGPRBlockSize =
395 MF.getInfo<SIMachineFunctionInfo>()->getDynamicVGPRBlockSize();
396 MaxUnifiedVGPRs =
397 std::min(ST.getAddressableNumVGPRs(DynamicVGPRBlockSize), NumVGPRs);
398 } else {
399 MaxUnifiedVGPRs = 0;
400 }
401}
402
404 const MachineRegisterInfo &MRI = MF.getRegInfo();
405 const TargetRegisterClass *RC = MRI.getRegClass(Reg);
406 const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo();
407 const SIRegisterInfo *SRI = static_cast<const SIRegisterInfo *>(TRI);
408
409 if (SRI->isSGPRClass(RC))
410 return RP.getSGPRNum() > MaxSGPRs;
411 unsigned NumVGPRs =
412 SRI->isAGPRClass(RC) ? RP.getAGPRNum() : RP.getArchVGPRNum();
413 // The addressable limit must always be respected.
414 if (NumVGPRs > MaxVGPRs)
415 return true;
416 // For unified RFs, combined VGPR usage limit must be respected as well.
417 return UnifiedRF && RP.getVGPRNum(true) > MaxUnifiedVGPRs;
418}
419
421 if (RP.getSGPRNum() > MaxSGPRs || RP.getVGPRNum(false) > MaxVGPRs)
422 return false;
423 if (UnifiedRF && RP.getVGPRNum(true) > MaxUnifiedVGPRs)
424 return false;
425 return true;
426}
427
428///////////////////////////////////////////////////////////////////////////////
429// GCNRPTracker
430
432 const LiveIntervals &LIS,
434 LaneBitmask LaneMaskFilter) {
435 return getLiveLaneMask(LIS.getInterval(Reg), SI, MRI, LaneMaskFilter);
436}
437
440 LaneBitmask LaneMaskFilter) {
441 LaneBitmask LiveMask;
442 if (LI.hasSubRanges()) {
443 for (const auto &S : LI.subranges())
444 if ((S.LaneMask & LaneMaskFilter).any() && S.liveAt(SI)) {
445 LiveMask |= S.LaneMask;
446 assert(LiveMask == (LiveMask & MRI.getMaxLaneMaskForVReg(LI.reg())));
447 }
448 } else if (LI.liveAt(SI)) {
449 LiveMask = MRI.getMaxLaneMaskForVReg(LI.reg());
450 }
451 LiveMask &= LaneMaskFilter;
452 return LiveMask;
453}
454
456 const LiveIntervals &LIS,
458 GCNRegPressure::RegKind RegKind) {
460 for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
461 auto Reg = Register::index2VirtReg(I);
462 if (RegKind != GCNRegPressure::TOTAL_KINDS &&
463 GCNRegPressure::getRegKind(Reg, MRI) != RegKind)
464 continue;
465 if (!LIS.hasInterval(Reg))
466 continue;
467 auto LiveMask = getLiveLaneMask(Reg, SI, LIS, MRI);
468 if (LiveMask.any())
469 LiveRegs[Reg] = LiveMask;
470 }
471 return LiveRegs;
472}
473
475 const LiveRegSet *LiveRegsCopy,
476 bool After) {
477 const MachineFunction &MF = *MI.getMF();
478 MRI = &MF.getRegInfo();
479 if (LiveRegsCopy) {
480 if (&LiveRegs != LiveRegsCopy)
481 LiveRegs = *LiveRegsCopy;
482 } else {
483 LiveRegs = After ? getLiveRegsAfter(MI, LIS)
485 }
486
488}
489
491 const LiveRegSet &LiveRegs_) {
492 MRI = &MRI_;
493 LiveRegs = LiveRegs_;
494 LastTrackedMI = nullptr;
495 MaxPressure = CurPressure = getRegPressure(MRI_, LiveRegs_);
496}
497
498/// Mostly copy/paste from CodeGen/RegisterPressure.cpp
501 LIS, *MRI, true, Reg, Pos.getBaseIndex(),
502 [](const LiveRange &LR, SlotIndex Pos) {
503 const LiveRange::Segment *S = LR.getSegmentContaining(Pos);
504 return S != nullptr && S->end == Pos.getRegSlot();
505 });
506}
507
508////////////////////////////////////////////////////////////////////////////////
509// GCNUpwardRPTracker
510
512 assert(MRI && "call reset first");
513
514 LastTrackedMI = &MI;
515
516 if (MI.isDebugInstr())
517 return;
518
519 // Kill all defs.
520 GCNRegPressure DefPressure, ECDefPressure;
521 bool HasECDefs = false;
522 for (const MachineOperand &MO : MI.all_defs()) {
523 if (!MO.getReg().isVirtual())
524 continue;
525
526 Register Reg = MO.getReg();
527 LaneBitmask DefMask = getDefRegMask(MO, *MRI);
528
529 // Treat a def as fully live at the moment of definition: keep a record.
530 if (MO.isEarlyClobber()) {
531 ECDefPressure.inc(Reg, LaneBitmask::getNone(), DefMask, *MRI);
532 HasECDefs = true;
533 } else
534 DefPressure.inc(Reg, LaneBitmask::getNone(), DefMask, *MRI);
535
536 auto I = LiveRegs.find(Reg);
537 if (I == LiveRegs.end())
538 continue;
539
540 LaneBitmask &LiveMask = I->second;
541 LaneBitmask PrevMask = LiveMask;
542 LiveMask &= ~DefMask;
543 CurPressure.inc(Reg, PrevMask, LiveMask, *MRI);
544 if (LiveMask.none())
545 LiveRegs.erase(I);
546 }
547
548 // Update MaxPressure with defs pressure.
549 DefPressure += CurPressure;
550 if (HasECDefs)
551 DefPressure += ECDefPressure;
552 MaxPressure = max(DefPressure, MaxPressure);
553
554 // Make uses alive.
556 collectVirtualRegUses(RegUses, MI, LIS, *MRI);
557 for (const VRegMaskOrUnit &U : RegUses) {
558 LaneBitmask &LiveMask = LiveRegs[U.VRegOrUnit.asVirtualReg()];
559 LaneBitmask PrevMask = LiveMask;
560 LiveMask |= U.LaneMask;
561 CurPressure.inc(U.VRegOrUnit.asVirtualReg(), PrevMask, LiveMask, *MRI);
562 }
563
564 // Update MaxPressure with uses plus early-clobber defs pressure.
565 MaxPressure = HasECDefs ? max(CurPressure + ECDefPressure, MaxPressure)
567
569}
570
571////////////////////////////////////////////////////////////////////////////////
572// GCNDownwardRPTracker
573
575 const LiveRegSet *LiveRegsCopy) {
576 MRI = &MI.getMF()->getRegInfo();
577 LastTrackedMI = nullptr;
578 MBBEnd = MI.getParent()->end();
579 NextMI = &MI;
580 NextMI = skipDebugInstructionsForward(NextMI, MBBEnd);
581 if (NextMI == MBBEnd)
582 return false;
583 GCNRPTracker::reset(*NextMI, LiveRegsCopy, false);
584 return true;
585}
586
588 bool UseInternalIterator) {
589 assert(MRI && "call reset first");
591 const MachineInstr *CurrMI;
592 if (UseInternalIterator) {
593 if (!LastTrackedMI)
594 return NextMI == MBBEnd;
595
596 assert(NextMI == MBBEnd || !NextMI->isDebugInstr());
597 CurrMI = LastTrackedMI;
598
599 SI = NextMI == MBBEnd
600 ? LIS.getInstructionIndex(*LastTrackedMI).getDeadSlot()
601 : LIS.getInstructionIndex(*NextMI).getBaseIndex();
602 } else { //! UseInternalIterator
603 SI = LIS.getInstructionIndex(*MI).getBaseIndex();
604 CurrMI = MI;
605 }
606
607 assert(SI.isValid());
608
609 // Remove dead registers or mask bits.
610 SmallSet<Register, 8> SeenRegs;
611 for (auto &MO : CurrMI->operands()) {
612 if (!MO.isReg() || !MO.getReg().isVirtual())
613 continue;
614 if (MO.isUse() && !MO.readsReg())
615 continue;
616 if (!UseInternalIterator && MO.isDef())
617 continue;
618 if (!SeenRegs.insert(MO.getReg()).second)
619 continue;
620 const LiveInterval &LI = LIS.getInterval(MO.getReg());
621 if (LI.hasSubRanges()) {
622 auto It = LiveRegs.end();
623 for (const auto &S : LI.subranges()) {
624 if (!S.liveAt(SI)) {
625 if (It == LiveRegs.end()) {
626 It = LiveRegs.find(MO.getReg());
627 if (It == LiveRegs.end())
628 llvm_unreachable("register isn't live");
629 }
630 auto PrevMask = It->second;
631 It->second &= ~S.LaneMask;
632 CurPressure.inc(MO.getReg(), PrevMask, It->second, *MRI);
633 }
634 }
635 if (It != LiveRegs.end() && It->second.none())
636 LiveRegs.erase(It);
637 } else if (!LI.liveAt(SI)) {
638 auto It = LiveRegs.find(MO.getReg());
639 if (It == LiveRegs.end())
640 llvm_unreachable("register isn't live");
641 CurPressure.inc(MO.getReg(), It->second, LaneBitmask::getNone(), *MRI);
642 LiveRegs.erase(It);
643 }
644 }
645
647
648 LastTrackedMI = nullptr;
649
650 return UseInternalIterator && (NextMI == MBBEnd);
651}
652
654 bool UseInternalIterator) {
655 if (UseInternalIterator) {
656 LastTrackedMI = &*NextMI++;
657 NextMI = skipDebugInstructionsForward(NextMI, MBBEnd);
658 } else {
660 }
661
662 const MachineInstr *CurrMI = LastTrackedMI;
663
664 // Add new registers or mask bits.
665 for (const auto &MO : CurrMI->all_defs()) {
666 Register Reg = MO.getReg();
667 if (!Reg.isVirtual())
668 continue;
669 auto &LiveMask = LiveRegs[Reg];
670 auto PrevMask = LiveMask;
671 LiveMask |= getDefRegMask(MO, *MRI);
672 CurPressure.inc(Reg, PrevMask, LiveMask, *MRI);
673 }
674
676}
677
678bool GCNDownwardRPTracker::advance(MachineInstr *MI, bool UseInternalIterator) {
679 if (UseInternalIterator && NextMI == MBBEnd)
680 return false;
681
682 advanceBeforeNext(MI, UseInternalIterator);
683 advanceToNext(MI, UseInternalIterator);
684 if (!UseInternalIterator) {
685 // We must remove any dead def lanes from the current RP
686 advanceBeforeNext(MI, true);
687 }
688 return true;
689}
690
692 while (NextMI != End)
693 if (!advance()) return false;
694 return true;
695}
696
699 const LiveRegSet *LiveRegsCopy) {
700 reset(*Begin, LiveRegsCopy);
701 return advance(End);
702}
703
705 const GCNRPTracker::LiveRegSet &TrackedLR,
706 const TargetRegisterInfo *TRI, StringRef Pfx) {
707 return Printable([&LISLR, &TrackedLR, TRI, Pfx](raw_ostream &OS) {
708 for (auto const &P : TrackedLR) {
709 auto I = LISLR.find(P.first);
710 if (I == LISLR.end()) {
711 OS << Pfx << printReg(P.first, TRI) << ":L" << PrintLaneMask(P.second)
712 << " isn't found in LIS reported set\n";
713 } else if (I->second != P.second) {
714 OS << Pfx << printReg(P.first, TRI)
715 << " masks doesn't match: LIS reported " << PrintLaneMask(I->second)
716 << ", tracked " << PrintLaneMask(P.second) << '\n';
717 }
718 }
719 for (auto const &P : LISLR) {
720 auto I = TrackedLR.find(P.first);
721 if (I == TrackedLR.end()) {
722 OS << Pfx << printReg(P.first, TRI) << ":L" << PrintLaneMask(P.second)
723 << " isn't found in tracked set\n";
724 }
725 }
726 });
727}
728
731 const SIRegisterInfo *TRI) const {
732 assert(!MI->isDebugOrPseudoInstr() && "Expect a nondebug instruction.");
733
734 SlotIndex SlotIdx;
735 SlotIdx = LIS.getInstructionIndex(*MI).getRegSlot();
736
737 // Account for register pressure similar to RegPressureTracker::recede().
738 RegisterOperands RegOpers;
739 RegOpers.collect(*MI, *TRI, *MRI, true, /*IgnoreDead=*/false);
740 RegOpers.adjustLaneLiveness(LIS, *MRI, SlotIdx);
741 GCNRegPressure TempPressure = CurPressure;
742
743 for (const VRegMaskOrUnit &Use : RegOpers.Uses) {
744 if (!Use.VRegOrUnit.isVirtualReg())
745 continue;
746 Register Reg = Use.VRegOrUnit.asVirtualReg();
747 LaneBitmask LastUseMask = getLastUsedLanes(Reg, SlotIdx);
748 if (LastUseMask.none())
749 continue;
750 // The LastUseMask is queried from the liveness information of instruction
751 // which may be further down the schedule. Some lanes may actually not be
752 // last uses for the current position.
753 // FIXME: allow the caller to pass in the list of vreg uses that remain
754 // to be bottom-scheduled to avoid searching uses at each query.
755 SlotIndex CurrIdx;
756 const MachineBasicBlock *MBB = MI->getParent();
758 LastTrackedMI ? LastTrackedMI : MBB->begin(), MBB->end());
759 if (IdxPos == MBB->end()) {
760 CurrIdx = LIS.getMBBEndIdx(MBB);
761 } else {
762 CurrIdx = LIS.getInstructionIndex(*IdxPos).getRegSlot();
763 }
764
765 LastUseMask =
766 findUseBetween(Reg, LastUseMask, CurrIdx, SlotIdx, *MRI, TRI, &LIS);
767 if (LastUseMask.none())
768 continue;
769
770 auto It = LiveRegs.find(Reg);
771 LaneBitmask LiveMask = It != LiveRegs.end() ? It->second : LaneBitmask(0);
772 LaneBitmask NewMask = LiveMask & ~LastUseMask;
773 TempPressure.inc(Reg, LiveMask, NewMask, *MRI);
774 }
775
776 // Generate liveness for defs.
777 for (const VRegMaskOrUnit &Def : RegOpers.Defs) {
778 if (!Def.VRegOrUnit.isVirtualReg())
779 continue;
780 Register Reg = Def.VRegOrUnit.asVirtualReg();
781 auto It = LiveRegs.find(Reg);
782 LaneBitmask LiveMask = It != LiveRegs.end() ? It->second : LaneBitmask(0);
783 LaneBitmask NewMask = LiveMask | Def.LaneMask;
784 TempPressure.inc(Reg, LiveMask, NewMask, *MRI);
785 }
786
787 return TempPressure;
788}
789
791 const auto &SI = LIS.getInstructionIndex(*LastTrackedMI).getBaseIndex();
792 const auto LISLR = llvm::getLiveRegs(SI, LIS, *MRI);
793 const auto &TrackedLR = LiveRegs;
794
795 if (!isEqual(LISLR, TrackedLR)) {
796 dbgs() << "\nGCNUpwardRPTracker error: Tracked and"
797 " LIS reported livesets mismatch:\n"
798 << print(LISLR, *MRI);
799 reportMismatch(LISLR, TrackedLR, MRI->getTargetRegisterInfo());
800 return false;
801 }
802
803 auto LISPressure = getRegPressure(*MRI, LISLR);
804 if (LISPressure != CurPressure) {
805 dbgs() << "GCNUpwardRPTracker error: Pressure sets different\nTracked: "
806 << print(CurPressure) << "LIS rpt: " << print(LISPressure);
807 return false;
808 }
809 return true;
810}
811
813 const MachineRegisterInfo &MRI) {
814 return Printable([&LiveRegs, &MRI](raw_ostream &OS) {
815 const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo();
816 for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
818 auto It = LiveRegs.find(Reg);
819 if (It != LiveRegs.end() && It->second.any())
820 OS << ' ' << printReg(Reg, TRI) << ':' << PrintLaneMask(It->second);
821 }
822 OS << '\n';
823 });
824}
825
826void GCNRegPressure::dump() const { dbgs() << print(*this); }
827
829 "amdgpu-print-rp-downward",
830 cl::desc("Use GCNDownwardRPTracker for GCNRegPressurePrinter pass"),
831 cl::init(false), cl::Hidden);
832
835
836INITIALIZE_PASS(GCNRegPressurePrinter, "amdgpu-print-rp", "", true, true)
837
838// Return lanemask of Reg's subregs that are live-through at [Begin, End] and
839// are fully covered by Mask.
840static LaneBitmask
842 Register Reg, SlotIndex Begin, SlotIndex End,
843 LaneBitmask Mask = LaneBitmask::getAll()) {
844
845 auto IsInOneSegment = [Begin, End](const LiveRange &LR) -> bool {
846 auto *Segment = LR.getSegmentContaining(Begin);
847 return Segment && Segment->contains(End);
848 };
849
850 LaneBitmask LiveThroughMask;
851 const LiveInterval &LI = LIS.getInterval(Reg);
852 if (LI.hasSubRanges()) {
853 for (auto &SR : LI.subranges()) {
854 if ((SR.LaneMask & Mask) == SR.LaneMask && IsInOneSegment(SR))
855 LiveThroughMask |= SR.LaneMask;
856 }
857 } else {
858 LaneBitmask RegMask = MRI.getMaxLaneMaskForVReg(Reg);
859 if ((RegMask & Mask) == RegMask && IsInOneSegment(LI))
860 LiveThroughMask = RegMask;
861 }
862
863 return LiveThroughMask;
864}
865
867 const MachineRegisterInfo &MRI = MF.getRegInfo();
868 const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo();
870
871 auto &OS = dbgs();
872
873// Leading spaces are important for YAML syntax.
874#define PFX " "
875
876 OS << "---\nname: " << MF.getName() << "\nbody: |\n";
877
878 auto printRP = [](const GCNRegPressure &RP) {
879 return Printable([&RP](raw_ostream &OS) {
880 OS << format(PFX " %-5d", RP.getSGPRNum())
881 << format(" %-5d", RP.getVGPRNum(false));
882 });
883 };
884
885 auto ReportLISMismatchIfAny = [&](const GCNRPTracker::LiveRegSet &TrackedLR,
886 const GCNRPTracker::LiveRegSet &LISLR) {
887 if (LISLR != TrackedLR) {
888 OS << PFX " mis LIS: " << llvm::print(LISLR, MRI)
889 << reportMismatch(LISLR, TrackedLR, TRI, PFX " ");
890 }
891 };
892
893 // Register pressure before and at an instruction (in program order).
895
896 for (auto &MBB : MF) {
897 RP.clear();
898 RP.reserve(MBB.size());
899
900 OS << PFX;
901 MBB.printName(OS);
902 OS << ":\n";
903
904 SlotIndex MBBStartSlot = LIS.getSlotIndexes()->getMBBStartIdx(&MBB);
905 SlotIndex MBBLastSlot = LIS.getSlotIndexes()->getMBBLastIdx(&MBB);
906
907 GCNRPTracker::LiveRegSet LiveIn, LiveOut;
908 GCNRegPressure RPAtMBBEnd;
909
910 if (UseDownwardTracker) {
911 if (MBB.empty()) {
912 LiveIn = LiveOut = getLiveRegs(MBBStartSlot, LIS, MRI);
913 RPAtMBBEnd = getRegPressure(MRI, LiveIn);
914 } else {
915 GCNDownwardRPTracker RPT(LIS);
916 RPT.reset(MBB.front());
917
918 LiveIn = RPT.getLiveRegs();
919
920 while (!RPT.advanceBeforeNext()) {
921 GCNRegPressure RPBeforeMI = RPT.getPressure();
922 RPT.advanceToNext();
923 RP.emplace_back(RPBeforeMI, RPT.getPressure());
924 }
925
926 LiveOut = RPT.getLiveRegs();
927 RPAtMBBEnd = RPT.getPressure();
928 }
929 } else {
930 GCNUpwardRPTracker RPT(LIS);
931 RPT.reset(MRI, MBBLastSlot);
932
933 LiveOut = RPT.getLiveRegs();
934 RPAtMBBEnd = RPT.getPressure();
935
936 for (auto &MI : reverse(MBB)) {
937 RPT.resetMaxPressure();
938 RPT.recede(MI);
939 if (!MI.isDebugInstr())
940 RP.emplace_back(RPT.getPressure(), RPT.getMaxPressure());
941 }
942
943 LiveIn = RPT.getLiveRegs();
944 }
945
946 OS << PFX " Live-in: " << llvm::print(LiveIn, MRI);
948 ReportLISMismatchIfAny(LiveIn, getLiveRegs(MBBStartSlot, LIS, MRI));
949
950 OS << PFX " SGPR VGPR\n";
951 int I = 0;
952 for (auto &MI : MBB) {
953 if (!MI.isDebugInstr()) {
954 auto &[RPBeforeInstr, RPAtInstr] =
955 RP[UseDownwardTracker ? I : (RP.size() - 1 - I)];
956 ++I;
957 OS << printRP(RPBeforeInstr) << '\n' << printRP(RPAtInstr) << " ";
958 } else
959 OS << PFX " ";
960 MI.print(OS);
961 }
962 OS << printRP(RPAtMBBEnd) << '\n';
963
964 OS << PFX " Live-out:" << llvm::print(LiveOut, MRI);
966 ReportLISMismatchIfAny(LiveOut, getLiveRegs(MBBLastSlot, LIS, MRI));
967
968 GCNRPTracker::LiveRegSet LiveThrough;
969 for (auto [Reg, Mask] : LiveIn) {
970 LaneBitmask MaskIntersection = Mask & LiveOut.lookup(Reg);
971 if (MaskIntersection.any()) {
973 MRI, LIS, Reg, MBBStartSlot, MBBLastSlot, MaskIntersection);
974 if (LTMask.any())
975 LiveThrough[Reg] = LTMask;
976 }
977 }
978 OS << PFX " Live-thr:" << llvm::print(LiveThrough, MRI);
979 OS << printRP(getRegPressure(MRI, LiveThrough)) << '\n';
980 }
981 OS << "...\n";
982 return false;
983
984#undef PFX
985}
986
987#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
990 LiveIntervals &LIS,
991 const MachineLoopInfo *MLI) {
992
993 const MachineRegisterInfo &MRI = MF.getRegInfo();
994 const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo();
995 auto &OS = dbgs();
996 const char *RegName = GCNRegPressure::getName(Kind);
997
998 unsigned MaxNumRegs = 0;
999 const MachineInstr *MaxPressureMI = nullptr;
1000 GCNUpwardRPTracker RPT(LIS);
1001 for (const MachineBasicBlock &MBB : MF) {
1003 for (const MachineInstr &MI : reverse(MBB)) {
1004 RPT.recede(MI);
1005 unsigned NumRegs = RPT.getMaxPressure().getNumRegs(Kind);
1006 if (NumRegs > MaxNumRegs) {
1007 MaxNumRegs = NumRegs;
1008 MaxPressureMI = &MI;
1009 }
1010 }
1011 }
1012
1013 SlotIndex MISlot = LIS.getInstructionIndex(*MaxPressureMI);
1014
1015 // Max pressure can occur at either the early-clobber or register slot.
1016 // Choose the maximum liveset between both slots. This is ugly but this is
1017 // diagnostic code.
1018 SlotIndex ECSlot = MISlot.getRegSlot(true);
1019 SlotIndex RSlot = MISlot.getRegSlot(false);
1020 GCNRPTracker::LiveRegSet ECLiveSet = getLiveRegs(ECSlot, LIS, MRI, Kind);
1021 GCNRPTracker::LiveRegSet RLiveSet = getLiveRegs(RSlot, LIS, MRI, Kind);
1022 unsigned ECNumRegs = getRegPressure(MRI, ECLiveSet).getNumRegs(Kind);
1023 unsigned RNumRegs = getRegPressure(MRI, RLiveSet).getNumRegs(Kind);
1024 GCNRPTracker::LiveRegSet *LiveSet =
1025 ECNumRegs > RNumRegs ? &ECLiveSet : &RLiveSet;
1026 SlotIndex MaxPressureSlot = ECNumRegs > RNumRegs ? ECSlot : RSlot;
1027 assert(getRegPressure(MRI, *LiveSet).getNumRegs(Kind) == MaxNumRegs);
1028
1029 // Split live registers into single-def and multi-def sets.
1030 GCNRegPressure SDefPressure, MDefPressure;
1031 SmallVector<Register, 16> SDefRegs, MDefRegs;
1032 for (auto [Reg, LaneMask] : *LiveSet) {
1033 assert(GCNRegPressure::getRegKind(Reg, MRI) == Kind);
1034 LiveInterval &LI = LIS.getInterval(Reg);
1035 if (LI.getNumValNums() == 1 ||
1036 (LI.hasSubRanges() &&
1037 llvm::all_of(LI.subranges(), [](const LiveInterval::SubRange &SR) {
1038 return SR.getNumValNums() == 1;
1039 }))) {
1040 SDefPressure.inc(Reg, LaneBitmask::getNone(), LaneMask, MRI);
1041 SDefRegs.push_back(Reg);
1042 } else {
1043 MDefPressure.inc(Reg, LaneBitmask::getNone(), LaneMask, MRI);
1044 MDefRegs.push_back(Reg);
1045 }
1046 }
1047 unsigned SDefNumRegs = SDefPressure.getNumRegs(Kind);
1048 unsigned MDefNumRegs = MDefPressure.getNumRegs(Kind);
1049 assert(SDefNumRegs + MDefNumRegs == MaxNumRegs);
1050
1051 auto printLoc = [&](const MachineBasicBlock *MBB, SlotIndex SI) {
1052 return Printable([&, MBB, SI](raw_ostream &OS) {
1053 OS << SI << ':' << printMBBReference(*MBB);
1054 if (MLI)
1055 if (const MachineLoop *ML = MLI->getLoopFor(MBB))
1056 OS << " (LoopHdr " << printMBBReference(*ML->getHeader())
1057 << ", Depth " << ML->getLoopDepth() << ")";
1058 });
1059 };
1060
1061 auto PrintRegInfo = [&](Register Reg, LaneBitmask LiveMask) {
1062 GCNRegPressure RegPressure;
1063 RegPressure.inc(Reg, LaneBitmask::getNone(), LiveMask, MRI);
1064 OS << " " << printReg(Reg, TRI) << ':'
1065 << TRI->getRegClassName(MRI.getRegClass(Reg)) << ", LiveMask "
1066 << PrintLaneMask(LiveMask) << " (" << RegPressure.getNumRegs(Kind) << ' '
1067 << RegName << "s)\n";
1068
1069 // Use std::map to sort def/uses by SlotIndex.
1070 std::map<SlotIndex, const MachineInstr *> Instrs;
1071 for (const MachineInstr &MI : MRI.reg_nodbg_instructions(Reg)) {
1072 Instrs[LIS.getInstructionIndex(MI).getRegSlot()] = &MI;
1073 }
1074
1075 for (const auto &[SI, MI] : Instrs) {
1076 OS << " ";
1077 if (MI->definesRegister(Reg, TRI))
1078 OS << "def ";
1079 if (MI->readsRegister(Reg, TRI))
1080 OS << "use ";
1081 OS << printLoc(MI->getParent(), SI) << ": " << *MI;
1082 }
1083 };
1084
1085 OS << "\n*** Register pressure info (" << RegName << "s) for " << MF.getName()
1086 << " ***\n";
1087 OS << "Max pressure is " << MaxNumRegs << ' ' << RegName << "s at "
1088 << printLoc(MaxPressureMI->getParent(), MaxPressureSlot) << ": "
1089 << *MaxPressureMI;
1090
1091 OS << "\nLive registers with single definition (" << SDefNumRegs << ' '
1092 << RegName << "s):\n";
1093
1094 // Sort SDefRegs by number of uses (smallest first)
1095 llvm::sort(SDefRegs, [&](Register A, Register B) {
1096 return std::distance(MRI.use_nodbg_begin(A), MRI.use_nodbg_end()) <
1097 std::distance(MRI.use_nodbg_begin(B), MRI.use_nodbg_end());
1098 });
1099
1100 for (const Register Reg : SDefRegs) {
1101 PrintRegInfo(Reg, LiveSet->lookup(Reg));
1102 }
1103
1104 OS << "\nLive registers with multiple definitions (" << MDefNumRegs << ' '
1105 << RegName << "s):\n";
1106 for (const Register Reg : MDefRegs) {
1107 PrintRegInfo(Reg, LiveSet->lookup(Reg));
1108 }
1109}
1110#endif
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
aarch64 promote const
constexpr LLT S1
MachineBasicBlock & MBB
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition Compiler.h:638
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 RegName(no)
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Register Reg
Register const TargetRegisterInfo * TRI
static bool InRange(int64_t Value, unsigned short Shift, int LBound, int HBound)
#define P(N)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition PassSupport.h:56
static LaneBitmask getLanesWithProperty(const LiveIntervals &LIS, const MachineRegisterInfo &MRI, bool TrackLaneMasks, VirtRegOrUnit VRegOrUnit, SlotIndex Pos, LaneBitmask SafeDefault, bool(*Property)(const LiveRange &LR, SlotIndex Pos))
static LaneBitmask findUseBetween(VirtRegOrUnit VRegOrUnit, LaneBitmask LastUseMask, SlotIndex PriorUseIdx, SlotIndex NextUseIdx, const MachineRegisterInfo &MRI, const LiveIntervals *LIS)
Helper to find a vreg use between two indices [PriorUseIdx, NextUseIdx).
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:205
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:178
unsigned size() const
Definition DenseMap.h:110
iterator end()
Definition DenseMap.h:81
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.
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
DenseMap< unsigned, LaneBitmask > LiveRegSet
LaneBitmask getLastUsedLanes(Register Reg, SlotIndex Pos) const
Mostly copy/paste from CodeGen/RegisterPressure.cpp.
GCNRegPressure MaxPressure
void reset(const MachineInstr &MI, const LiveRegSet *LiveRegsCopy, bool After)
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.
LiveInterval - This class represents the liveness of a register, or stack slot.
Register reg() const
bool hasSubRanges() const
Returns true if subregister liveness information is available.
iterator_range< subrange_iterator > subranges()
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)
This class represents the liveness of a register, stack slot, etc.
bool liveAt(SlotIndex index) const
unsigned getNumValNums() const
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
MachineInstrBundleIterator< const MachineInstr > const_iterator
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.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Representation of each machine instruction.
const MachineBasicBlock * getParent() const
filtered_mop_range all_defs()
Returns an iterator range over all operands that are (explicit or implicit) register defs.
mop_range operands()
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,...
AnalysisType & getAnalysis() const
getAnalysis<AnalysisType>() - This function is used by subclasses to get to the analysis information ...
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:20
static Register index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
Definition Register.h:72
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Definition Register.h:79
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 getBaseIndex() const
Returns the base index for associated with this index.
SlotIndex getPrevSlot() const
Returns the previous slot in the index list.
SlotIndex getRegSlot(bool EC=false) const
Returns the register use/def slot in the current instruction for a normal or early-clobber def.
SlotIndex getMBBLastIdx(const MachineBasicBlock *MBB) const
Returns the last valid index in the given basic block.
SlotIndex getMBBEndIdx(unsigned Num) const
Returns the index past the last valid index in the given basic block.
SlotIndex getMBBStartIdx(unsigned Num) const
Returns the first index in the given basic block number.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition SmallSet.h:133
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:183
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
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
Wrapper class representing a virtual register or register unit.
Definition Register.h:181
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)
This is an optimization pass for GlobalISel generic memory operations.
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 all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1725
bool isEqual(const GCNRPTracker::LiveRegSet &S1, const GCNRPTracker::LiveRegSet &S2)
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
GCNRPTracker::LiveRegSet getLiveRegs(SlotIndex SI, const LiveIntervals &LIS, const MachineRegisterInfo &MRI, GCNRegPressure::RegKind RegKind=GCNRegPressure::TOTAL_KINDS)
GCNRegPressure getRegPressure(const MachineRegisterInfo &MRI, Range &&LiveRegs)
Printable PrintLaneMask(LaneBitmask LaneMask)
Create Printable object to print LaneBitmasks on a raw_ostream.
Definition LaneBitmask.h:92
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 getLiveRegsAfter(const MachineInstr &MI, const LiveIntervals &LIS)
auto reverse(ContainerTy &&C)
Definition STLExtras.h:406
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1622
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:129
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:1758
GCNRPTracker::LiveRegSet getLiveRegsBefore(const MachineInstr &MI, const LiveIntervals &LIS)
LLVM_ABI void dumpMaxRegPressure(MachineFunction &MF, GCNRegPressure::RegKind Kind, LiveIntervals &LIS, const MachineLoopInfo *MLI)
LLVM_ABI Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
Printable reportMismatch(const GCNRPTracker::LiveRegSet &LISLR, const GCNRPTracker::LiveRegSet &TrackedL, const TargetRegisterInfo *TRI, StringRef Pfx=" ")
LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:869
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)
unsigned getNumRegs(RegKind Kind) const
unsigned getVGPRTuplesWeight() const
unsigned getVGPRNum(bool UnifiedVGPRFile) const
friend Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST, unsigned DynamicVGPRBlockSize)
void inc(unsigned Reg, LaneBitmask PrevMask, LaneBitmask NewMask, const MachineRegisterInfo &MRI)
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