23#define DEBUG_TYPE "machine-scheduler"
27 if (
S1.size() != S2.
size())
30 for (
const auto &
P :
S1) {
32 if (
I == S2.
end() ||
I->second !=
P.second)
56 if (NewNumCoveredRegs == PrevNumCoveredRegs)
60 if (NewMask < PrevMask) {
62 std::swap(NewNumCoveredRegs, PrevNumCoveredRegs);
65 assert(PrevMask < NewMask && PrevNumCoveredRegs < NewNumCoveredRegs &&
66 "prev mask should always be lesser than new");
72 if (
TRI->getRegSizeInBits(*RC) != 32) {
74 if (PrevMask.
none()) {
76 Value[TupleIdx] += Sign *
TRI->getRegClassWeight(RC).RegWeight;
96 Sign *= NewNumCoveredRegs - PrevNumCoveredRegs;
105 unsigned ArchVGPR = 0;
108 bool anyExcess()
const {
return SGPR || VGPR || ArchVGPR || AGPR; }
109 bool hasVectorRegisterExcess()
const {
return VGPR || ArchVGPR || AGPR; }
111 RegExcess(
const MachineFunction &MF,
const GCNRegPressure &RP)
112 : RegExcess(MF,
RP, GCNRPTarget(MF,
RP)) {}
113 RegExcess(
const MachineFunction &MF,
const GCNRegPressure &RP,
114 const GCNRPTarget &Target) {
115 unsigned MaxSGPRs =
Target.getMaxSGPRs();
116 unsigned MaxVGPRs =
Target.getMaxVGPRs();
119 SGPR = std::max(
static_cast<int>(
RP.getSGPRNum() - MaxSGPRs), 0);
122 unsigned WaveSize =
ST.getWavefrontSize();
123 unsigned VGPRForSGPRSpills =
divideCeil(SGPR, WaveSize);
125 unsigned MaxArchVGPRs =
ST.getAddressableNumArchVGPRs();
129 VGPR = std::max(
static_cast<int>(
RP.getVGPRNum(
ST.hasGFX90AInsts()) +
130 VGPRForSGPRSpills - MaxVGPRs),
133 unsigned ArchVGPRLimit =
ST.hasGFX90AInsts() ? MaxArchVGPRs : MaxVGPRs;
136 ArchVGPR = std::max(
static_cast<int>(
RP.getArchVGPRNum() +
137 VGPRForSGPRSpills - ArchVGPRLimit),
141 AGPR = std::max(
static_cast<int>(
RP.getAGPRNum() - ArchVGPRLimit), 0);
147 unsigned MaxOccupancy)
const {
149 unsigned DynamicVGPRBlockSize =
152 const auto SGPROcc = std::min(MaxOccupancy,
154 const auto VGPROcc = std::min(
155 MaxOccupancy, ST.getOccupancyWithNumVGPRs(
getVGPRNum(ST.hasGFX90AInsts()),
156 DynamicVGPRBlockSize));
157 const auto OtherSGPROcc = std::min(MaxOccupancy,
158 ST.getOccupancyWithNumSGPRs(O.getSGPRNum()));
159 const auto OtherVGPROcc =
160 std::min(MaxOccupancy,
161 ST.getOccupancyWithNumVGPRs(O.getVGPRNum(ST.hasGFX90AInsts()),
162 DynamicVGPRBlockSize));
164 const auto Occ = std::min(SGPROcc, VGPROcc);
165 const auto OtherOcc = std::min(OtherSGPROcc, OtherVGPROcc);
169 return Occ > OtherOcc;
171 unsigned MaxVGPRs = ST.getMaxNumVGPRs(MF);
173 RegExcess Excess(MF, *
this);
174 RegExcess OtherExcess(MF, O);
176 unsigned MaxArchVGPRs = ST.getAddressableNumArchVGPRs();
178 bool ExcessRP = Excess.anyExcess();
179 bool OtherExcessRP = OtherExcess.anyExcess();
183 if (ExcessRP || OtherExcessRP) {
187 ((OtherExcess.VGPR + OtherExcess.ArchVGPR + OtherExcess.AGPR) -
188 (Excess.VGPR + Excess.ArchVGPR + Excess.AGPR));
190 int SGPRDiff = OtherExcess.SGPR - Excess.SGPR;
195 unsigned PureExcessVGPR =
196 std::max(
static_cast<int>(
getVGPRNum(ST.hasGFX90AInsts()) - MaxVGPRs),
198 std::max(
static_cast<int>(
getVGPRNum(
false) - MaxArchVGPRs), 0);
199 unsigned OtherPureExcessVGPR =
201 static_cast<int>(O.getVGPRNum(ST.hasGFX90AInsts()) - MaxVGPRs),
203 std::max(
static_cast<int>(O.getVGPRNum(
false) - MaxArchVGPRs), 0);
208 if (PureExcessVGPR != OtherPureExcessVGPR)
216 bool SGPRImportant = SGPROcc < VGPROcc;
217 const bool OtherSGPRImportant = OtherSGPROcc < OtherVGPROcc;
220 if (SGPRImportant != OtherSGPRImportant) {
221 SGPRImportant =
false;
225 bool SGPRFirst = SGPRImportant;
226 for (
int I = 2;
I > 0; --
I, SGPRFirst = !SGPRFirst) {
229 auto OtherSW = O.getSGPRTuplesWeight();
234 auto OtherVW = O.getVGPRTuplesWeight();
241 return SGPRImportant ? (
getSGPRNum() < O.getSGPRNum()):
243 O.getVGPRNum(ST.hasGFX90AInsts()));
247 unsigned DynamicVGPRBlockSize) {
249 OS <<
"VGPRs: " << RP.getArchVGPRNum() <<
' '
250 <<
"AGPRs: " << RP.getAGPRNum();
253 << ST->getOccupancyWithNumVGPRs(RP.getVGPRNum(ST->hasGFX90AInsts()),
254 DynamicVGPRBlockSize)
256 OS <<
", SGPRs: " << RP.getSGPRNum();
258 OS <<
"(O" << ST->getOccupancyWithNumSGPRs(RP.getSGPRNum()) <<
')';
259 OS <<
", LVGPR WT: " << RP.getVGPRTuplesWeight()
260 <<
", LSGPR WT: " << RP.getSGPRTuplesWeight();
262 OS <<
" -> Occ: " << RP.getOccupancy(*ST, DynamicVGPRBlockSize);
285 for (
const auto &MO :
MI.operands()) {
286 if (!MO.isReg() || !MO.getReg().isVirtual())
288 if (!MO.isUse() || !MO.readsReg())
293 return RM.VRegOrUnit.asVirtualReg() ==
Reg;
296 auto &
P =
I == VRegMaskOrUnits.
end()
301 P.LaneMask |= MO.getSubReg() ?
TRI.getSubRegIndexLaneMask(MO.getSubReg())
306 for (
auto &
P : VRegMaskOrUnits) {
307 auto &LI = LIS.
getInterval(
P.VRegOrUnit.asVirtualReg());
308 if (!LI.hasSubRanges())
331 if (Property(SR, Pos))
332 Result |= SR.LaneMask;
334 }
else if (Property(LI, Pos)) {
351 bool Upward =
false) {
356 SlotIndex InstSlot =
LIS->getInstructionIndex(*MI).getRegSlot();
357 bool InRange = Upward ? (InstSlot > PriorUseIdx && InstSlot <= NextUseIdx)
358 : (InstSlot >= PriorUseIdx && InstSlot < NextUseIdx);
362 unsigned SubRegIdx = MO.getSubReg();
364 LastUseMask &= ~UseMask;
365 if (LastUseMask.
none())
378 setTarget(ST.getMaxNumSGPRs(
F), ST.getMaxNumVGPRs(
F));
391 unsigned DynamicVGPRBlockSize =
393 setTarget(ST.getMaxNumSGPRs(Occupancy,
false),
394 ST.getMaxNumVGPRs(Occupancy, DynamicVGPRBlockSize));
399 MaxSGPRs = std::min(ST.getAddressableNumSGPRs(), NumSGPRs);
400 MaxVGPRs = std::min(ST.getAddressableNumArchVGPRs(), NumVGPRs);
402 unsigned DynamicVGPRBlockSize =
405 std::min(ST.getAddressableNumVGPRs(DynamicVGPRBlockSize), NumVGPRs);
417 RegExcess Excess(MF, RP, *
this);
423 return (UnifiedRF && Excess.VGPR) || Excess.AGPR;
425 return (UnifiedRF && Excess.VGPR) || Excess.ArchVGPR;
429 RegExcess Excess(MF, RP, *
this);
430 if (SaveRP.
getSGPRNum() != 0 && Excess.SGPR != 0)
434 if (SaveRP.
getAGPRNum() != 0 && Excess.AGPR != 0)
436 if (UnifiedRF && Excess.VGPR != 0)
442 RegExcess Excess(MF, RP, *
this);
443 const unsigned NumVGPRAboveAddrLimit =
446 unsigned NumRegsSaved =
447 std::min(Excess.SGPR, SaveRP.
getSGPRNum()) + NumVGPRAboveAddrLimit;
449 if (UnifiedRF && Excess.VGPR) {
458 if (NumVGPRAboveAddrLimit < VGPRSave)
459 NumRegsSaved += std::min(Excess.VGPR, VGPRSave - NumVGPRAboveAddrLimit);
468 if (UnifiedRF && TestRP.
getVGPRNum(
true) > MaxUnifiedVGPRs)
474 RegExcess Excess(MF, RP, *
this);
475 return Excess.hasVectorRegisterExcess();
494 if ((S.LaneMask & LaneMaskFilter).any() && S.liveAt(
SI)) {
495 LiveMask |= S.LaneMask;
501 LiveMask &= LaneMaskFilter;
526 if (!
MI.isDebugInstr()) {
529 SI =
SI.getDeadSlot();
536 MBBEnd =
MI.getParent()->end();
539 if (NonDbgMI == MBBEnd) {
554 :
LIS.getMBBStartIdx(&
MBB);
579 const LiveRange::Segment *S = LR.getSegmentContaining(Pos);
580 return S != nullptr && S->end == Pos.getRegSlot();
592 if (
MI.isDebugInstr())
597 bool HasECDefs =
false;
599 if (!MO.getReg().isVirtual())
606 if (MO.isEarlyClobber()) {
618 LiveMask &= ~DefMask;
627 DefPressure += ECDefPressure;
636 LiveMask |= U.LaneMask;
637 CurPressure.inc(U.VRegOrUnit.asVirtualReg(), PrevMask, LiveMask, *
MRI);
653 MBBEnd =
MI.getParent()->end();
655 End->getParent()->end() == MBBEnd &&
"end unrelated to MI block");
665 else if (NextMI != MBBEnd)
669 return NextMI != End;
673 bool UseInternalIterator) {
677 if (UseInternalIterator) {
679 return NextMI == MBBEnd;
681 assert(NextMI == MBBEnd || !NextMI->isDebugInstr());
684 SI = NextMI == MBBEnd
685 ?
LIS.getInstructionIndex(*LastTrackedMI).getDeadSlot()
686 :
LIS.getInstructionIndex(*NextMI).getBaseIndex();
688 SI =
LIS.getInstructionIndex(*MI).getBaseIndex();
696 for (
auto &MO : CurrMI->
operands()) {
697 if (!MO.isReg() || !MO.getReg().isVirtual())
699 if (MO.isUse() && !MO.readsReg())
701 if (!UseInternalIterator && MO.isDef())
703 if (!SeenRegs.
insert(MO.getReg()).second)
715 auto PrevMask = It->second;
716 It->second &= ~S.LaneMask;
720 if (It !=
LiveRegs.end() && It->second.none())
723 auto It =
LiveRegs.find(MO.getReg());
735 return UseInternalIterator && (NextMI == MBBEnd);
739 bool UseInternalIterator) {
740 if (UseInternalIterator) {
750 for (
const auto &MO : CurrMI->
all_defs()) {
752 if (!Reg.isVirtual())
755 auto PrevMask = LiveMask;
764 if (UseInternalIterator && NextMI == MBBEnd)
769 if (!UseInternalIterator) {
777 bool AnyAdvance =
false;
778 while (NextMI != End &&
advance())
786 if (!
reset(*Begin, End, LiveRegsCopy))
795 for (
auto const &
P : TrackedLR) {
796 auto I = LISLR.
find(
P.first);
797 if (
I == LISLR.
end()) {
799 <<
" isn't found in LIS reported set\n";
800 }
else if (
I->second !=
P.second) {
802 <<
" masks doesn't match: LIS reported " <<
PrintLaneMask(
I->second)
806 for (
auto const &
P : LISLR) {
807 auto I = TrackedLR.find(
P.first);
808 if (
I == TrackedLR.end()) {
810 <<
" isn't found in tracked set\n";
819 assert(!
MI->isDebugOrPseudoInstr() &&
"Expect a nondebug instruction.");
822 SlotIdx =
LIS.getInstructionIndex(*MI).getRegSlot();
831 if (!
Use.VRegOrUnit.isVirtualReg())
835 if (LastUseMask.
none())
846 if (IdxPos ==
MBB->end()) {
847 CurrIdx =
LIS.getMBBEndIdx(
MBB);
849 CurrIdx =
LIS.getInstructionIndex(*IdxPos).getRegSlot();
854 if (LastUseMask.
none())
860 TempPressure.
inc(Reg, LiveMask, NewMask, *
MRI);
865 if (!Def.VRegOrUnit.isVirtualReg())
867 Register Reg = Def.VRegOrUnit.asVirtualReg();
871 TempPressure.
inc(Reg, LiveMask, NewMask, *
MRI);
878 const auto &
SI =
LIS.getInstructionIndex(*LastTrackedMI).getBaseIndex();
882 if (!
isEqual(LISLR, TrackedLR)) {
883 dbgs() <<
"\nGCNUpwardRPTracker error: Tracked and"
884 " LIS reported livesets mismatch:\n"
892 dbgs() <<
"GCNUpwardRPTracker error: Pressure sets different\nTracked: "
906 if (It !=
LiveRegs.end() && It->second.any())
916 "amdgpu-print-rp-downward",
917 cl::desc(
"Use GCNDownwardRPTracker for GCNRegPressurePrinter pass"),
932 auto IsInOneSegment = [Begin, End](
const LiveRange &LR) ->
bool {
934 return Segment && Segment->
contains(End);
940 for (auto &SR : LI.subranges()) {
941 if ((SR.LaneMask & Mask) == SR.LaneMask && IsInOneSegment(SR))
942 LiveThroughMask |= SR.LaneMask;
946 if ((RegMask & Mask) == RegMask && IsInOneSegment(LI))
947 LiveThroughMask = RegMask;
950 return LiveThroughMask;
963 OS <<
"---\nname: " << MF.
getName() <<
"\nbody: |\n";
967 OS <<
format(
PFX " %-5d", RP.getSGPRNum())
968 <<
format(
" %-5d", RP.getVGPRNum(
false));
974 if (LISLR != TrackedLR) {
983 for (
auto &
MBB : MF) {
985 RP.reserve(
MBB.size());
999 LiveIn = LiveOut =
getLiveRegs(MBBStartSlot, LIS, MRI);
1018 RPT.
reset(MRI, MBBLastSlot);
1026 if (!
MI.isDebugInstr())
1035 ReportLISMismatchIfAny(LiveIn,
getLiveRegs(MBBStartSlot, LIS, MRI));
1037 OS <<
PFX " SGPR VGPR\n";
1039 for (
auto &
MI :
MBB) {
1040 if (!
MI.isDebugInstr()) {
1041 auto &[RPBeforeInstr, RPAtInstr] =
1044 OS << printRP(RPBeforeInstr) <<
'\n' << printRP(RPAtInstr) <<
" ";
1049 OS << printRP(RPAtMBBEnd) <<
'\n';
1053 ReportLISMismatchIfAny(LiveOut,
getLiveRegs(MBBLastSlot, LIS, MRI));
1056 for (
auto [Reg, Mask] : LiveIn) {
1058 if (MaskIntersection.
any()) {
1060 MRI, LIS, Reg, MBBStartSlot, MBBLastSlot, MaskIntersection);
1062 LiveThrough[Reg] = LTMask;
1074#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1085 unsigned MaxNumRegs = 0;
1093 if (NumRegs > MaxNumRegs) {
1094 MaxNumRegs = NumRegs;
1095 MaxPressureMI = &
MI;
1112 ECNumRegs > RNumRegs ? &ECLiveSet : &RLiveSet;
1113 SlotIndex MaxPressureSlot = ECNumRegs > RNumRegs ? ECSlot : RSlot;
1119 for (
auto [Reg, LaneMask] : *LiveSet) {
1125 return SR.getNumValNums() == 1;
1134 unsigned SDefNumRegs = SDefPressure.
getNumRegs(Kind);
1135 unsigned MDefNumRegs = MDefPressure.
getNumRegs(Kind);
1136 assert(SDefNumRegs + MDefNumRegs == MaxNumRegs);
1144 <<
", Depth " <<
ML->getLoopDepth() <<
")";
1153 <<
PrintLaneMask(LiveMask) <<
" (" << RegPressure.getNumRegs(Kind) <<
' '
1157 std::map<SlotIndex, const MachineInstr *> Instrs;
1162 for (
const auto &[
SI,
MI] : Instrs) {
1164 if (
MI->definesRegister(Reg,
TRI))
1166 if (
MI->readsRegister(Reg,
TRI))
1168 OS << printLoc(
MI->getParent(),
SI) <<
": " << *
MI;
1172 OS <<
"\n*** Register pressure info (" <<
RegName <<
"s) for " << MF.
getName()
1174 OS <<
"Max pressure is " << MaxNumRegs <<
' ' <<
RegName <<
"s at "
1175 << printLoc(MaxPressureMI->
getParent(), MaxPressureSlot) <<
": "
1178 OS <<
"\nLive registers with single definition (" << SDefNumRegs <<
' '
1187 for (
const Register Reg : SDefRegs) {
1188 PrintRegInfo(Reg, LiveSet->
lookup(Reg));
1191 OS <<
"\nLive registers with multiple definitions (" << MDefNumRegs <<
' '
1193 for (
const Register Reg : MDefRegs) {
1194 PrintRegInfo(Reg, LiveSet->
lookup(Reg));
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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.
static void collectVirtualRegUses(SmallVectorImpl< VRegMaskOrUnit > &VRegMaskOrUnits, const MachineInstr &MI, const LiveIntervals &LIS, const MachineRegisterInfo &MRI)
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...
Register const TargetRegisterInfo * TRI
static bool InRange(int64_t Value, unsigned short Shift, int LBound, int HBound)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
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
Return the entry for the specified key, or a default constructed value if no such entry exists.
iterator find(const_arg_type_t< KeyT > Val)
bool reset(const MachineInstr &MI, MachineBasicBlock::const_iterator End, const LiveRegSet *LiveRegs=nullptr)
Reset tracker to the point before the MI filling LiveRegs upon this point using LIS.
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 ...
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
const MachineRegisterInfo * MRI
const LiveIntervals & LIS
void reset(const MachineInstr &MI, bool After)
Resets tracker before or After the provided MI, which can be a debug instruction.
void recede(const MachineInstr &MI)
Move to the state of RP just before the MI .
const GCNRegPressure & getMaxPressure() const
bool isValid() const
returns whether the tracker's state after receding MI corresponds to reported by LIS.
void reset(const MachineInstr &MI)
Resets tracker to the point just after MI (in program order), which can be a debug instruction.
A live range for subregisters.
LiveInterval - This class represents the liveness of a register, or stack slot.
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.
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()
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&)>.
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.
static Register index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
This class keeps track of the SPI_SP_INPUT_ADDR config register, which tells the hardware which inter...
unsigned getDynamicVGPRBlockSize() const
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.
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...
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
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.
Represent a constant reference to a string, i.e.
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.
Wrapper class representing a virtual register or register unit.
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.
#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.
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.
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.
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.
auto reverse(ContainerTy &&C)
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
constexpr NextUseDistance max(NextUseDistance A, NextUseDistance B)
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.
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.
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()
constexpr bool none() const
constexpr bool any() const
static constexpr LaneBitmask getNone()
bool contains(SlotIndex I) const
Return true if the index is covered by this segment.