17#ifndef LLVM_LIB_TARGET_AMDGPU_GCNREGPRESSURE_H
18#define LLVM_LIB_TARGET_AMDGPU_GCNREGPRESSURE_H
27class MachineRegisterInfo;
49 if (UnifiedVGPRFile) {
67 return alignTo(NumArchVGPRs + NumAVGPRs,
87 unsigned DynamicVGPRBlockSize)
const {
88 return std::min(ST.getOccupancyWithNumSGPRs(
getSGPRNum()),
89 ST.getOccupancyWithNumVGPRs(
getVGPRNum(ST.hasGFX90AInsts()),
90 DynamicVGPRBlockSize));
99 unsigned DynamicVGPRBlockSize)
const {
101 O.getOccupancy(ST, DynamicVGPRBlockSize);
117 unsigned MaxOccupancy = std::numeric_limits<unsigned>::max())
const;
120 return std::equal(&
Value[0], &
Value[ValueArraySize], O.Value);
124 return !(*
this == O);
128 for (
unsigned I = 0;
I < ValueArraySize; ++
I)
134 for (
unsigned I = 0;
I < ValueArraySize; ++
I)
142 static constexpr unsigned ValueArraySize =
TOTAL_KINDS * 2;
146 unsigned Value[ValueArraySize];
155 unsigned DynamicVGPRBlockSize);
160 for (
unsigned I = 0;
I < GCNRegPressure::ValueArraySize; ++
I)
161 Res.Value[
I] = std::max(P1.Value[
I], P2.Value[
I]);
204 void setTarget(
unsigned NumSGPRs,
unsigned NumVGPRs);
222#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
224 OS <<
"Actual/Target: " <<
Target.RP.getSGPRNum() <<
'/' <<
Target.MaxSGPRs
225 <<
" SGPRs, " <<
Target.RP.getArchVGPRNum() <<
'/' <<
Target.MaxVGPRs
226 <<
" ArchVGPRs, " <<
Target.RP.getAGPRNum() <<
'/' <<
Target.MaxVGPRs
229 if (
Target.MaxUnifiedVGPRs) {
230 OS <<
", " <<
Target.RP.getVGPRNum(
true) <<
'/' <<
Target.MaxUnifiedVGPRs
231 <<
" VGPRs (unified)";
239 const bool UnifiedRF;
250 unsigned MaxUnifiedVGPRs;
253 : MF(MF), UnifiedRF(MF.getSubtarget<
GCNSubtarget>().hasGFX90AInsts()),
293 return std::move(LiveRegs);
298 const MachineRegisterInfo &
MRI);
316 reset(
MBB.getParent()->getRegInfo(),
382 bool UseInternalIterator =
true);
391 bool UseInternalIterator =
true);
423 const LiveIntervals &LIS,
424 const MachineRegisterInfo &
MRI,
428 const MachineRegisterInfo &
MRI,
432 const MachineRegisterInfo &
MRI);
439template <
typename Range>
440DenseMap<MachineInstr*, GCNRPTracker::LiveRegSet>
442 std::vector<SlotIndex> Indexes;
443 Indexes.reserve(std::distance(R.begin(), R.end()));
446 auto SI = SII.getInstructionIndex(*
I);
447 Indexes.push_back(After ? SI.getDeadSlot() : SI.getBaseIndex());
454 for (
unsigned I = 0,
E =
MRI.getNumVirtRegs();
I !=
E; ++
I) {
460 if (!LI.findIndexesLiveAt(Indexes, std::back_inserter(LiveIdxs)))
462 if (!LI.hasSubRanges()) {
463 for (
auto SI : LiveIdxs)
464 LiveRegMap[SII.getInstructionFromIndex(SI)][
Reg] =
465 MRI.getMaxLaneMaskForVReg(
Reg);
467 for (
const auto &S : LI.subranges()) {
470 S.findIndexesLiveAt(LiveIdxs, std::back_inserter(SRLiveIdxs));
471 for (
auto SI : SRLiveIdxs)
472 LiveRegMap[SII.getInstructionFromIndex(SI)][
Reg] |= S.LaneMask;
481 MI.getParent()->getParent()->getRegInfo());
487 MI.getParent()->getParent()->getRegInfo());
490template <
typename Range>
494 for (
const auto &RM : LiveRegs)
502Printable
print(
const GCNRegPressure &RP,
const GCNSubtarget *ST =
nullptr,
503 unsigned DynamicVGPRBlockSize = 0);
506 const MachineRegisterInfo &
MRI);
510 const TargetRegisterInfo *
TRI, StringRef Pfx =
" ");
unsigned const MachineRegisterInfo * MRI
static const Function * getParent(const Value *V)
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))
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
void setPreservesAll()
Set by analyses that do not transform their input at all.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
GCNRegPressure moveMaxPressure()
return MaxPressure and clear it.
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 ...
MachineBasicBlock::const_iterator getNext() const
GCNDownwardRPTracker(const LiveIntervals &LIS_)
bool reset(const MachineInstr &MI, const LiveRegSet *LiveRegs=nullptr)
Reset tracker to the point before the MI filling LiveRegs upon this point using LIS.
void advanceToNext(MachineInstr *MI=nullptr, bool UseInternalIterator=true)
Move to the state at the MI, advanceBeforeNext has to be called first.
Models a register pressure target, allowing to evaluate and track register savings against that targe...
bool isSaveBeneficial(Register Reg) const
Determines whether saving virtual register Reg will be beneficial towards achieving the RP target.
void saveReg(Register Reg, LaneBitmask Mask, const MachineRegisterInfo &MRI)
Saves virtual register Reg with lanemask Mask.
bool satisfied() const
Whether the current RP is at or below the defined pressure target.
void setRP(const GCNRegPressure &NewRP)
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)
GCNRegPressure getPressure() const
const decltype(LiveRegs) & getLiveRegs() const
const MachineInstr * LastTrackedMI
decltype(LiveRegs) moveLiveRegs()
GCNRegPressure CurPressure
DenseMap< unsigned, LaneBitmask > LiveRegSet
GCNRPTracker(const LiveIntervals &LIS_)
GCNRegPressure MaxPressure
void reset(const MachineInstr &MI, const LiveRegSet *LiveRegsCopy, bool After)
LaneBitmask getLastUsedLanes(Register RegUnit, SlotIndex Pos) const
Mostly copy/paste from CodeGen/RegisterPressure.cpp.
void bumpDeadDefs(ArrayRef< VRegMaskOrUnit > DeadDefs)
Mostly copy/paste from CodeGen/RegisterPressure.cpp.
const MachineInstr * getLastTrackedMI() const
const MachineRegisterInfo * MRI
const LiveIntervals & LIS
GCNUpwardRPTracker(const LiveIntervals &LIS_)
GCNRegPressure getMaxPressureAndReset()
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
void reset(const MachineBasicBlock &MBB)
reset tracker to the end of the MBB.
bool isValid() const
returns whether the tracker's state after receding MI corresponds to reported by LIS.
void reset(const MachineInstr &MI)
reset tracker to the point just after MI (in program order).
Module * getParent()
Get the module that this global value is contained inside of...
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.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
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.
SlotIndex getMBBEndIdx(unsigned Num) const
Returns the last index in the given basic block number.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
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.
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
LaneBitmask getLiveLaneMask(unsigned Reg, SlotIndex SI, const LiveIntervals &LIS, const MachineRegisterInfo &MRI, LaneBitmask LaneMaskFilter=LaneBitmask::getAll())
bool isEqual(const GCNRPTracker::LiveRegSet &S1, const GCNRPTracker::LiveRegSet &S2)
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
GCNRegPressure getRegPressure(const MachineRegisterInfo &MRI, Range &&LiveRegs)
GCNRPTracker::LiveRegSet getLiveRegs(SlotIndex SI, const LiveIntervals &LIS, const MachineRegisterInfo &MRI)
GCNRPTracker::LiveRegSet getLiveRegsAfter(const MachineInstr &MI, const LiveIntervals &LIS)
void sort(IteratorTy Start, IteratorTy End)
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
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)
Printable reportMismatch(const GCNRPTracker::LiveRegSet &LISLR, const GCNRPTracker::LiveRegSet &TrackedL, const TargetRegisterInfo *TRI, StringRef Pfx=" ")
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
bool operator!=(const GCNRegPressure &O) const
friend Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST, unsigned DynamicVGPRBlockSize)
GCNRegPressure & operator+=(const GCNRegPressure &RHS)
unsigned getVGPRTuplesWeight() const
GCNRegPressure & operator-=(const GCNRegPressure &RHS)
unsigned getVGPRNum(bool UnifiedVGPRFile) const
unsigned getOccupancy(const GCNSubtarget &ST, unsigned DynamicVGPRBlockSize) const
friend GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
void inc(unsigned Reg, LaneBitmask PrevMask, LaneBitmask NewMask, const MachineRegisterInfo &MRI)
bool higherOccupancy(const GCNSubtarget &ST, const GCNRegPressure &O, unsigned DynamicVGPRBlockSize) const
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()