22 #include "llvm/Config/llvm-config.h" 33 #define DEBUG_TYPE "machine-scheduler" 35 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 40 dbgs() <<
"Live regs at " << SI <<
": " 48 if (LI.hasSubRanges()) {
49 bool firstTime =
true;
50 for (
const auto &S : LI.subranges()) {
51 if (!S.liveAt(SI))
continue;
57 dbgs() <<
" " << S <<
'\n';
60 }
else if (LI.liveAt(SI)) {
61 dbgs() <<
" " << LI <<
'\n';
65 if (!Num)
dbgs() <<
" <none>\n";
73 for (
const auto &
P : S1) {
75 if (
I == S2.
end() ||
I->second !=
P.second)
85 unsigned GCNRegPressure::getRegKind(
unsigned Reg,
99 if (NewMask == PrevMask)
103 if (NewMask < PrevMask) {
110 switch (
auto Kind = getRegKind(Reg, MRI)) {
113 assert(PrevMask.
none() && NewMask == MaxMask);
119 assert(NewMask < MaxMask || NewMask == MaxMask);
120 assert(PrevMask < NewMask);
123 Sign * (~PrevMask & NewMask).getNumLanes();
125 if (PrevMask.
none()) {
137 unsigned MaxOccupancy)
const {
138 const auto SGPROcc = std::min(MaxOccupancy,
140 const auto VGPROcc = std::min(MaxOccupancy,
142 const auto OtherSGPROcc = std::min(MaxOccupancy,
144 const auto OtherVGPROcc = std::min(MaxOccupancy,
147 const auto Occ = std::min(SGPROcc, VGPROcc);
148 const auto OtherOcc = std::min(OtherSGPROcc, OtherVGPROcc);
150 return Occ > OtherOcc;
152 bool SGPRImportant = SGPROcc < VGPROcc;
153 const bool OtherSGPRImportant = OtherSGPROcc < OtherVGPROcc;
156 if (SGPRImportant != OtherSGPRImportant) {
157 SGPRImportant =
false;
161 bool SGPRFirst = SGPRImportant;
162 for (
int I = 2;
I > 0; --
I, SGPRFirst = !SGPRFirst) {
179 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 230 for (
const auto &MO : MI.
operands()) {
233 if (!MO.isUse() || !MO.readsReg())
238 auto Reg = MO.getReg();
240 return RM.RegUnit ==
Reg;
243 I->LaneMask |= UsedMask;
259 if (LI.hasSubRanges()) {
260 for (
const auto &S : LI.subranges())
262 LiveMask |= S.LaneMask;
266 }
else if (LI.liveAt(SI)) {
282 LiveRegs[Reg] = LiveMask;
293 if (&LiveRegs != LiveRegsCopy)
294 LiveRegs = *LiveRegsCopy;
309 assert(MRI &&
"call reset first");
319 auto AtMIPressure = CurPressure;
320 for (
const auto &U : RegUses) {
321 auto LiveMask = LiveRegs[U.RegUnit];
322 AtMIPressure.inc(U.RegUnit, LiveMask, LiveMask | U.LaneMask, *MRI);
325 MaxPressure =
max(AtMIPressure, MaxPressure);
327 for (
const auto &MO : MI.
defs()) {
332 auto Reg = MO.getReg();
333 auto I = LiveRegs.find(Reg);
334 if (
I == LiveRegs.end())
336 auto &LiveMask =
I->second;
337 auto PrevMask = LiveMask;
339 CurPressure.inc(Reg, PrevMask, LiveMask, *MRI);
343 for (
const auto &U : RegUses) {
344 auto &LiveMask = LiveRegs[U.RegUnit];
345 auto PrevMask = LiveMask;
346 LiveMask |= U.LaneMask;
347 CurPressure.inc(U.RegUnit, PrevMask, LiveMask, *MRI);
355 LastTrackedMI =
nullptr;
359 if (NextMI == MBBEnd)
366 assert(MRI &&
"call reset first");
369 if (NextMI == MBBEnd)
372 SlotIndex SI = LIS.getInstructionIndex(*NextMI).getBaseIndex();
376 for (
auto &It : LiveRegs) {
381 auto PrevMask = It.second;
382 It.second &= ~S.LaneMask;
383 CurPressure.inc(It.first, PrevMask, It.second, *MRI);
386 }
else if (!LI.
liveAt(SI)) {
387 auto PrevMask = It.second;
389 CurPressure.inc(It.first, PrevMask, It.second, *MRI);
391 if (It.second.none())
392 LiveRegs.erase(It.first);
395 MaxPressure =
max(MaxPressure, CurPressure);
401 LastTrackedMI = &*NextMI++;
404 for (
const auto &MO : LastTrackedMI->defs()) {
407 unsigned Reg = MO.getReg();
410 auto &LiveMask = LiveRegs[
Reg];
411 auto PrevMask = LiveMask;
413 CurPressure.inc(Reg, PrevMask, LiveMask, *MRI);
416 MaxPressure =
max(MaxPressure, CurPressure);
421 if ((NextMI == MBBEnd) || (LastTrackedMI && !advanceBeforeNext()))
428 while (NextMI != End)
429 if (!advance())
return false;
436 reset(*Begin, LiveRegsCopy);
440 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 445 for (
auto const &
P : TrackedLR) {
446 auto I = LISLR.
find(
P.first);
447 if (
I == LISLR.
end()) {
450 <<
" isn't found in LIS reported set\n";
452 else if (
I->second !=
P.second) {
454 <<
" masks doesn't match: LIS reported " 461 for (
auto const &
P : LISLR) {
462 auto I = TrackedLR.find(
P.first);
463 if (
I == TrackedLR.end()) {
466 <<
" isn't found in tracked set\n";
472 const auto &
SI = LIS.getInstructionIndex(*LastTrackedMI).getBaseIndex();
474 const auto &TrackedLR = LiveRegs;
476 if (!
isEqual(LISLR, TrackedLR)) {
477 dbgs() <<
"\nGCNUpwardRPTracker error: Tracked and" 478 " LIS reported livesets mismatch:\n";
485 if (LISPressure != CurPressure) {
486 dbgs() <<
"GCNUpwardRPTracker error: Pressure sets different\nTracked: ";
487 CurPressure.print(
dbgs());
488 dbgs() <<
"LIS rpt: ";
489 LISPressure.print(
dbgs());
500 auto It = LiveRegs.
find(Reg);
501 if (It != LiveRegs.
end() && It->second.any())
Interface definition for SIRegisterInfo.
A common definition of LaneBitmask for use in TableGen and CodeGen.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
AMDGPU specific subclass of TargetSubtarget.
const TargetRegisterClass * getRegClass(unsigned Reg) const
Return the register class of the specified virtual register.
static void printLiveRegs(raw_ostream &OS, const LiveRegSet &LiveRegs, const MachineRegisterInfo &MRI)
const MachineFunction * getMF() const
Return the function that contains the basic block that this instruction belongs to.
LaneBitmask getMaxLaneMaskForVReg(unsigned Reg) const
Returns a mask covering all bits that can appear in lane masks of subregisters of the virtual registe...
This class represents lattice values for constants.
static unsigned index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
unsigned getSGPRTuplesWeight() const
void push_back(const T &Elt)
LiveInterval - This class represents the liveness of a register, or stack slot.
bool reset(const MachineInstr &MI, const LiveRegSet *LiveRegs=nullptr)
unsigned getReg() const
getReg - Returns the register number.
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
GCNRPTracker::LiveRegSet getLiveRegs(SlotIndex SI, const LiveIntervals &LIS, const MachineRegisterInfo &MRI)
unsigned getSubReg() const
friend GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
bool isValid() const
Returns true if this is a valid index.
unsigned const TargetRegisterInfo * TRI
Printable PrintLaneMask(LaneBitmask LaneMask)
Create Printable object to print LaneBitmasks on a raw_ostream.
iterator_range< mop_iterator > operands()
static LaneBitmask getDefRegMask(const MachineOperand &MO, const MachineRegisterInfo &MRI)
Printable printReg(unsigned Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
iterator_range< subrange_iterator > subranges()
bool hasSubRanges() const
Returns true if subregister liveness information is available.
unsigned getOccupancy(const GCNSubtarget &ST) const
bool isSGPRClass(const TargetRegisterClass *RC) const
static constexpr LaneBitmask getNone()
MachineInstr * getInstructionFromIndex(SlotIndex index) const
Returns the instruction associated with the given index.
void inc(unsigned Reg, LaneBitmask PrevMask, LaneBitmask NewMask, const MachineRegisterInfo &MRI)
unsigned getVGPRTuplesWeight() const
GCNRPTracker::LiveRegSet getLiveRegsBefore(const MachineInstr &MI, const LiveIntervals &LIS)
bool less(const GCNSubtarget &ST, const GCNRegPressure &O, unsigned MaxOccupancy=std::numeric_limits< unsigned >::max()) const
static constexpr LaneBitmask getLane(unsigned Lane)
void reset(const MachineInstr &MI, const LiveRegSet *LiveRegs=nullptr)
iterator find(const_arg_type_t< KeyT > Val)
static bool isEqual(const GCNRPTracker::LiveRegSet &S1, const GCNRPTracker::LiveRegSet &S2)
const TargetRegisterInfo * getTargetRegisterInfo() const
unsigned const MachineRegisterInfo * MRI
bool hasInterval(unsigned Reg) const
bool liveAt(SlotIndex index) const
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
unsigned getSGPRNum() const
Printable printVRegOrUnit(unsigned VRegOrUnit, const TargetRegisterInfo *TRI)
Create Printable object to print virtual registers and physical registers on a raw_ostream.
constexpr bool none() const
iterator_range< mop_iterator > defs()
Returns a range over all explicit operands that are register definitions.
auto find_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range))
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly...
unsigned getNumVirtRegs() const
getNumVirtRegs - Return the number of virtual registers created.
GCNRPTracker::LiveRegSet getLiveRegsAfter(const MachineInstr &MI, const LiveIntervals &LIS)
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
bool isDebugInstr() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static SmallVector< RegisterMaskPair, 8 > collectVirtualRegUses(const MachineInstr &MI, const LiveIntervals &LIS, const MachineRegisterInfo &MRI)
static LLVM_DUMP_METHOD void reportMismatch(const GCNRPTracker::LiveRegSet &LISLR, const GCNRPTracker::LiveRegSet &TrackedLR, const TargetRegisterInfo *TRI)
void printLivesAt(SlotIndex SI, const LiveIntervals &LIS, const MachineRegisterInfo &MRI)
static LaneBitmask getUsedRegMask(const MachineOperand &MO, const MachineRegisterInfo &MRI, const LiveIntervals &LIS)
MachineOperand class - Representation of each machine instruction operand.
unsigned getVGPRNum() const
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
LaneBitmask getSubRegIndexLaneMask(unsigned SubIdx) const
Return a bitmask representing the parts of a register that are covered by SubIdx. ...
LiveInterval & getInterval(unsigned Reg)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
unsigned getOccupancyWithNumSGPRs(unsigned SGPRs) const
Return the maximum number of waves per SIMD for kernels using SGPRs SGPRs.
IterT skipDebugInstructionsForward(IterT It, IterT End)
Increment It until it points to a non-debug instruction or to End and return the resulting iterator...
SlotIndex getInstructionIndex(const MachineInstr &Instr) const
Returns the base index of the given instruction.
const MachineBasicBlock * getParent() const
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
GCNRegPressure getRegPressure(const MachineRegisterInfo &MRI, Range &&LiveRegs)
Representation of each machine instruction.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
PSetIterator getPressureSets(unsigned RegUnit) const
Get an iterator over the pressure sets affected by the given physical or virtual register.
constexpr bool any() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
LaneBitmask getLiveLaneMask(unsigned Reg, SlotIndex SI, const LiveIntervals &LIS, const MachineRegisterInfo &MRI)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void print(raw_ostream &OS, const GCNSubtarget *ST=nullptr) const
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream...
unsigned getWeight() const
unsigned getOccupancyWithNumVGPRs(unsigned VGPRs) const
Return the maximum number of waves per SIMD for kernels using VGPRs VGPRs.
SlotIndex - An opaque wrapper around machine indexes.
void recede(const MachineInstr &MI)
void reset(const MachineInstr &MI, const LiveRegSet *LiveRegsCopy, bool After)