43 #define DEBUG_TYPE "post-RA-sched" 48 TII(MF.getSubtarget().getInstrInfo()),
49 TRI(MF.getSubtarget().getRegisterInfo()), RegClassInfo(RCI),
50 Classes(
TRI->getNumRegs(), nullptr), KillIndices(
TRI->getNumRegs(), 0),
51 DefIndices(
TRI->getNumRegs(), 0), KeepRegs(
TRI->getNumRegs(),
false) {}
56 const unsigned BBSize = BB->
size();
57 for (
unsigned i = 0, e = TRI->
getNumRegs(); i != e; ++i) {
63 DefIndices[i] = BBSize;
74 for (
const auto &LI : (*SI)->liveins()) {
78 KillIndices[
Reg] = BBSize;
79 DefIndices[
Reg] = ~0u;
91 if (!IsReturnBlock && !Pristine.
test(Reg))
96 KillIndices[
Reg] = BBSize;
97 DefIndices[
Reg] = ~0u;
108 unsigned InsertPosIndex) {
118 assert(Count < InsertPosIndex &&
"Instruction index out of expected range!");
121 if (KillIndices[
Reg] != ~0u) {
126 KillIndices[
Reg] = Count;
127 }
else if (DefIndices[
Reg] < InsertPosIndex && DefIndices[
Reg] >= Count) {
136 DefIndices[
Reg] = InsertPosIndex;
140 PrescanInstruction(MI);
141 ScanInstruction(MI, Count);
147 const SDep *Next =
nullptr;
148 unsigned NextDepth = 0;
152 const SUnit *PredSU =
P->getSUnit();
153 unsigned PredLatency =
P->getLatency();
154 unsigned PredTotalLatency = PredSU->
getDepth() + PredLatency;
157 if (NextDepth < PredTotalLatency ||
158 (NextDepth == PredTotalLatency &&
P->getKind() ==
SDep::Anti)) {
159 NextDepth = PredTotalLatency;
166 void CriticalAntiDepBreaker::PrescanInstruction(
MachineInstr &
MI) {
190 if (!MO.
isReg())
continue;
192 if (Reg == 0)
continue;
200 if (!Classes[Reg] && NewRC)
201 Classes[
Reg] = NewRC;
202 else if (!NewRC || Classes[Reg] != NewRC)
210 unsigned AliasReg = *AI;
211 if (Classes[AliasReg]) {
218 if (Classes[Reg] != reinterpret_cast<TargetRegisterClass *>(-1))
219 RegRefs.insert(std::make_pair(Reg, &MO));
234 SubRegs.
isValid(); ++SubRegs) {
235 KeepRegs.
set(*SubRegs);
238 SuperRegs.
isValid(); ++SuperRegs) {
239 KeepRegs.
set(*SuperRegs);
243 if (MO.
isUse() && Special) {
244 if (!KeepRegs.
test(Reg)) {
247 KeepRegs.
set(*SubRegs);
253 void CriticalAntiDepBreaker::ScanInstruction(
MachineInstr &MI,
unsigned Count) {
257 assert(!MI.
isKill() &&
"Attempting to scan a kill instruction");
266 for (
unsigned i = 0, e = TRI->
getNumRegs(); i != e; ++i)
268 DefIndices[i] = Count;
269 KillIndices[i] = ~0u;
271 Classes[i] =
nullptr;
275 if (!MO.
isReg())
continue;
277 if (Reg == 0)
continue;
278 if (!MO.
isDef())
continue;
286 bool Keep = KeepRegs.
test(Reg);
291 unsigned SubregReg = *SRI;
292 DefIndices[SubregReg] = Count;
293 KillIndices[SubregReg] = ~0u;
294 Classes[SubregReg] =
nullptr;
295 RegRefs.erase(SubregReg);
297 KeepRegs.
reset(SubregReg);
301 Classes[*SR] = reinterpret_cast<TargetRegisterClass *>(-1);
306 if (!MO.
isReg())
continue;
308 if (Reg == 0)
continue;
309 if (!MO.
isUse())
continue;
317 if (!Classes[Reg] && NewRC)
318 Classes[
Reg] = NewRC;
319 else if (!NewRC || Classes[Reg] != NewRC)
322 RegRefs.insert(std::make_pair(Reg, &MO));
327 unsigned AliasReg = *AI;
328 if (KillIndices[AliasReg] == ~0u) {
329 KillIndices[AliasReg] = Count;
330 DefIndices[AliasReg] = ~0u;
348 CriticalAntiDepBreaker::isNewRegClobberedByRefs(RegRefIter RegRefBegin,
349 RegRefIter RegRefEnd,
351 for (RegRefIter
I = RegRefBegin;
I != RegRefEnd; ++
I ) {
368 if (!CheckOper.
isReg() || !CheckOper.
isDef() ||
369 CheckOper.
getReg() != NewReg)
374 if (RefOper->
isDef())
391 unsigned CriticalAntiDepBreaker::
392 findSuitableFreeRegister(RegRefIter RegRefBegin,
393 RegRefIter RegRefEnd,
399 for (
unsigned i = 0; i != Order.
size(); ++i) {
400 unsigned NewReg = Order[i];
402 if (NewReg == AntiDepReg)
continue;
406 if (NewReg == LastNewReg)
continue;
410 if (isNewRegClobberedByRefs(RegRefBegin, RegRefEnd, NewReg))
continue;
413 assert(((KillIndices[AntiDepReg] == ~0u) != (DefIndices[AntiDepReg] == ~0u))
414 &&
"Kill and Def maps aren't consistent for AntiDepReg!");
415 assert(((KillIndices[NewReg] == ~0u) != (DefIndices[NewReg] == ~0u))
416 &&
"Kill and Def maps aren't consistent for NewReg!");
417 if (KillIndices[NewReg] != ~0u ||
418 Classes[NewReg] == reinterpret_cast<TargetRegisterClass *>(-1) ||
419 KillIndices[AntiDepReg] > DefIndices[NewReg])
422 bool Forbidden =
false;
424 ite = Forbid.
end(); it != ite; ++it)
429 if (Forbidden)
continue;
441 unsigned InsertPosIndex,
445 if (SUnits.empty())
return 0;
454 const SUnit *Max =
nullptr;
455 for (
unsigned i = 0, e = SUnits.size(); i != e; ++i) {
456 const SUnit *SU = &SUnits[i];
468 if (KillIndices[
Reg] == ~0u)
477 const SUnit *CriticalPathSU = Max;
521 std::vector<unsigned> LastNewReg(TRI->
getNumRegs(), 0);
527 unsigned Count = InsertPosIndex - 1;
553 unsigned AntiDepReg = 0;
554 if (&MI == CriticalPathMI) {
556 const SUnit *NextSU = Edge->getSUnit();
560 AntiDepReg = Edge->getReg();
561 assert(AntiDepReg != 0 &&
"Anti-dependence on reg0?");
565 else if (KeepRegs.
test(AntiDepReg))
579 PE = CriticalPathSU->
Preds.end();
P != PE; ++
P)
580 if (
P->getSUnit() == NextSU ?
581 (
P->getKind() !=
SDep::Anti ||
P->getReg() != AntiDepReg) :
582 (
P->getKind() ==
SDep::Data &&
P->getReg() == AntiDepReg)) {
588 CriticalPathSU = NextSU;
589 CriticalPathMI = CriticalPathSU->
getInstr();
592 CriticalPathSU =
nullptr;
593 CriticalPathMI =
nullptr;
597 PrescanInstruction(MI);
608 else if (AntiDepReg) {
615 if (!MO.
isReg())
continue;
617 if (Reg == 0)
continue;
622 if (MO.
isDef() && Reg != AntiDepReg)
631 assert((AntiDepReg == 0 || RC !=
nullptr) &&
632 "Register should be live if it's causing an anti-dependence!");
633 if (RC == reinterpret_cast<TargetRegisterClass *>(-1))
640 if (AntiDepReg != 0) {
641 std::pair<std::multimap<unsigned, MachineOperand *>::iterator,
642 std::multimap<unsigned, MachineOperand *>::iterator>
643 Range = RegRefs.equal_range(AntiDepReg);
644 if (
unsigned NewReg = findSuitableFreeRegister(Range.first, Range.second,
646 LastNewReg[AntiDepReg],
649 <<
printReg(AntiDepReg, TRI) <<
" with " 650 << RegRefs.count(AntiDepReg) <<
" references" 651 <<
" using " <<
printReg(NewReg, TRI) <<
"!\n");
655 for (std::multimap<unsigned, MachineOperand *>::iterator
656 Q = Range.first, QE = Range.second; Q != QE; ++Q) {
657 Q->second->setReg(NewReg);
661 const SUnit *SU = MISUnitMap[Q->second->getParent()];
670 Classes[NewReg] = Classes[AntiDepReg];
671 DefIndices[NewReg] = DefIndices[AntiDepReg];
672 KillIndices[NewReg] = KillIndices[AntiDepReg];
673 assert(((KillIndices[NewReg] == ~0u) !=
674 (DefIndices[NewReg] == ~0u)) &&
675 "Kill and Def maps aren't consistent for NewReg!");
677 Classes[AntiDepReg] =
nullptr;
678 DefIndices[AntiDepReg] = KillIndices[AntiDepReg];
679 KillIndices[AntiDepReg] = ~0u;
680 assert(((KillIndices[AntiDepReg] == ~0u) !=
681 (DefIndices[AntiDepReg] == ~0u)) &&
682 "Kill and Def maps aren't consistent for AntiDepReg!");
684 RegRefs.erase(AntiDepReg);
685 LastNewReg[AntiDepReg] = NewReg;
690 ScanInstruction(MI, Count);
bool isRegMask() const
isRegMask - Tests if this is a MO_RegisterMask operand.
ArrayRef< MCPhysReg > getOrder(const TargetRegisterClass *RC) const
getOrder - Returns the preferred allocation order for RC.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
bool isCall(QueryType Type=AnyInBundle) const
bool isAllocatable(unsigned PhysReg) const
isAllocatable - Returns true when PhysReg belongs to an allocatable register class and it hasn't been...
This class represents lattice values for constants.
bool hasExtraDefRegAllocReq(QueryType Type=AnyInBundle) const
Returns true if this instruction def operands have special register allocation requirements that are ...
void FinishBlock() override
Finish anti-dep breaking for a basic block.
void push_back(const T &Elt)
unsigned getDepth() const
Returns the depth of this node, which is the length of the maximum path up to any node which has no p...
unsigned getReg() const
getReg - Returns the register number.
~CriticalAntiDepBreaker() override
bool test(unsigned Idx) const
unsigned const TargetRegisterInfo * TRI
SmallVector< SDep, 4 > Preds
All sunit predecessors.
A register anti-dependence (aka WAR).
bool isEarlyClobber() const
bool isReturnBlock() const
Convenience function that returns true if the block ends in a return instruction. ...
MCSuperRegIterator enumerates all super-registers of Reg.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
const HexagonInstrInfo * TII
This class works in conjunction with the post-RA scheduler to rename registers to break register anti...
unsigned getNumOperands() const
Retuns the total number of operands.
const TargetRegisterClass * getRegClass(const MCInstrDesc &MCID, unsigned OpNum, const TargetRegisterInfo *TRI, const MachineFunction &MF) const
Given a machine instruction descriptor, returns the register class constraint for OpNum...
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.
SmallVectorImpl< SDep >::const_iterator const_pred_iterator
Regular data dependence (aka true-dependence).
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
unsigned getNumRegs() const
Return the number of registers this target has (useful for sizing arrays holding per register informa...
std::vector< std::pair< MachineInstr *, MachineInstr * > > DbgValueVector
MachineInstr * getInstr() const
Returns the representative MachineInstr for this SUnit.
unsigned const MachineRegisterInfo * MRI
unsigned short Latency
Node latency.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
size_t size() const
size - Get the array size.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
MCRegAliasIterator enumerates all registers aliasing Reg.
void StartBlock(MachineBasicBlock *BB) override
Initialize anti-dep breaking for a new basic block.
CriticalAntiDepBreaker(MachineFunction &MFi, const RegisterClassInfo &RCI)
succ_iterator succ_begin()
unsigned BreakAntiDependencies(const std::vector< SUnit > &SUnits, MachineBasicBlock::iterator Begin, MachineBasicBlock::iterator End, unsigned InsertPosIndex, DbgValueVector &DbgValues) override
Identifiy anti-dependencies along the critical path of the ScheduleDAG and break them by renaming reg...
MCSubRegIterator enumerates all sub-registers of Reg.
virtual bool isPredicated(const MachineInstr &MI) const
Returns true if the instruction is already predicated.
bool isDebugInstr() const
bool regsOverlap(unsigned regA, unsigned regB) const
Returns true if the two registers are equal or alias each other.
MachineOperand class - Representation of each machine instruction operand.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
static bool clobbersPhysReg(const uint32_t *RegMask, unsigned PhysReg)
clobbersPhysReg - Returns true if this RegMask clobbers PhysReg.
bool isValid() const
isValid - returns true if this iterator is not yet at the end.
void Observe(MachineInstr &MI, unsigned Count, unsigned InsertPosIndex) override
Update liveness information to account for the current instruction, which will not be scheduled...
Representation of each machine instruction.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
bool hasExtraSrcRegAllocReq(QueryType Type=AnyInBundle) const
Returns true if this instruction source operands have special register allocation requirements that a...
static const SDep * CriticalPathStep(const SUnit *SU)
CriticalPathStep - Return the next SUnit after SU on the bottom-up critical path. ...
bool isRegTiedToUseOperand(unsigned DefOpIdx, unsigned *UseOpIdx=nullptr) const
Given the index of a register def operand, check if the register def is tied to a source operand...
bool isReg() const
isReg - Tests if this is a MO_Register operand.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void UpdateDbgValues(const DbgValueVector &DbgValues, MachineInstr *ParentMI, unsigned OldReg, unsigned NewReg)
Update all DBG_VALUE instructions that may be affected by the dependency breaker's update of ParentMI...
const MCPhysReg * getCalleeSavedRegs() const
Returns list of callee saved registers.
BitVector getPristineRegs(const MachineFunction &MF) const
Return a set of physical registers that are pristine.
const MachineOperand & getOperand(unsigned i) const
std::vector< MachineBasicBlock * >::iterator succ_iterator
Scheduling unit. This is a node in the scheduling DAG.