17#ifndef LLVM_LIB_TARGET_AMDGPU_GCNREGPRESSURE_H
18#define LLVM_LIB_TARGET_AMDGPU_GCNREGPRESSURE_H
37 const char *Names[] = {
"SGPR",
"VGPR",
"AGPR",
"AVGPR"};
62 if (UnifiedVGPRFile) {
80 return alignTo(NumArchVGPRs + NumAVGPRs,
107 unsigned AccLimit)
const {
108 unsigned Arch = Value[
VGPR];
109 unsigned Acc = Value[
AGPR];
110 unsigned Flex = Value[
AVGPR];
111 unsigned ToArch = std::min(Flex, Arch < ArchLimit ? ArchLimit - Arch : 0);
113 unsigned ToAcc = std::min(Flex, Acc < AccLimit ? AccLimit - Acc : 0);
115 return {Arch + ToArch + Flex, Acc + ToAcc};
125 unsigned DynamicVGPRBlockSize)
const {
126 return std::min(ST.getOccupancyWithNumSGPRs(
getSGPRNum()),
127 ST.getOccupancyWithNumVGPRs(
getVGPRNum(ST.hasGFX90AInsts()),
128 DynamicVGPRBlockSize));
132 unsigned AGPRThreshold,
unsigned CombinedThreshold) {
134 if (!ST.hasGFX90AInsts())
140 unsigned ArchSpill = ArchPressure > ArchVGPRThreshold
141 ? (ArchPressure - ArchVGPRThreshold)
144 AGPRPressure > AGPRThreshold ? (AGPRPressure - AGPRThreshold) : 0;
147 unsigned UnifiedSpill = UnifiedPressure > CombinedThreshold
148 ? (UnifiedPressure - CombinedThreshold)
151 return std::max(UnifiedSpill, ArchSpill + AGPRSpill);
172 unsigned MaxOccupancy = std::numeric_limits<unsigned>::max())
const;
177 return !(*
this == O);
181 for (
unsigned I = 0;
I < ValueArraySize; ++
I)
182 Value[
I] +=
RHS.Value[
I];
187 for (
unsigned I = 0;
I < ValueArraySize; ++
I)
188 Value[
I] -=
RHS.Value[
I];
201 static constexpr unsigned ValueArraySize =
TOTAL_KINDS * 2;
205 std::array<unsigned, ValueArraySize>
Value;
214 unsigned DynamicVGPRBlockSize);
227 for (
unsigned I = 0;
I < GCNRegPressure::ValueArraySize; ++
I) {
232 P1.Value[
I] + P1.Value[AV] >= P2.Value[
I] + P2.Value[AV] ? P1 : P2;
233 Res.Value[
I] = From.Value[
I];
234 Res.Value[AV] = From.Value[AV];
241 Res.Value[
I] = std::max(P1.Value[
I], P2.Value[
I]);
286 void setTarget(
unsigned NumSGPRs,
unsigned NumVGPRs);
306 assert(!RP.less(MF, SaveRP) &&
"saving beyond current RP");
318 return UnifiedRF ? MaxUnifiedVGPRs : MaxVGPRs;
321#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
323 OS <<
"Actual/Target: " <<
Target.RP.getSGPRNum() <<
'/' <<
Target.MaxSGPRs
324 <<
" SGPRs, " <<
Target.RP.getArchVGPRNum() <<
'/' <<
Target.MaxVGPRs
325 <<
" ArchVGPRs, " <<
Target.RP.getAGPRNum() <<
'/' <<
Target.MaxVGPRs
328 if (
Target.MaxUnifiedVGPRs) {
329 OS <<
", " <<
Target.RP.getVGPRNum(
true) <<
'/' <<
Target.MaxUnifiedVGPRs
330 <<
" VGPRs (unified)";
338 const bool UnifiedRF;
344 unsigned MaxSGPRs = 0;
346 unsigned MaxVGPRs = 0;
349 unsigned MaxUnifiedVGPRs = 0;
352 : MF(MF), UnifiedRF(MF.getSubtarget<
GCNSubtarget>().hasGFX90AInsts()),
425 const MachineRegisterInfo &
MRI,
571 const LiveIntervals &LIS,
572 const MachineRegisterInfo &
MRI,
576 const MachineRegisterInfo &
MRI,
584template <
typename Range>
585DenseMap<MachineInstr*, GCNRPTracker::LiveRegSet>
587 std::vector<SlotIndex> Indexes;
591 auto SI = SII.getInstructionIndex(*
I);
592 Indexes.push_back(After ?
SI.getDeadSlot() :
SI.getBaseIndex());
596 auto &
MRI = (*R.begin())->getMF()->getRegInfo();
599 for (
unsigned I = 0,
E =
MRI.getNumVirtRegs();
I !=
E; ++
I) {
605 if (!LI.findIndexesLiveAt(Indexes, std::back_inserter(LiveIdxs)))
607 if (!LI.hasSubRanges()) {
608 for (
auto SI : LiveIdxs)
609 LiveRegMap[SII.getInstructionFromIndex(
SI)][
Reg] =
610 MRI.getMaxLaneMaskForVReg(
Reg);
612 for (
const auto &S : LI.subranges()) {
615 S.findIndexesLiveAt(LiveIdxs, std::back_inserter(SRLiveIdxs));
616 for (
auto SI : SRLiveIdxs)
617 LiveRegMap[SII.getInstructionFromIndex(
SI)][
Reg] |= S.LaneMask;
626 MI.getMF()->getRegInfo());
632 MI.getMF()->getRegInfo());
635template <
typename Range>
647Printable
print(
const GCNRegPressure &RP,
const GCNSubtarget *ST =
nullptr,
648 unsigned DynamicVGPRBlockSize = 0);
651 const MachineRegisterInfo &
MRI);
655 const TargetRegisterInfo *
TRI, StringRef Pfx =
" ");
675 const MachineLoopInfo *MLI);
687 const MachineRegisterInfo &
MRI,
const SIRegisterInfo &
TRI);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
AMD GCN specific subclass of TargetSubtarget.
Register const TargetRegisterInfo * TRI
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
StandardInstrumentations SI(Mod->getContext(), Debug, VerifyEach)
MachineRegisterInfo & MRI
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
void setPreservesAll()
Set by analyses that do not transform their input at all.
void retireDeadDefs(const MachineInstr &MI, SlotIndex SI)
Retires the lanes defined by MI that are dead at SI, according to LIS.
GCNDownwardRPTrackerBase(LiveIntervals &LIS)
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 retireDeadUses(const MachineInstr &MI)
Retires the lanes of MI's used registers that die at MI, mirroring RegPressureTracker::advance().
void addDefs(const MachineInstr &MI)
Adds all lanes (dead or not) defined by MI's register operands to CurPressure.
bool advance()
Advance to the state at the next MI in program order.
GCNRegPressure moveMaxPressure()
return MaxPressure and clear it.
GCNDownwardRPTracker(LiveIntervals &LIS)
MachineBasicBlock::const_iterator getNext() const
Returns the next MI that will be advanced over.
void advanceToNext()
Move to the state at NextMI.
bool advanceBeforeNext()
Move to the state right before NextMI or the end of the MBB.
bool reset(const MachineInstr &MI, MachineBasicBlock::const_iterator End, const LiveRegSet *LiveRegsCopy=nullptr)
Reset tracker to the point before the MI (filling LiveRegs upon this point using LiveRegsCopy if prov...
GCNManualDownwardRPTracker(LiveIntervals &LIS)
void advance(const MachineInstr &MI)
Advances to the state after MI.
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 ...
unsigned getMaxVGPRs() const
bool isSaveBeneficial(Register Reg) const
Determines whether saving virtual register Reg will be beneficial towards achieving the RP target.
bool hasVectorRegisterExcess() const
void setRP(const GCNRegPressure &NewRP)
bool satisfied() const
Whether the current RP is at or below the defined pressure target.
unsigned getMaxSGPRs() const
const GCNRegPressure & getCurrentRP() const
void setTarget(unsigned NumSGPRs, unsigned NumVGPRs)
Changes the target (same semantics as constructor).
friend raw_ostream & operator<<(raw_ostream &OS, const GCNRPTarget &Target)
void saveRP(const GCNRegPressure &SaveRP)
Saves a total pressure of SaveRP.
unsigned getNumRegsBenefit(const GCNRegPressure &SaveRP) const
Returns the benefit towards achieving the RP target that saving SaveRP represents,...
const GCNRegPressure & getMaxPressure() const
GCNRegPressure getPressure() const
const decltype(LiveRegs) & getLiveRegs() const
decltype(LiveRegs) moveLiveRegs()
GCNRegPressure CurPressure
GCNRPTracker(LiveIntervals &LIS_)
DenseMap< unsigned, LaneBitmask > LiveRegSet
std::function< void(const GCNRegPressure &)> PressureCallback
MachineBasicBlock::const_iterator LastTrackedMI
LaneBitmask getLastUsedLanes(Register Reg, SlotIndex Pos) const
Mostly copy/paste from CodeGen/RegisterPressure.cpp.
void updateMaxPressure(const GCNRegPressure &RP)
Folds the pressure RP of one program point into MaxPressure and passes it to the pressure callback.
GCNRegPressure MaxPressure
const MachineInstr * getLastTrackedMI() const
const MachineRegisterInfo * MRI
void setPressureCallback(std::function< void(const GCNRegPressure &)> CB)
Sets a function that the tracker calls with the pressure of every program point that it folds into th...
void reset(const MachineInstr &MI, bool After)
Resets tracker before or After the provided MI, which can be a debug instruction.
GCNRegPressure getMaxPressureAndReset()
GCNUpwardRPTracker(LiveIntervals &LIS_)
void recede(const MachineInstr &MI)
Move to the state of RP just before the MI.
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.
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)
A set of live virtual registers and physical register units.
MachineInstrBundleIterator< const MachineInstr > const_iterator
MachineFunctionPass(char &ID)
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Representation of each machine instruction.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Simple wrapper around std::function<void(raw_ostream&)>.
Wrapper class representing virtual and physical registers.
static Register index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
SlotIndex - An opaque wrapper around machine indexes.
SlotIndex getDeadSlot() const
Returns the dead def kill slot for the current instruction.
SlotIndex getBaseIndex() const
Returns the base index for associated with this index.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Target - Wrapper for Target specific information.
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream.
unsigned getArchVGPRAllocGranule()
For subtargets with a unified VGPR file and mixed ArchVGPR/AGPR usage, returns the allocation granule...
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 isEqual(const GCNRPTracker::LiveRegSet &S1, const GCNRPTracker::LiveRegSet &S2)
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
GCNRPTracker::LiveRegSet getLiveRegs(SlotIndex SI, const LiveIntervals &LIS, const MachineRegisterInfo &MRI, GCNRegPressure::RegKind RegKind=GCNRegPressure::TOTAL_KINDS)
GCNRegPressure getRegPressure(const MachineRegisterInfo &MRI, Range &&LiveRegs)
GCNRPTracker::LiveRegSet getLiveRegsAfter(const MachineInstr &MI, const LiveIntervals &LIS)
void sort(IteratorTy Start, IteratorTy End)
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
GCNRegPressure maxPerRegFile(const GCNRegPressure &P1, const GCNRegPressure &P2)
DenseMap< MachineInstr *, GCNRPTracker::LiveRegSet > getLiveRegMap(Range &&R, bool After, LiveIntervals &LIS)
creates a map MachineInstr -> LiveRegSet R - range of iterators on instructions After - upon entry or...
APInt operator+(APInt a, const APInt &b)
GCNRPTracker::LiveRegSet getLiveRegsBefore(const MachineInstr &MI, const LiveIntervals &LIS)
LLVM_ABI void dumpMaxRegPressure(MachineFunction &MF, GCNRegPressure::RegKind Kind, LiveIntervals &LIS, const MachineLoopInfo *MLI)
@ End
Run the machine verifier once, at the end of the pipeline.
unsigned estimateGreedyVGPRPressure(MachineBasicBlock::const_iterator RegionBegin, MachineBasicBlock::const_iterator RegionEnd, const GCNRPTracker::LiveRegSet &LiveIns, const LiveIntervals &LIS, const MachineRegisterInfo &MRI, const SIRegisterInfo &TRI)
Estimate VGPR pressure using greedy, non-splitting register allocation simulation,...
Printable reportMismatch(const GCNRPTracker::LiveRegSet &LISLR, const GCNRPTracker::LiveRegSet &TrackedL, const TargetRegisterInfo *TRI, StringRef Pfx=" ")
MCRegisterClass TargetRegisterClass
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
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)
bool operator!=(const GCNRegPressure &O) const
std::pair< unsigned, unsigned > getBankedVGPRNum(unsigned ArchLimit, unsigned AccLimit) const
GCNRegPressure & operator+=(const GCNRegPressure &RHS)
friend GCNRegPressure maxPerRegFile(const GCNRegPressure &P1, const GCNRegPressure &P2)
unsigned getNumRegs(RegKind Kind) const
unsigned getVGPRTuplesWeight() const
GCNRegPressure & operator-=(const GCNRegPressure &RHS)
unsigned getVGPRSpills(MachineFunction &MF, unsigned ArchVGPRThreshold, unsigned AGPRThreshold, unsigned CombinedThreshold)
unsigned getVGPRNum(bool UnifiedVGPRFile) const
friend Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST, unsigned DynamicVGPRBlockSize)
unsigned getOccupancy(const GCNSubtarget &ST, unsigned DynamicVGPRBlockSize) const
void inc(unsigned Reg, LaneBitmask PrevMask, LaneBitmask NewMask, const MachineRegisterInfo &MRI)
static unsigned getBankedUnifiedVGPRNum(unsigned NumArchVGPRs, unsigned NumAGPRs)
Returns the aggregated VGPR pressure for NumArchVGPRs ArchVGPRs and NumAGPRs AGPRs,...
unsigned getArchVGPRNum() const
unsigned getAGPRNum() const
unsigned getSGPRNum() const
unsigned getSGPRTuplesWeight() const
bool operator==(const GCNRegPressure &O) const
static unsigned getUnifiedVGPRNum(unsigned NumArchVGPRs, unsigned NumAGPRs, unsigned NumAVGPRs)
Returns the aggregated VGPR pressure, assuming NumArchVGPRs ArchVGPRs NumAGPRs AGPRS,...
unsigned getAVGPRNum() 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()
static constexpr LaneBitmask getNone()