Go to the documentation of this file.
19 #define DEBUG_TYPE "machine-scheduler"
21 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
26 dbgs() <<
"Live regs at " <<
SI <<
": "
34 if (LI.hasSubRanges()) {
35 bool firstTime =
true;
36 for (
const auto &
S : LI.subranges()) {
37 if (!
S.liveAt(
SI))
continue;
43 dbgs() <<
" " <<
S <<
'\n';
46 }
else if (LI.liveAt(
SI)) {
47 dbgs() <<
" " << LI <<
'\n';
51 if (!Num)
dbgs() <<
" <none>\n";
60 for (
const auto &
P : S1) {
62 if (
I == S2.
end() ||
I->second !=
P.second)
79 : STI->isAGPRClass(RC)
93 if (NewMask < PrevMask) {
108 assert(PrevMask < NewMask);
113 if (PrevMask.
none()) {
125 unsigned MaxOccupancy)
const {
126 const auto SGPROcc =
std::min(MaxOccupancy,
131 const auto OtherSGPROcc =
std::min(MaxOccupancy,
132 ST.getOccupancyWithNumSGPRs(
O.getSGPRNum()));
133 const auto OtherVGPROcc =
135 ST.getOccupancyWithNumVGPRs(
O.getVGPRNum(
ST.hasGFX90AInsts())));
137 const auto Occ =
std::min(SGPROcc, VGPROcc);
138 const auto OtherOcc =
std::min(OtherSGPROcc, OtherVGPROcc);
140 return Occ > OtherOcc;
142 bool SGPRImportant = SGPROcc < VGPROcc;
143 const bool OtherSGPRImportant = OtherSGPROcc < OtherVGPROcc;
146 if (SGPRImportant != OtherSGPRImportant) {
147 SGPRImportant =
false;
151 bool SGPRFirst = SGPRImportant;
152 for (
int I = 2;
I > 0; --
I, SGPRFirst = !SGPRFirst) {
155 auto OtherSW =
O.getSGPRTuplesWeight();
160 auto OtherVW =
O.getVGPRTuplesWeight();
165 return SGPRImportant ? (
getSGPRNum() <
O.getSGPRNum()):
167 O.getVGPRNum(
ST.hasGFX90AInsts()));
170 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
179 if (
ST) OS <<
"(O" <<
ST->getOccupancyWithNumSGPRs(
getSGPRNum()) <<
')';
222 for (
const auto &MO :
MI.operands()) {
223 if (!MO.isReg() || !MO.getReg().isVirtual())
225 if (!MO.isUse() || !MO.readsReg())
230 auto Reg = MO.getReg();
234 I->LaneMask |= UsedMask;
250 if (LI.hasSubRanges()) {
251 for (
const auto &
S : LI.subranges())
253 LiveMask |=
S.LaneMask;
257 }
else if (LI.liveAt(
SI)) {
273 LiveRegs[
Reg] = LiveMask;
304 if (
MI.isDebugInstr())
311 for (
const auto &U : RegUses) {
312 auto LiveMask =
LiveRegs[U.RegUnit];
313 AtMIPressure.inc(U.RegUnit, LiveMask, LiveMask | U.LaneMask, *
MRI);
318 for (
const auto &MO :
MI.operands()) {
319 if (!MO.isReg() || !MO.isDef() || !MO.getReg().isVirtual() || MO.isDead())
322 auto Reg = MO.getReg();
326 auto &LiveMask =
I->second;
327 auto PrevMask = LiveMask;
333 for (
const auto &U : RegUses) {
334 auto &LiveMask =
LiveRegs[U.RegUnit];
335 auto PrevMask = LiveMask;
336 LiveMask |= U.LaneMask;
344 MRI = &
MI.getParent()->getParent()->getRegInfo();
346 MBBEnd =
MI.getParent()->end();
349 if (NextMI == MBBEnd)
359 if (NextMI == MBBEnd)
371 auto PrevMask = It.second;
372 It.second &= ~
S.LaneMask;
377 auto PrevMask = It.second;
381 if (It.second.none())
396 if (!MO.isReg() || !MO.isDef())
399 if (!
Reg.isVirtual())
402 auto PrevMask = LiveMask;
419 while (NextMI != End)
427 reset(*Begin, LiveRegsCopy);
431 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
436 for (
auto const &
P : TrackedLR) {
437 auto I = LISLR.
find(
P.first);
438 if (
I == LISLR.
end()) {
441 <<
" isn't found in LIS reported set\n";
443 else if (
I->second !=
P.second) {
445 <<
" masks doesn't match: LIS reported "
452 for (
auto const &
P : LISLR) {
453 auto I = TrackedLR.find(
P.first);
454 if (
I == TrackedLR.end()) {
457 <<
" isn't found in tracked set\n";
467 if (!
isEqual(LISLR, TrackedLR)) {
468 dbgs() <<
"\nGCNUpwardRPTracker error: Tracked and"
469 " LIS reported livesets mismatch:\n";
477 dbgs() <<
"GCNUpwardRPTracker error: Pressure sets different\nTracked: ";
479 dbgs() <<
"LIS rpt: ";
480 LISPressure.print(
dbgs());
unsigned getSGPRTuplesWeight() const
void reset(const MachineInstr &MI, const LiveRegSet *LiveRegs=nullptr)
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
This is an optimization pass for GlobalISel generic memory operations.
GCNRPTracker::LiveRegSet getLiveRegsBefore(const MachineInstr &MI, const LiveIntervals &LIS)
Printable printVRegOrUnit(unsigned VRegOrUnit, const TargetRegisterInfo *TRI)
Create Printable object to print virtual registers and physical registers on a raw_ostream.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
GCNRegPressure getRegPressure(const MachineRegisterInfo &MRI, Range &&LiveRegs)
LaneBitmask getLiveLaneMask(unsigned Reg, SlotIndex SI, const LiveIntervals &LIS, const MachineRegisterInfo &MRI)
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
MachineInstr * getInstructionFromIndex(SlotIndex index) const
Returns the instruction associated with the given index.
Reg
All possible values of the reg field in the ModR/M byte.
const TargetRegisterInfo * getTargetRegisterInfo() const
bool erase(const KeyT &Val)
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
unsigned getNumVirtRegs() const
getNumVirtRegs - Return the number of virtual registers created.
static Register index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
bool less(const GCNSubtarget &ST, const GCNRegPressure &O, unsigned MaxOccupancy=std::numeric_limits< unsigned >::max()) const
GCNRPTracker::LiveRegSet getLiveRegsAfter(const MachineInstr &MI, const LiveIntervals &LIS)
unsigned const TargetRegisterInfo * TRI
unsigned getVGPRTuplesWeight() const
bool isEqual(const GCNRPTracker::LiveRegSet &S1, const GCNRPTracker::LiveRegSet &S2)
SlotIndex getInstructionIndex(const MachineInstr &Instr) const
Returns the base index of the given instruction.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void recede(const MachineInstr &MI)
static LaneBitmask getDefRegMask(const MachineOperand &MO, const MachineRegisterInfo &MRI)
void inc(unsigned Reg, LaneBitmask PrevMask, LaneBitmask NewMask, const MachineRegisterInfo &MRI)
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
bool liveAt(SlotIndex index) const
LaneBitmask getSubRegIndexLaneMask(unsigned SubIdx) const
Return a bitmask representing the parts of a register that are covered by SubIdx.
unsigned getSGPRNum() const
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
GCNRegPressure MaxPressure
unsigned getOccupancy(const GCNSubtarget &ST) const
static constexpr LaneBitmask getNone()
MachineOperand class - Representation of each machine instruction operand.
unsigned getWeight() const
This class implements an extremely fast bulk output stream that can only output to a stream.
Printable PrintLaneMask(LaneBitmask LaneMask)
Create Printable object to print LaneBitmasks on a raw_ostream.
const MachineRegisterInfo * MRI
static bool isSGPRClass(const TargetRegisterClass *RC)
LiveInterval - This class represents the liveness of a register, or stack slot.
SlotIndex - An opaque wrapper around machine indexes.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
static LaneBitmask getUsedRegMask(const MachineOperand &MO, const MachineRegisterInfo &MRI, const LiveIntervals &LIS)
bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
SlotIndex getBaseIndex() const
Returns the base index for associated with this index.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Representation of each machine instruction.
static SmallVector< RegisterMaskPair, 8 > collectVirtualRegUses(const MachineInstr &MI, const LiveIntervals &LIS, const MachineRegisterInfo &MRI)
iterator find(const_arg_type_t< KeyT > Val)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool reset(const MachineInstr &MI, const LiveRegSet *LiveRegs=nullptr)
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
StandardInstrumentations SI(Debug, VerifyEach)
Register getReg() const
getReg - Returns the register number.
LiveInterval & getInterval(Register Reg)
static LLVM_DUMP_METHOD void reportMismatch(const GCNRPTracker::LiveRegSet &LISLR, const GCNRPTracker::LiveRegSet &TrackedLR, const TargetRegisterInfo *TRI)
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.
Expected< ExpressionValue > min(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
static unsigned getNumCoveredRegs(LaneBitmask LM)
constexpr bool none() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
unsigned const MachineRegisterInfo * MRI
Wrapper class representing virtual and physical registers.
unsigned getSubReg() const
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
LaneBitmask getMaxLaneMaskForVReg(Register Reg) const
Returns a mask covering all bits that can appear in lane masks of subregisters of the virtual registe...
unsigned getVGPRNum(bool UnifiedVGPRFile) const
const LiveIntervals & LIS
void reset(const MachineInstr &MI, const LiveRegSet *LiveRegsCopy, bool After)
GCNRegPressure CurPressure
static void printLiveRegs(raw_ostream &OS, const LiveRegSet &LiveRegs, const MachineRegisterInfo &MRI)
void printLivesAt(SlotIndex SI, const LiveIntervals &LIS, const MachineRegisterInfo &MRI)
bool hasSubRanges() const
Returns true if subregister liveness information is available.
Align max(MaybeAlign Lhs, Align Rhs)
GCNRPTracker::LiveRegSet getLiveRegs(SlotIndex SI, const LiveIntervals &LIS, const MachineRegisterInfo &MRI)
bool hasInterval(Register Reg) const
const MachineInstr * LastTrackedMI
void print(raw_ostream &OS, const GCNSubtarget *ST=nullptr) const
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.
PSetIterator getPressureSets(Register RegUnit) const
Get an iterator over the pressure sets affected by the given physical or virtual register.
iterator_range< mop_iterator > operands()
LLVM Value Representation.
iterator_range< subrange_iterator > subranges()