LLVM 23.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);
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
100namespace {
101struct RegExcess {
102 unsigned SGPR = 0;
103 unsigned VGPR = 0;
104 unsigned ArchVGPR = 0;
105 unsigned AGPR = 0;
106
107 bool anyExcess() const { return SGPR || VGPR || ArchVGPR || AGPR; }
108 bool hasVectorRegisterExcess() const { return VGPR || ArchVGPR || AGPR; }
109
110 RegExcess(const MachineFunction &MF, const GCNRegPressure &RP)
111 : RegExcess(MF, RP, GCNRPTarget(MF, RP)) {}
112 RegExcess(const MachineFunction &MF, const GCNRegPressure &RP,
113 const GCNRPTarget &Target) {
114 unsigned MaxSGPRs = Target.getMaxSGPRs();
115 unsigned MaxVGPRs = Target.getMaxVGPRs();
116
117 const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
118 SGPR = std::max(static_cast<int>(RP.getSGPRNum() - MaxSGPRs), 0);
119
120 // The number of virtual VGPRs required to handle excess SGPR
121 unsigned WaveSize = ST.getWavefrontSize();
122 unsigned VGPRForSGPRSpills = divideCeil(SGPR, WaveSize);
123
124 unsigned MaxArchVGPRs = ST.getAddressableNumArchVGPRs();
125
126 // Unified excess pressure conditions, accounting for VGPRs used for SGPR
127 // spills
128 VGPR = std::max(static_cast<int>(RP.getVGPRNum(ST.hasGFX90AInsts()) +
129 VGPRForSGPRSpills - MaxVGPRs),
130 0);
131
132 unsigned ArchVGPRLimit = ST.hasGFX90AInsts() ? MaxArchVGPRs : MaxVGPRs;
133 // Arch VGPR excess pressure conditions, accounting for VGPRs used for SGPR
134 // spills
135 ArchVGPR = std::max(static_cast<int>(RP.getArchVGPRNum() +
136 VGPRForSGPRSpills - ArchVGPRLimit),
137 0);
138
139 // AGPR excess pressure conditions
140 AGPR = std::max(static_cast<int>(RP.getAGPRNum() - ArchVGPRLimit), 0);
141 }
142};
143} // namespace
144
146 unsigned MaxOccupancy) const {
147 const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
148 unsigned DynamicVGPRBlockSize =
149 MF.getInfo<SIMachineFunctionInfo>()->getDynamicVGPRBlockSize();
150
151 const auto SGPROcc = std::min(MaxOccupancy,
152 ST.getOccupancyWithNumSGPRs(getSGPRNum()));
153 const auto VGPROcc = std::min(
154 MaxOccupancy, ST.getOccupancyWithNumVGPRs(getVGPRNum(ST.hasGFX90AInsts()),
155 DynamicVGPRBlockSize));
156 const auto OtherSGPROcc = std::min(MaxOccupancy,
157 ST.getOccupancyWithNumSGPRs(O.getSGPRNum()));
158 const auto OtherVGPROcc =
159 std::min(MaxOccupancy,
160 ST.getOccupancyWithNumVGPRs(O.getVGPRNum(ST.hasGFX90AInsts()),
161 DynamicVGPRBlockSize));
162
163 const auto Occ = std::min(SGPROcc, VGPROcc);
164 const auto OtherOcc = std::min(OtherSGPROcc, OtherVGPROcc);
165
166 // Give first precedence to the better occupancy.
167 if (Occ != OtherOcc)
168 return Occ > OtherOcc;
169
170 unsigned MaxVGPRs = ST.getMaxNumVGPRs(MF);
171
172 RegExcess Excess(MF, *this);
173 RegExcess OtherExcess(MF, O);
174
175 unsigned MaxArchVGPRs = ST.getAddressableNumArchVGPRs();
176
177 bool ExcessRP = Excess.anyExcess();
178 bool OtherExcessRP = OtherExcess.anyExcess();
179
180 // Give second precedence to the reduced number of spills to hold the register
181 // pressure.
182 if (ExcessRP || OtherExcessRP) {
183 // The difference in excess VGPR pressure, after including VGPRs used for
184 // SGPR spills
185 int VGPRDiff =
186 ((OtherExcess.VGPR + OtherExcess.ArchVGPR + OtherExcess.AGPR) -
187 (Excess.VGPR + Excess.ArchVGPR + Excess.AGPR));
188
189 int SGPRDiff = OtherExcess.SGPR - Excess.SGPR;
190
191 if (VGPRDiff != 0)
192 return VGPRDiff > 0;
193 if (SGPRDiff != 0) {
194 unsigned PureExcessVGPR =
195 std::max(static_cast<int>(getVGPRNum(ST.hasGFX90AInsts()) - MaxVGPRs),
196 0) +
197 std::max(static_cast<int>(getVGPRNum(false) - MaxArchVGPRs), 0);
198 unsigned OtherPureExcessVGPR =
199 std::max(
200 static_cast<int>(O.getVGPRNum(ST.hasGFX90AInsts()) - MaxVGPRs),
201 0) +
202 std::max(static_cast<int>(O.getVGPRNum(false) - MaxArchVGPRs), 0);
203
204 // If we have a special case where there is a tie in excess VGPR, but one
205 // of the pressures has VGPR usage from SGPR spills, prefer the pressure
206 // with SGPR spills.
207 if (PureExcessVGPR != OtherPureExcessVGPR)
208 return SGPRDiff < 0;
209 // If both pressures have the same excess pressure before and after
210 // accounting for SGPR spills, prefer fewer SGPR spills.
211 return SGPRDiff > 0;
212 }
213 }
214
215 bool SGPRImportant = SGPROcc < VGPROcc;
216 const bool OtherSGPRImportant = OtherSGPROcc < OtherVGPROcc;
217
218 // If both pressures disagree on what is more important compare vgprs.
219 if (SGPRImportant != OtherSGPRImportant) {
220 SGPRImportant = false;
221 }
222
223 // Give third precedence to lower register tuple pressure.
224 bool SGPRFirst = SGPRImportant;
225 for (int I = 2; I > 0; --I, SGPRFirst = !SGPRFirst) {
226 if (SGPRFirst) {
227 auto SW = getSGPRTuplesWeight();
228 auto OtherSW = O.getSGPRTuplesWeight();
229 if (SW != OtherSW)
230 return SW < OtherSW;
231 } else {
232 auto VW = getVGPRTuplesWeight();
233 auto OtherVW = O.getVGPRTuplesWeight();
234 if (VW != OtherVW)
235 return VW < OtherVW;
236 }
237 }
238
239 // Give final precedence to lower general RP.
240 return SGPRImportant ? (getSGPRNum() < O.getSGPRNum()):
241 (getVGPRNum(ST.hasGFX90AInsts()) <
242 O.getVGPRNum(ST.hasGFX90AInsts()));
243}
244
246 unsigned DynamicVGPRBlockSize) {
247 return Printable([&RP, ST, DynamicVGPRBlockSize](raw_ostream &OS) {
248 OS << "VGPRs: " << RP.getArchVGPRNum() << ' '
249 << "AGPRs: " << RP.getAGPRNum();
250 if (ST)
251 OS << "(O"
252 << ST->getOccupancyWithNumVGPRs(RP.getVGPRNum(ST->hasGFX90AInsts()),
253 DynamicVGPRBlockSize)
254 << ')';
255 OS << ", SGPRs: " << RP.getSGPRNum();
256 if (ST)
257 OS << "(O" << ST->getOccupancyWithNumSGPRs(RP.getSGPRNum()) << ')';
258 OS << ", LVGPR WT: " << RP.getVGPRTuplesWeight()
259 << ", LSGPR WT: " << RP.getSGPRTuplesWeight();
260 if (ST)
261 OS << " -> Occ: " << RP.getOccupancy(*ST, DynamicVGPRBlockSize);
262 OS << '\n';
263 });
264}
265
267 const MachineRegisterInfo &MRI) {
268 assert(MO.isDef() && MO.isReg() && MO.getReg().isVirtual());
269
270 // We don't rely on read-undef flag because in case of tentative schedule
271 // tracking it isn't set correctly yet. This works correctly however since
272 // use mask has been tracked before using LIS.
273 return MO.getSubReg() == 0 ?
274 MRI.getMaxLaneMaskForVReg(MO.getReg()) :
276}
277
278static void
280 const MachineInstr &MI, const LiveIntervals &LIS,
281 const MachineRegisterInfo &MRI) {
282
283 auto &TRI = *MRI.getTargetRegisterInfo();
284 for (const auto &MO : MI.operands()) {
285 if (!MO.isReg() || !MO.getReg().isVirtual())
286 continue;
287 if (!MO.isUse() || !MO.readsReg())
288 continue;
289
290 Register Reg = MO.getReg();
291 auto I = llvm::find_if(VRegMaskOrUnits, [Reg](const VRegMaskOrUnit &RM) {
292 return RM.VRegOrUnit.asVirtualReg() == Reg;
293 });
294
295 auto &P = I == VRegMaskOrUnits.end()
296 ? VRegMaskOrUnits.emplace_back(VirtRegOrUnit(Reg),
298 : *I;
299
300 P.LaneMask |= MO.getSubReg() ? TRI.getSubRegIndexLaneMask(MO.getSubReg())
302 }
303
304 SlotIndex InstrSI;
305 for (auto &P : VRegMaskOrUnits) {
306 auto &LI = LIS.getInterval(P.VRegOrUnit.asVirtualReg());
307 if (!LI.hasSubRanges())
308 continue;
309
310 // For a tentative schedule LIS isn't updated yet but livemask should
311 // remain the same on any schedule. Subreg defs can be reordered but they
312 // all must dominate uses anyway.
313 if (!InstrSI)
314 InstrSI = LIS.getInstructionIndex(MI).getBaseIndex();
315
316 P.LaneMask = getLiveLaneMask(LI, InstrSI, MRI, P.LaneMask);
317 }
318}
319
320/// Mostly copy/paste from CodeGen/RegisterPressure.cpp
322 const LiveIntervals &LIS, const MachineRegisterInfo &MRI,
323 bool TrackLaneMasks, Register Reg, SlotIndex Pos,
324 function_ref<bool(const LiveRange &LR, SlotIndex Pos)> Property) {
325 assert(Reg.isVirtual());
326 const LiveInterval &LI = LIS.getInterval(Reg);
327 LaneBitmask Result;
328 if (TrackLaneMasks && LI.hasSubRanges()) {
329 for (const LiveInterval::SubRange &SR : LI.subranges()) {
330 if (Property(SR, Pos))
331 Result |= SR.LaneMask;
332 }
333 } else if (Property(LI, Pos)) {
334 Result =
335 TrackLaneMasks ? MRI.getMaxLaneMaskForVReg(Reg) : LaneBitmask::getAll();
336 }
337
338 return Result;
339}
340
341/// Mostly copy/paste from CodeGen/RegisterPressure.cpp
342/// Helper to find a vreg use between two indices {PriorUseIdx, NextUseIdx}.
343/// The query starts with a lane bitmask which gets lanes/bits removed for every
344/// use we find.
345static LaneBitmask findUseBetween(unsigned Reg, LaneBitmask LastUseMask,
346 SlotIndex PriorUseIdx, SlotIndex NextUseIdx,
347 const MachineRegisterInfo &MRI,
348 const SIRegisterInfo *TRI,
349 const LiveIntervals *LIS,
350 bool Upward = false) {
351 for (const MachineOperand &MO : MRI.use_nodbg_operands(Reg)) {
352 if (MO.isUndef())
353 continue;
354 const MachineInstr *MI = MO.getParent();
355 SlotIndex InstSlot = LIS->getInstructionIndex(*MI).getRegSlot();
356 bool InRange = Upward ? (InstSlot > PriorUseIdx && InstSlot <= NextUseIdx)
357 : (InstSlot >= PriorUseIdx && InstSlot < NextUseIdx);
358 if (!InRange)
359 continue;
360
361 unsigned SubRegIdx = MO.getSubReg();
362 LaneBitmask UseMask = TRI->getSubRegIndexLaneMask(SubRegIdx);
363 LastUseMask &= ~UseMask;
364 if (LastUseMask.none())
365 return LaneBitmask::getNone();
366 }
367 return LastUseMask;
368}
369
370////////////////////////////////////////////////////////////////////////////////
371// GCNRPTarget
372
374 : GCNRPTarget(RP, MF) {
375 const Function &F = MF.getFunction();
376 const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
377 setTarget(ST.getMaxNumSGPRs(F), ST.getMaxNumVGPRs(F));
378}
379
380GCNRPTarget::GCNRPTarget(unsigned NumSGPRs, unsigned NumVGPRs,
381 const MachineFunction &MF, const GCNRegPressure &RP)
382 : GCNRPTarget(RP, MF) {
383 setTarget(NumSGPRs, NumVGPRs);
384}
385
386GCNRPTarget::GCNRPTarget(unsigned Occupancy, const MachineFunction &MF,
387 const GCNRegPressure &RP)
388 : GCNRPTarget(RP, MF) {
389 const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
390 unsigned DynamicVGPRBlockSize =
392 setTarget(ST.getMaxNumSGPRs(Occupancy, /*Addressable=*/false),
393 ST.getMaxNumVGPRs(Occupancy, DynamicVGPRBlockSize));
394}
395
396void GCNRPTarget::setTarget(unsigned NumSGPRs, unsigned NumVGPRs) {
397 const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
398 MaxSGPRs = std::min(ST.getAddressableNumSGPRs(), NumSGPRs);
399 MaxVGPRs = std::min(ST.getAddressableNumArchVGPRs(), NumVGPRs);
400 if (UnifiedRF) {
401 unsigned DynamicVGPRBlockSize =
402 MF.getInfo<SIMachineFunctionInfo>()->getDynamicVGPRBlockSize();
403 MaxUnifiedVGPRs =
404 std::min(ST.getAddressableNumVGPRs(DynamicVGPRBlockSize), NumVGPRs);
405 } else {
406 MaxUnifiedVGPRs = 0;
407 }
408}
409
411 const MachineRegisterInfo &MRI = MF.getRegInfo();
412 const TargetRegisterClass *RC = MRI.getRegClass(Reg);
414 const SIRegisterInfo *SRI = static_cast<const SIRegisterInfo *>(TRI);
415
416 RegExcess Excess(MF, RP, *this);
417
418 if (SRI->isSGPRClass(RC))
419 return Excess.SGPR;
420
421 if (SRI->isAGPRClass(RC))
422 return (UnifiedRF && Excess.VGPR) || Excess.AGPR;
423
424 return (UnifiedRF && Excess.VGPR) || Excess.ArchVGPR;
425}
426
428 RegExcess Excess(MF, RP, *this);
429 if (SaveRP.getSGPRNum() != 0 && Excess.SGPR != 0)
430 return true;
431 if (SaveRP.getArchVGPRNum() != 0 && Excess.ArchVGPR != 0)
432 return true;
433 if (SaveRP.getAGPRNum() != 0 && Excess.AGPR != 0)
434 return true;
435 if (UnifiedRF && Excess.VGPR != 0)
436 return SaveRP.getArchVGPRNum() != 0 || SaveRP.getAGPRNum() != 0;
437 return false;
438}
439
440unsigned GCNRPTarget::getNumRegsBenefit(const GCNRegPressure &SaveRP) const {
441 RegExcess Excess(MF, RP, *this);
442 const unsigned NumVGPRAboveAddrLimit =
443 std::min(Excess.ArchVGPR, SaveRP.getArchVGPRNum()) +
444 std::min(Excess.AGPR, SaveRP.getAGPRNum());
445 unsigned NumRegsSaved =
446 std::min(Excess.SGPR, SaveRP.getSGPRNum()) + NumVGPRAboveAddrLimit;
447
448 if (UnifiedRF && Excess.VGPR) {
449 // We have already accounted for excess pressure above addressive limits for
450 // the individual VGPR classes. However for targets with unified RFs there
451 // is also a unified VGPR pressure (ArchVGPR + AGPR combination) limit to
452 // honor that may be more restrictive that the per-VGPR-class limits. We
453 // must also be careful not to double-count VGPR saves that may contribute
454 // to lowering pressure both above the addressable limit in their respective
455 // class as well as in the unified VGPR limit.
456 const unsigned VGPRSave = SaveRP.getArchVGPRNum() + SaveRP.getAGPRNum();
457 if (NumVGPRAboveAddrLimit < VGPRSave)
458 NumRegsSaved += std::min(Excess.VGPR, VGPRSave - NumVGPRAboveAddrLimit);
459 }
460
461 return NumRegsSaved;
462}
463
464bool GCNRPTarget::satisfied(const GCNRegPressure &TestRP) const {
465 if (TestRP.getSGPRNum() > MaxSGPRs || TestRP.getVGPRNum(false) > MaxVGPRs)
466 return false;
467 if (UnifiedRF && TestRP.getVGPRNum(true) > MaxUnifiedVGPRs)
468 return false;
469 return true;
470}
471
473 RegExcess Excess(MF, RP, *this);
474 return Excess.hasVectorRegisterExcess();
475}
476
477///////////////////////////////////////////////////////////////////////////////
478// GCNRPTracker
479
481 const LiveIntervals &LIS,
482 const MachineRegisterInfo &MRI,
483 LaneBitmask LaneMaskFilter) {
484 return getLiveLaneMask(LIS.getInterval(Reg), SI, MRI, LaneMaskFilter);
485}
486
488 const MachineRegisterInfo &MRI,
489 LaneBitmask LaneMaskFilter) {
490 LaneBitmask LiveMask;
491 if (LI.hasSubRanges()) {
492 for (const auto &S : LI.subranges())
493 if ((S.LaneMask & LaneMaskFilter).any() && S.liveAt(SI)) {
494 LiveMask |= S.LaneMask;
495 assert(LiveMask == (LiveMask & MRI.getMaxLaneMaskForVReg(LI.reg())));
496 }
497 } else if (LI.liveAt(SI)) {
498 LiveMask = MRI.getMaxLaneMaskForVReg(LI.reg());
499 }
500 LiveMask &= LaneMaskFilter;
501 return LiveMask;
502}
503
505 const LiveIntervals &LIS,
506 const MachineRegisterInfo &MRI,
507 GCNRegPressure::RegKind RegKind) {
509 for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
510 auto Reg = Register::index2VirtReg(I);
511 if (RegKind != GCNRegPressure::TOTAL_KINDS &&
512 GCNRegPressure::getRegKind(Reg, MRI) != RegKind)
513 continue;
514 if (!LIS.hasInterval(Reg))
515 continue;
516 auto LiveMask = getLiveLaneMask(Reg, SI, LIS, MRI);
517 if (LiveMask.any())
518 LiveRegs[Reg] = LiveMask;
519 }
520 return LiveRegs;
521}
522
524 const LiveRegSet *LiveRegsCopy,
525 bool After) {
526 const MachineFunction &MF = *MI.getMF();
527 MRI = &MF.getRegInfo();
528 if (LiveRegsCopy) {
529 if (&LiveRegs != LiveRegsCopy)
530 LiveRegs = *LiveRegsCopy;
531 } else {
532 LiveRegs = After ? getLiveRegsAfter(MI, LIS)
534 }
535
537}
538
540 const LiveRegSet &LiveRegs_) {
541 MRI = &MRI_;
542 LiveRegs = LiveRegs_;
543 LastTrackedMI = nullptr;
544 MaxPressure = CurPressure = getRegPressure(MRI_, LiveRegs_);
545}
546
547/// Mostly copy/paste from CodeGen/RegisterPressure.cpp
550 LIS, *MRI, true, Reg, Pos.getBaseIndex(),
551 [](const LiveRange &LR, SlotIndex Pos) {
552 const LiveRange::Segment *S = LR.getSegmentContaining(Pos);
553 return S != nullptr && S->end == Pos.getRegSlot();
554 });
555}
556
557////////////////////////////////////////////////////////////////////////////////
558// GCNUpwardRPTracker
559
561 assert(MRI && "call reset first");
562
563 LastTrackedMI = &MI;
564
565 if (MI.isDebugInstr())
566 return;
567
568 // Kill all defs.
569 GCNRegPressure DefPressure, ECDefPressure;
570 bool HasECDefs = false;
571 for (const MachineOperand &MO : MI.all_defs()) {
572 if (!MO.getReg().isVirtual())
573 continue;
574
575 Register Reg = MO.getReg();
576 LaneBitmask DefMask = getDefRegMask(MO, *MRI);
577
578 // Treat a def as fully live at the moment of definition: keep a record.
579 if (MO.isEarlyClobber()) {
580 ECDefPressure.inc(Reg, LaneBitmask::getNone(), DefMask, *MRI);
581 HasECDefs = true;
582 } else
583 DefPressure.inc(Reg, LaneBitmask::getNone(), DefMask, *MRI);
584
585 auto I = LiveRegs.find(Reg);
586 if (I == LiveRegs.end())
587 continue;
588
589 LaneBitmask &LiveMask = I->second;
590 LaneBitmask PrevMask = LiveMask;
591 LiveMask &= ~DefMask;
592 CurPressure.inc(Reg, PrevMask, LiveMask, *MRI);
593 if (LiveMask.none())
594 LiveRegs.erase(I);
595 }
596
597 // Update MaxPressure with defs pressure.
598 DefPressure += CurPressure;
599 if (HasECDefs)
600 DefPressure += ECDefPressure;
601 MaxPressure = max(DefPressure, MaxPressure);
602
603 // Make uses alive.
605 collectVirtualRegUses(RegUses, MI, LIS, *MRI);
606 for (const VRegMaskOrUnit &U : RegUses) {
607 LaneBitmask &LiveMask = LiveRegs[U.VRegOrUnit.asVirtualReg()];
608 LaneBitmask PrevMask = LiveMask;
609 LiveMask |= U.LaneMask;
610 CurPressure.inc(U.VRegOrUnit.asVirtualReg(), PrevMask, LiveMask, *MRI);
611 }
612
613 // Update MaxPressure with uses plus early-clobber defs pressure.
614 MaxPressure = HasECDefs ? max(CurPressure + ECDefPressure, MaxPressure)
616
618}
619
620////////////////////////////////////////////////////////////////////////////////
621// GCNDownwardRPTracker
622
624 const LiveRegSet *LiveRegsCopy) {
625 MRI = &MI.getMF()->getRegInfo();
626 LastTrackedMI = nullptr;
627 MBBEnd = MI.getParent()->end();
628 NextMI = &MI;
629 NextMI = skipDebugInstructionsForward(NextMI, MBBEnd);
630 if (NextMI == MBBEnd)
631 return false;
632 GCNRPTracker::reset(*NextMI, LiveRegsCopy, false);
633 return true;
634}
635
637 bool UseInternalIterator) {
638 assert(MRI && "call reset first");
640 const MachineInstr *CurrMI;
641 if (UseInternalIterator) {
642 if (!LastTrackedMI)
643 return NextMI == MBBEnd;
644
645 assert(NextMI == MBBEnd || !NextMI->isDebugInstr());
646 CurrMI = LastTrackedMI;
647
648 SI = NextMI == MBBEnd
649 ? LIS.getInstructionIndex(*LastTrackedMI).getDeadSlot()
650 : LIS.getInstructionIndex(*NextMI).getBaseIndex();
651 } else { //! UseInternalIterator
652 SI = LIS.getInstructionIndex(*MI).getBaseIndex();
653 CurrMI = MI;
654 }
655
656 assert(SI.isValid());
657
658 // Remove dead registers or mask bits.
659 SmallSet<Register, 8> SeenRegs;
660 for (auto &MO : CurrMI->operands()) {
661 if (!MO.isReg() || !MO.getReg().isVirtual())
662 continue;
663 if (MO.isUse() && !MO.readsReg())
664 continue;
665 if (!UseInternalIterator && MO.isDef())
666 continue;
667 if (!SeenRegs.insert(MO.getReg()).second)
668 continue;
669 const LiveInterval &LI = LIS.getInterval(MO.getReg());
670 if (LI.hasSubRanges()) {
671 auto It = LiveRegs.end();
672 for (const auto &S : LI.subranges()) {
673 if (!S.liveAt(SI)) {
674 if (It == LiveRegs.end()) {
675 It = LiveRegs.find(MO.getReg());
676 if (It == LiveRegs.end())
677 llvm_unreachable("register isn't live");
678 }
679 auto PrevMask = It->second;
680 It->second &= ~S.LaneMask;
681 CurPressure.inc(MO.getReg(), PrevMask, It->second, *MRI);
682 }
683 }
684 if (It != LiveRegs.end() && It->second.none())
685 LiveRegs.erase(It);
686 } else if (!LI.liveAt(SI)) {
687 auto It = LiveRegs.find(MO.getReg());
688 if (It == LiveRegs.end())
689 llvm_unreachable("register isn't live");
690 CurPressure.inc(MO.getReg(), It->second, LaneBitmask::getNone(), *MRI);
691 LiveRegs.erase(It);
692 }
693 }
694
696
697 LastTrackedMI = nullptr;
698
699 return UseInternalIterator && (NextMI == MBBEnd);
700}
701
703 bool UseInternalIterator) {
704 if (UseInternalIterator) {
705 LastTrackedMI = &*NextMI++;
706 NextMI = skipDebugInstructionsForward(NextMI, MBBEnd);
707 } else {
709 }
710
711 const MachineInstr *CurrMI = LastTrackedMI;
712
713 // Add new registers or mask bits.
714 for (const auto &MO : CurrMI->all_defs()) {
715 Register Reg = MO.getReg();
716 if (!Reg.isVirtual())
717 continue;
718 auto &LiveMask = LiveRegs[Reg];
719 auto PrevMask = LiveMask;
720 LiveMask |= getDefRegMask(MO, *MRI);
721 CurPressure.inc(Reg, PrevMask, LiveMask, *MRI);
722 }
723
725}
726
727bool GCNDownwardRPTracker::advance(MachineInstr *MI, bool UseInternalIterator) {
728 if (UseInternalIterator && NextMI == MBBEnd)
729 return false;
730
731 advanceBeforeNext(MI, UseInternalIterator);
732 advanceToNext(MI, UseInternalIterator);
733 if (!UseInternalIterator) {
734 // We must remove any dead def lanes from the current RP
735 advanceBeforeNext(MI, true);
736 }
737 return true;
738}
739
741 while (NextMI != End)
742 if (!advance()) return false;
743 return true;
744}
745
748 const LiveRegSet *LiveRegsCopy) {
749 reset(*Begin, LiveRegsCopy);
750 return advance(End);
751}
752
754 const GCNRPTracker::LiveRegSet &TrackedLR,
755 const TargetRegisterInfo *TRI, StringRef Pfx) {
756 return Printable([&LISLR, &TrackedLR, TRI, Pfx](raw_ostream &OS) {
757 for (auto const &P : TrackedLR) {
758 auto I = LISLR.find(P.first);
759 if (I == LISLR.end()) {
760 OS << Pfx << printReg(P.first, TRI) << ":L" << PrintLaneMask(P.second)
761 << " isn't found in LIS reported set\n";
762 } else if (I->second != P.second) {
763 OS << Pfx << printReg(P.first, TRI)
764 << " masks doesn't match: LIS reported " << PrintLaneMask(I->second)
765 << ", tracked " << PrintLaneMask(P.second) << '\n';
766 }
767 }
768 for (auto const &P : LISLR) {
769 auto I = TrackedLR.find(P.first);
770 if (I == TrackedLR.end()) {
771 OS << Pfx << printReg(P.first, TRI) << ":L" << PrintLaneMask(P.second)
772 << " isn't found in tracked set\n";
773 }
774 }
775 });
776}
777
780 const SIRegisterInfo *TRI) const {
781 assert(!MI->isDebugOrPseudoInstr() && "Expect a nondebug instruction.");
782
783 SlotIndex SlotIdx;
784 SlotIdx = LIS.getInstructionIndex(*MI).getRegSlot();
785
786 // Account for register pressure similar to RegPressureTracker::recede().
787 RegisterOperands RegOpers;
788 RegOpers.collect(*MI, *TRI, *MRI, true, /*IgnoreDead=*/false);
789 RegOpers.adjustLaneLiveness(LIS, *MRI, SlotIdx);
790 GCNRegPressure TempPressure = CurPressure;
791
792 for (const VRegMaskOrUnit &Use : RegOpers.Uses) {
793 if (!Use.VRegOrUnit.isVirtualReg())
794 continue;
795 Register Reg = Use.VRegOrUnit.asVirtualReg();
796 LaneBitmask LastUseMask = getLastUsedLanes(Reg, SlotIdx);
797 if (LastUseMask.none())
798 continue;
799 // The LastUseMask is queried from the liveness information of instruction
800 // which may be further down the schedule. Some lanes may actually not be
801 // last uses for the current position.
802 // FIXME: allow the caller to pass in the list of vreg uses that remain
803 // to be bottom-scheduled to avoid searching uses at each query.
804 SlotIndex CurrIdx;
805 const MachineBasicBlock *MBB = MI->getParent();
807 LastTrackedMI ? LastTrackedMI : MBB->begin(), MBB->end());
808 if (IdxPos == MBB->end()) {
809 CurrIdx = LIS.getMBBEndIdx(MBB);
810 } else {
811 CurrIdx = LIS.getInstructionIndex(*IdxPos).getRegSlot();
812 }
813
814 LastUseMask =
815 findUseBetween(Reg, LastUseMask, CurrIdx, SlotIdx, *MRI, TRI, &LIS);
816 if (LastUseMask.none())
817 continue;
818
819 auto It = LiveRegs.find(Reg);
820 LaneBitmask LiveMask = It != LiveRegs.end() ? It->second : LaneBitmask(0);
821 LaneBitmask NewMask = LiveMask & ~LastUseMask;
822 TempPressure.inc(Reg, LiveMask, NewMask, *MRI);
823 }
824
825 // Generate liveness for defs.
826 for (const VRegMaskOrUnit &Def : RegOpers.Defs) {
827 if (!Def.VRegOrUnit.isVirtualReg())
828 continue;
829 Register Reg = Def.VRegOrUnit.asVirtualReg();
830 auto It = LiveRegs.find(Reg);
831 LaneBitmask LiveMask = It != LiveRegs.end() ? It->second : LaneBitmask(0);
832 LaneBitmask NewMask = LiveMask | Def.LaneMask;
833 TempPressure.inc(Reg, LiveMask, NewMask, *MRI);
834 }
835
836 return TempPressure;
837}
838
840 const auto &SI = LIS.getInstructionIndex(*LastTrackedMI).getBaseIndex();
841 const auto LISLR = llvm::getLiveRegs(SI, LIS, *MRI);
842 const auto &TrackedLR = LiveRegs;
843
844 if (!isEqual(LISLR, TrackedLR)) {
845 dbgs() << "\nGCNUpwardRPTracker error: Tracked and"
846 " LIS reported livesets mismatch:\n"
847 << print(LISLR, *MRI);
848 reportMismatch(LISLR, TrackedLR, MRI->getTargetRegisterInfo());
849 return false;
850 }
851
852 auto LISPressure = getRegPressure(*MRI, LISLR);
853 if (LISPressure != CurPressure) {
854 dbgs() << "GCNUpwardRPTracker error: Pressure sets different\nTracked: "
855 << print(CurPressure) << "LIS rpt: " << print(LISPressure);
856 return false;
857 }
858 return true;
859}
860
862 const MachineRegisterInfo &MRI) {
863 return Printable([&LiveRegs, &MRI](raw_ostream &OS) {
865 for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
867 auto It = LiveRegs.find(Reg);
868 if (It != LiveRegs.end() && It->second.any())
869 OS << ' ' << printReg(Reg, TRI) << ':' << PrintLaneMask(It->second);
870 }
871 OS << '\n';
872 });
873}
874
875void GCNRegPressure::dump() const { dbgs() << print(*this); }
876
878 "amdgpu-print-rp-downward",
879 cl::desc("Use GCNDownwardRPTracker for GCNRegPressurePrinter pass"),
880 cl::init(false), cl::Hidden);
881
884
885INITIALIZE_PASS(GCNRegPressurePrinter, "amdgpu-print-rp", "", true, true)
886
887// Return lanemask of Reg's subregs that are live-through at [Begin, End] and
888// are fully covered by Mask.
889static LaneBitmask
891 Register Reg, SlotIndex Begin, SlotIndex End,
892 LaneBitmask Mask = LaneBitmask::getAll()) {
893
894 auto IsInOneSegment = [Begin, End](const LiveRange &LR) -> bool {
895 auto *Segment = LR.getSegmentContaining(Begin);
896 return Segment && Segment->contains(End);
897 };
898
899 LaneBitmask LiveThroughMask;
900 const LiveInterval &LI = LIS.getInterval(Reg);
901 if (LI.hasSubRanges()) {
902 for (auto &SR : LI.subranges()) {
903 if ((SR.LaneMask & Mask) == SR.LaneMask && IsInOneSegment(SR))
904 LiveThroughMask |= SR.LaneMask;
905 }
906 } else {
908 if ((RegMask & Mask) == RegMask && IsInOneSegment(LI))
909 LiveThroughMask = RegMask;
910 }
911
912 return LiveThroughMask;
913}
914
916 const MachineRegisterInfo &MRI = MF.getRegInfo();
919
920 auto &OS = dbgs();
921
922// Leading spaces are important for YAML syntax.
923#define PFX " "
924
925 OS << "---\nname: " << MF.getName() << "\nbody: |\n";
926
927 auto printRP = [](const GCNRegPressure &RP) {
928 return Printable([&RP](raw_ostream &OS) {
929 OS << format(PFX " %-5d", RP.getSGPRNum())
930 << format(" %-5d", RP.getVGPRNum(false));
931 });
932 };
933
934 auto ReportLISMismatchIfAny = [&](const GCNRPTracker::LiveRegSet &TrackedLR,
935 const GCNRPTracker::LiveRegSet &LISLR) {
936 if (LISLR != TrackedLR) {
937 OS << PFX " mis LIS: " << llvm::print(LISLR, MRI)
938 << reportMismatch(LISLR, TrackedLR, TRI, PFX " ");
939 }
940 };
941
942 // Register pressure before and at an instruction (in program order).
944
945 for (auto &MBB : MF) {
946 RP.clear();
947 RP.reserve(MBB.size());
948
949 OS << PFX;
950 MBB.printName(OS);
951 OS << ":\n";
952
953 SlotIndex MBBStartSlot = LIS.getSlotIndexes()->getMBBStartIdx(&MBB);
954 SlotIndex MBBLastSlot = LIS.getSlotIndexes()->getMBBLastIdx(&MBB);
955
956 GCNRPTracker::LiveRegSet LiveIn, LiveOut;
957 GCNRegPressure RPAtMBBEnd;
958
959 if (UseDownwardTracker) {
960 if (MBB.empty()) {
961 LiveIn = LiveOut = getLiveRegs(MBBStartSlot, LIS, MRI);
962 RPAtMBBEnd = getRegPressure(MRI, LiveIn);
963 } else {
964 GCNDownwardRPTracker RPT(LIS);
965 RPT.reset(MBB.front());
966
967 LiveIn = RPT.getLiveRegs();
968
969 while (!RPT.advanceBeforeNext()) {
970 GCNRegPressure RPBeforeMI = RPT.getPressure();
971 RPT.advanceToNext();
972 RP.emplace_back(RPBeforeMI, RPT.getPressure());
973 }
974
975 LiveOut = RPT.getLiveRegs();
976 RPAtMBBEnd = RPT.getPressure();
977 }
978 } else {
979 GCNUpwardRPTracker RPT(LIS);
980 RPT.reset(MRI, MBBLastSlot);
981
982 LiveOut = RPT.getLiveRegs();
983 RPAtMBBEnd = RPT.getPressure();
984
985 for (auto &MI : reverse(MBB)) {
986 RPT.resetMaxPressure();
987 RPT.recede(MI);
988 if (!MI.isDebugInstr())
989 RP.emplace_back(RPT.getPressure(), RPT.getMaxPressure());
990 }
991
992 LiveIn = RPT.getLiveRegs();
993 }
994
995 OS << PFX " Live-in: " << llvm::print(LiveIn, MRI);
997 ReportLISMismatchIfAny(LiveIn, getLiveRegs(MBBStartSlot, LIS, MRI));
998
999 OS << PFX " SGPR VGPR\n";
1000 int I = 0;
1001 for (auto &MI : MBB) {
1002 if (!MI.isDebugInstr()) {
1003 auto &[RPBeforeInstr, RPAtInstr] =
1004 RP[UseDownwardTracker ? I : (RP.size() - 1 - I)];
1005 ++I;
1006 OS << printRP(RPBeforeInstr) << '\n' << printRP(RPAtInstr) << " ";
1007 } else
1008 OS << PFX " ";
1009 MI.print(OS);
1010 }
1011 OS << printRP(RPAtMBBEnd) << '\n';
1012
1013 OS << PFX " Live-out:" << llvm::print(LiveOut, MRI);
1015 ReportLISMismatchIfAny(LiveOut, getLiveRegs(MBBLastSlot, LIS, MRI));
1016
1017 GCNRPTracker::LiveRegSet LiveThrough;
1018 for (auto [Reg, Mask] : LiveIn) {
1019 LaneBitmask MaskIntersection = Mask & LiveOut.lookup(Reg);
1020 if (MaskIntersection.any()) {
1022 MRI, LIS, Reg, MBBStartSlot, MBBLastSlot, MaskIntersection);
1023 if (LTMask.any())
1024 LiveThrough[Reg] = LTMask;
1025 }
1026 }
1027 OS << PFX " Live-thr:" << llvm::print(LiveThrough, MRI);
1028 OS << printRP(getRegPressure(MRI, LiveThrough)) << '\n';
1029 }
1030 OS << "...\n";
1031 return false;
1032
1033#undef PFX
1034}
1035
1036#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1039 LiveIntervals &LIS,
1040 const MachineLoopInfo *MLI) {
1041
1042 const MachineRegisterInfo &MRI = MF.getRegInfo();
1044 auto &OS = dbgs();
1045 const char *RegName = GCNRegPressure::getName(Kind);
1046
1047 unsigned MaxNumRegs = 0;
1048 const MachineInstr *MaxPressureMI = nullptr;
1049 GCNUpwardRPTracker RPT(LIS);
1050 for (const MachineBasicBlock &MBB : MF) {
1051 RPT.reset(MRI, LIS.getSlotIndexes()->getMBBEndIdx(&MBB).getPrevSlot());
1052 for (const MachineInstr &MI : reverse(MBB)) {
1053 RPT.recede(MI);
1054 unsigned NumRegs = RPT.getMaxPressure().getNumRegs(Kind);
1055 if (NumRegs > MaxNumRegs) {
1056 MaxNumRegs = NumRegs;
1057 MaxPressureMI = &MI;
1058 }
1059 }
1060 }
1061
1062 SlotIndex MISlot = LIS.getInstructionIndex(*MaxPressureMI);
1063
1064 // Max pressure can occur at either the early-clobber or register slot.
1065 // Choose the maximum liveset between both slots. This is ugly but this is
1066 // diagnostic code.
1067 SlotIndex ECSlot = MISlot.getRegSlot(true);
1068 SlotIndex RSlot = MISlot.getRegSlot(false);
1069 GCNRPTracker::LiveRegSet ECLiveSet = getLiveRegs(ECSlot, LIS, MRI, Kind);
1070 GCNRPTracker::LiveRegSet RLiveSet = getLiveRegs(RSlot, LIS, MRI, Kind);
1071 unsigned ECNumRegs = getRegPressure(MRI, ECLiveSet).getNumRegs(Kind);
1072 unsigned RNumRegs = getRegPressure(MRI, RLiveSet).getNumRegs(Kind);
1073 GCNRPTracker::LiveRegSet *LiveSet =
1074 ECNumRegs > RNumRegs ? &ECLiveSet : &RLiveSet;
1075 SlotIndex MaxPressureSlot = ECNumRegs > RNumRegs ? ECSlot : RSlot;
1076 assert(getRegPressure(MRI, *LiveSet).getNumRegs(Kind) == MaxNumRegs);
1077
1078 // Split live registers into single-def and multi-def sets.
1079 GCNRegPressure SDefPressure, MDefPressure;
1080 SmallVector<Register, 16> SDefRegs, MDefRegs;
1081 for (auto [Reg, LaneMask] : *LiveSet) {
1082 assert(GCNRegPressure::getRegKind(Reg, MRI) == Kind);
1083 LiveInterval &LI = LIS.getInterval(Reg);
1084 if (LI.getNumValNums() == 1 ||
1085 (LI.hasSubRanges() &&
1086 llvm::all_of(LI.subranges(), [](const LiveInterval::SubRange &SR) {
1087 return SR.getNumValNums() == 1;
1088 }))) {
1089 SDefPressure.inc(Reg, LaneBitmask::getNone(), LaneMask, MRI);
1090 SDefRegs.push_back(Reg);
1091 } else {
1092 MDefPressure.inc(Reg, LaneBitmask::getNone(), LaneMask, MRI);
1093 MDefRegs.push_back(Reg);
1094 }
1095 }
1096 unsigned SDefNumRegs = SDefPressure.getNumRegs(Kind);
1097 unsigned MDefNumRegs = MDefPressure.getNumRegs(Kind);
1098 assert(SDefNumRegs + MDefNumRegs == MaxNumRegs);
1099
1100 auto printLoc = [&](const MachineBasicBlock *MBB, SlotIndex SI) {
1101 return Printable([&, MBB, SI](raw_ostream &OS) {
1102 OS << SI << ':' << printMBBReference(*MBB);
1103 if (MLI)
1104 if (const MachineLoop *ML = MLI->getLoopFor(MBB))
1105 OS << " (LoopHdr " << printMBBReference(*ML->getHeader())
1106 << ", Depth " << ML->getLoopDepth() << ")";
1107 });
1108 };
1109
1110 auto PrintRegInfo = [&](Register Reg, LaneBitmask LiveMask) {
1111 GCNRegPressure RegPressure;
1112 RegPressure.inc(Reg, LaneBitmask::getNone(), LiveMask, MRI);
1113 OS << " " << printReg(Reg, TRI) << ':'
1114 << TRI->getRegClassName(MRI.getRegClass(Reg)) << ", LiveMask "
1115 << PrintLaneMask(LiveMask) << " (" << RegPressure.getNumRegs(Kind) << ' '
1116 << RegName << "s)\n";
1117
1118 // Use std::map to sort def/uses by SlotIndex.
1119 std::map<SlotIndex, const MachineInstr *> Instrs;
1120 for (const MachineInstr &MI : MRI.reg_nodbg_instructions(Reg)) {
1121 Instrs[LIS.getInstructionIndex(MI).getRegSlot()] = &MI;
1122 }
1123
1124 for (const auto &[SI, MI] : Instrs) {
1125 OS << " ";
1126 if (MI->definesRegister(Reg, TRI))
1127 OS << "def ";
1128 if (MI->readsRegister(Reg, TRI))
1129 OS << "use ";
1130 OS << printLoc(MI->getParent(), SI) << ": " << *MI;
1131 }
1132 };
1133
1134 OS << "\n*** Register pressure info (" << RegName << "s) for " << MF.getName()
1135 << " ***\n";
1136 OS << "Max pressure is " << MaxNumRegs << ' ' << RegName << "s at "
1137 << printLoc(MaxPressureMI->getParent(), MaxPressureSlot) << ": "
1138 << *MaxPressureMI;
1139
1140 OS << "\nLive registers with single definition (" << SDefNumRegs << ' '
1141 << RegName << "s):\n";
1142
1143 // Sort SDefRegs by number of uses (smallest first)
1144 llvm::sort(SDefRegs, [&](Register A, Register B) {
1145 return std::distance(MRI.use_nodbg_begin(A), MRI.use_nodbg_end()) <
1146 std::distance(MRI.use_nodbg_begin(B), MRI.use_nodbg_end());
1147 });
1148
1149 for (const Register Reg : SDefRegs) {
1150 PrintRegInfo(Reg, LiveSet->lookup(Reg));
1151 }
1152
1153 OS << "\nLive registers with multiple definitions (" << MDefNumRegs << ' '
1154 << RegName << "s):\n";
1155 for (const Register Reg : MDefRegs) {
1156 PrintRegInfo(Reg, LiveSet->lookup(Reg));
1157 }
1158}
1159#endif
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:661
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 hasVectorRegisterExcess() const
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).
unsigned getNumRegsBenefit(const GCNRegPressure &SaveRP) const
Returns the benefit towards achieving the RP target that saving SaveRP represents,...
GCNRegPressure getPressure() const
const decltype(LiveRegs) & getLiveRegs() const
const MachineInstr * LastTrackedMI
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.
const Segment * getSegmentContaining(SlotIndex Idx) const
Return the segment that contains the specified index, or null if there is none.
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,...
use_nodbg_iterator use_nodbg_begin(Register RegNo) const
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
static use_nodbg_iterator use_nodbg_end()
iterator_range< use_nodbg_iterator > use_nodbg_operands(Register Reg) const
const TargetRegisterInfo * getTargetRegisterInfo() const
LLVM_ABI LaneBitmask getMaxLaneMaskForVReg(Register Reg) const
Returns a mask covering all bits that can appear in lane masks of subregisters of the virtual registe...
unsigned getNumVirtRegs() const
getNumVirtRegs - Return the number of virtual registers created.
iterator_range< reg_instr_nodbg_iterator > reg_nodbg_instructions(Register Reg) const
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: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:184
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...
LaneBitmask getSubRegIndexLaneMask(unsigned SubIdx) const
Return a bitmask representing the parts of a register that are covered by SubIdx.
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:1739
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:408
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1636
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
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
Definition MathExtras.h:394
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:1772
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:872
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 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
bool contains(SlotIndex I) const
Return true if the index is covered by this segment.