39#define DEBUG_TYPE "post-RA-sched"
43 : MF(MFi),
MRI(MF.getRegInfo()),
TII(MF.getSubtarget().getInstrInfo()),
44 TRI(MF.getSubtarget().getRegisterInfo()), RegClassInfo(RCI),
45 Classes(
TRI->getNumRegs(), nullptr), KillIndices(
TRI->getNumRegs(), 0),
46 DefIndices(
TRI->getNumRegs(), 0), KeepRegs(
TRI->getNumRegs(),
false) {}
51 const unsigned BBSize = BB->
size();
52 for (
unsigned i = 1, e = TRI->
getNumRegs(); i != e; ++i) {
58 DefIndices[i] = BBSize;
68 for (
const auto &LI : Succ->liveins()) {
72 KillIndices[Reg.id()] = BBSize;
73 DefIndices[Reg] = ~0u;
85 if (!IsReturnBlock && !Pristine.
test(Reg))
90 KillIndices[Reg.id()] = BBSize;
91 DefIndices[Reg.id()] = ~0u;
102 unsigned InsertPosIndex) {
110 if (
MI.isDebugInstr() ||
MI.isKill())
112 assert(Count < InsertPosIndex &&
"Instruction index out of expected range!");
114 for (
unsigned Reg = 1; Reg != TRI->
getNumRegs(); ++Reg) {
115 if (KillIndices[Reg] != ~0u) {
120 KillIndices[Reg] = Count;
121 }
else if (DefIndices[Reg] < InsertPosIndex && DefIndices[Reg] >= Count) {
130 DefIndices[Reg] = InsertPosIndex;
134 PrescanInstruction(
MI);
135 ScanInstruction(
MI, Count);
141 const SDep *Next =
nullptr;
142 unsigned NextDepth = 0;
145 const SUnit *PredSU =
P.getSUnit();
146 unsigned PredLatency =
P.getLatency();
147 unsigned PredTotalLatency = PredSU->
getDepth() + PredLatency;
150 if (NextDepth < PredTotalLatency ||
151 (NextDepth == PredTotalLatency &&
P.getKind() ==
SDep::Anti)) {
152 NextDepth = PredTotalLatency;
159void CriticalAntiDepBreaker::PrescanInstruction(
MachineInstr &
MI) {
181 for (
unsigned i = 0, e =
MI.getNumOperands(); i != e; ++i) {
183 if (!MO.
isReg())
continue;
189 if (i <
MI.getDesc().getNumOperands())
194 if (!Classes[
Reg.id()] && NewRC)
195 Classes[
Reg.id()] = NewRC;
196 else if (!NewRC || Classes[
Reg.id()] != NewRC)
204 unsigned AliasReg = (*AI).id();
205 if (Classes[AliasReg]) {
213 RegRefs.emplace(Reg, &MO);
215 if (MO.
isUse() && Special) {
216 if (!KeepRegs.
test(
Reg.id())) {
223 for (
unsigned I = 0, E =
MI.getNumOperands();
I != E; ++
I) {
225 if (!MO.
isReg())
continue;
239 if (
MI.isRegTiedToUseOperand(
I) &&
245 KeepRegs.
set(SuperReg);
251void CriticalAntiDepBreaker::ScanInstruction(
MachineInstr &
MI,
unsigned Count) {
255 assert(!
MI.isKill() &&
"Attempting to scan a kill instruction");
260 for (
unsigned i = 0, e =
MI.getNumOperands(); i != e; ++i) {
264 auto ClobbersPhysRegAndSubRegs = [&](
unsigned PhysReg) {
266 [&](
MCPhysReg SR) { return MO.clobbersPhysReg(SR); });
269 for (
unsigned i = 1, e = TRI->
getNumRegs(); i != e; ++i) {
270 if (ClobbersPhysRegAndSubRegs(i)) {
271 DefIndices[i] = Count;
272 KillIndices[i] = ~0
u;
274 Classes[i] =
nullptr;
280 if (!MO.
isReg())
continue;
284 if (!MO.
isDef())
continue;
287 if (
MI.isRegTiedToUseOperand(i))
297 DefIndices[SubregReg] = Count;
298 KillIndices[SubregReg] = ~0
u;
299 Classes[SubregReg] =
nullptr;
300 RegRefs.erase(SubregReg);
302 KeepRegs.
reset(SubregReg);
309 for (
unsigned i = 0, e =
MI.getNumOperands(); i !=
e; ++i) {
311 if (!MO.
isReg())
continue;
315 if (!MO.
isUse())
continue;
318 if (i <
MI.getDesc().getNumOperands())
323 if (!Classes[
Reg.id()] && NewRC)
324 Classes[
Reg.id()] = NewRC;
325 else if (!NewRC || Classes[
Reg.id()] != NewRC)
328 RegRefs.emplace(Reg, &MO);
334 if (KillIndices[AliasReg.
id()] == ~0
u) {
335 KillIndices[AliasReg.
id()] = Count;
336 DefIndices[AliasReg.
id()] = ~0
u;
353bool CriticalAntiDepBreaker::isNewRegClobberedByRefs(RegRefIter RegRefBegin,
354 RegRefIter RegRefEnd,
356 for (RegRefIter
I = RegRefBegin;
I != RegRefEnd; ++
I ) {
368 if (CheckOper.isRegMask() && CheckOper.clobbersPhysReg(NewReg))
371 if (!CheckOper.isReg() || !CheckOper.isDef() ||
372 CheckOper.getReg() != NewReg)
377 if (RefOper->
isDef())
382 if (CheckOper.isEarlyClobber())
387 if (
MI->isInlineAsm())
394MCRegister CriticalAntiDepBreaker::findSuitableFreeRegister(
395 RegRefIter RegRefBegin, RegRefIter RegRefEnd,
MCRegister AntiDepReg,
401 if (NewReg == AntiDepReg)
continue;
405 if (NewReg == LastNewReg)
continue;
409 if (isNewRegClobberedByRefs(RegRefBegin, RegRefEnd, NewReg))
continue;
412 assert(((KillIndices[AntiDepReg.
id()] == ~0u) !=
413 (DefIndices[AntiDepReg.
id()] == ~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 ||
419 KillIndices[AntiDepReg.
id()] > DefIndices[NewReg])
422 bool Forbidden =
false;
424 if (
TRI->regsOverlap(NewReg, R)) {
428 if (Forbidden)
continue;
440 unsigned InsertPosIndex,
444 if (SUnits.empty())
return 0;
453 const SUnit *Max =
nullptr;
454 for (
const SUnit &SU : SUnits) {
455 MISUnitMap[SU.getInstr()] = &SU;
456 if (!Max || SU.getDepth() + SU.Latency > Max->getDepth() + Max->Latency)
459 assert(Max &&
"Failed to find bottom of the critical path");
464 << (Max->getDepth() + Max->Latency) <<
"\n");
466 for (
unsigned Reg = 1; Reg <
TRI->getNumRegs(); ++Reg) {
467 if (KillIndices[Reg] == ~0u)
476 const SUnit *CriticalPathSU = Max;
520 std::vector<MCRegister> LastNewReg(
TRI->getNumRegs(),
MCRegister());
526 unsigned Count = InsertPosIndex - 1;
536 if (
MI.isDebugInstr() ||
MI.isKill())
553 if (&
MI == CriticalPathMI) {
559 AntiDepReg =
Edge->getReg().asMCReg();
560 assert(AntiDepReg &&
"Anti-dependence on reg0?");
564 else if (KeepRegs.
test(AntiDepReg.
id()))
578 if (
P.getSUnit() == NextSU
579 ? (
P.getKind() !=
SDep::Anti ||
P.getReg() != AntiDepReg)
581 P.getReg() == AntiDepReg)) {
587 CriticalPathSU = NextSU;
588 CriticalPathMI = CriticalPathSU->
getInstr();
591 CriticalPathSU =
nullptr;
592 CriticalPathMI =
nullptr;
596 PrescanInstruction(
MI);
607 else if (AntiDepReg) {
613 if (!MO.
isReg())
continue;
617 if (MO.
isUse() &&
TRI->regsOverlap(AntiDepReg, Reg)) {
621 if (MO.
isDef() && Reg != AntiDepReg)
629 AntiDepReg ? Classes[AntiDepReg.
id()] :
nullptr;
630 assert((!AntiDepReg || RC !=
nullptr) &&
631 "Register should be live if it's causing an anti-dependence!");
640 std::pair<std::multimap<MCRegister, MachineOperand *>::iterator,
641 std::multimap<MCRegister, MachineOperand *>::iterator>
642 Range = RegRefs.equal_range(AntiDepReg);
643 if (
MCRegister NewReg = findSuitableFreeRegister(
644 Range.first,
Range.second, AntiDepReg, LastNewReg[AntiDepReg], RC,
648 << RegRefs.count(AntiDepReg) <<
" references"
653 for (std::multimap<MCRegister, MachineOperand *>::iterator
657 Q->second->setReg(NewReg);
661 const SUnit *SU = MISUnitMap[Q->second->getParent()];
670 Classes[NewReg.id()] = Classes[AntiDepReg.id()];
671 DefIndices[NewReg.id()] = DefIndices[AntiDepReg.id()];
672 KillIndices[NewReg.id()] = KillIndices[AntiDepReg.id()];
673 assert(((KillIndices[NewReg.id()] == ~0u) !=
674 (DefIndices[NewReg.id()] == ~0u)) &&
675 "Kill and Def maps aren't consistent for NewReg!");
677 Classes[AntiDepReg.id()] =
nullptr;
678 DefIndices[AntiDepReg.id()] = KillIndices[AntiDepReg.id()];
679 KillIndices[AntiDepReg.id()] = ~0u;
680 assert(((KillIndices[AntiDepReg.id()] == ~0u) !=
681 (DefIndices[AntiDepReg.id()] == ~0u)) &&
682 "Kill and Def maps aren't consistent for AntiDepReg!");
684 RegRefs.erase(AntiDepReg);
685 LastNewReg[AntiDepReg.id()] = NewReg;
690 ScanInstruction(
MI, Count);
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static const SUnit * CriticalPathStep(const SUnit *SU)
CriticalPathStep - Return the next SUnit after SU on the bottom-up critical path.
This file defines the DenseMap class.
const HexagonInstrInfo * TII
Register const TargetRegisterInfo * TRI
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
std::pair< BasicBlock *, BasicBlock * > Edge
This file defines the SmallVector class.
This class works in conjunction with the post-RA scheduler to rename registers to break register anti...
void UpdateDbgValues(const DbgValueVector &DbgValues, MachineInstr *ParentMI, MCRegister OldReg, MCRegister NewReg)
Update all DBG_VALUE instructions that may be affected by the dependency breaker's update of ParentMI...
std::vector< std::pair< MachineInstr *, MachineInstr * > > DbgValueVector
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
bool test(unsigned Idx) const
~CriticalAntiDepBreaker() override
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...
void FinishBlock() override
Finish anti-dep breaking for a basic block.
void Observe(MachineInstr &MI, unsigned Count, unsigned InsertPosIndex) override
Update liveness information to account for the current instruction, which will not be scheduled.
void StartBlock(MachineBasicBlock *BB) override
Initialize anti-dep breaking for a new basic block.
CriticalAntiDepBreaker(MachineFunction &MFi, const RegisterClassInfo &RCI)
MCRegAliasIterator enumerates all registers aliasing Reg.
iterator_range< MCSuperRegIterator > superregs(MCRegister Reg) const
Return an iterator range over all super-registers of Reg, excluding Reg.
iterator_range< MCSubRegIterator > subregs_inclusive(MCRegister Reg) const
Return an iterator range over all sub-registers of Reg, including Reg.
unsigned getNumRegs() const
Return the number of registers this target has (useful for sizing arrays holding per register informa...
Wrapper class representing physical registers. Should be passed by value.
constexpr unsigned id() const
bool isReturnBlock() const
Convenience function that returns true if the block ends in a return instruction.
iterator_range< succ_iterator > successors()
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
LLVM_ABI BitVector getPristineRegs(const MachineFunction &MF) const
Return a set of physical registers that are pristine.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isRegMask() const
isRegMask - Tests if this is a MO_RegisterMask operand.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
bool isEarlyClobber() const
Register getReg() const
getReg - Returns the register number.
bool isAllocatable(MCRegister PhysReg) const
isAllocatable - Returns true when PhysReg belongs to an allocatable register class and it hasn't been...
LLVM_ABI const MCPhysReg * getCalleeSavedRegs() const
Returns list of callee saved registers.
ArrayRef< MCPhysReg > getOrder(const TargetRegisterClass *RC) const
getOrder - Returns the preferred allocation order for RC.
Wrapper class representing virtual and physical registers.
@ Anti
A register anti-dependence (aka WAR).
@ Data
Regular data dependence (aka true-dependence).
Scheduling unit. This is a node in the scheduling DAG.
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...
SmallVector< SDep, 4 > Preds
All sunit predecessors.
MachineInstr * getInstr() const
Returns the representative MachineInstr for this SUnit.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
virtual bool isPredicated(const MachineInstr &MI) const
Returns true if the instruction is already predicated.
virtual 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,...
Reg
All possible values of the reg field in the ModR/M byte.
This is an optimization pass for GlobalISel generic memory operations.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
AntiDepBreaker * createCriticalAntiDepBreaker(MachineFunction &MFi, const RegisterClassInfo &RCI)
LLVM_ABI 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.
@ Keep
No function return thunk.