41#define DEBUG_TYPE "post-RA-sched"
46 cl::desc(
"Debug control for aggressive anti-dep breaker"),
51 cl::desc(
"Debug control for aggressive anti-dep breaker"),
56 : NumTargetRegs(TargetRegs), GroupNodes(TargetRegs, 0),
57 GroupNodeIndices(TargetRegs, 0), KillIndices(TargetRegs, 0),
58 DefIndices(TargetRegs, 0) {
59 const unsigned BBSize = BB->
size();
60 for (
unsigned i = 0; i < NumTargetRegs; ++i) {
63 GroupNodeIndices[i] = i;
66 DefIndices[i] = BBSize;
71 unsigned Node = GroupNodeIndices[Reg];
79 unsigned Group, std::vector<MCRegister> &Regs,
80 std::multimap<MCRegister, AggressiveAntiDepState::RegisterReference>
82 for (
unsigned Reg = 0; Reg != NumTargetRegs; ++Reg) {
83 if ((
GetGroup(Reg) == Group) && (RegRefs->count(Reg) > 0))
89 assert(GroupNodes[0] == 0 &&
"GroupNode 0 not parent!");
90 assert(GroupNodeIndices[0] == 0 &&
"Reg 0 not in Group 0!");
97 unsigned Parent = (Group1 == 0) ? Group1 : Group2;
98 unsigned Other = (Parent == Group1) ? Group2 : Group1;
99 GroupNodes.at(
Other) = Parent;
107 unsigned idx = GroupNodes.size();
108 GroupNodes.push_back(idx);
109 GroupNodeIndices[Reg] = idx;
116 return((KillIndices[Reg] != ~0u) && (DefIndices[Reg] == ~0u));
122 : MF(MFi), MRI(MF.getRegInfo()), TII(MF.getSubtarget().getInstrInfo()),
123 TRI(MF.getSubtarget().getRegisterInfo()), RegClassInfo(RCI) {
127 BitVector CPSet = TRI->getAllocatableSet(MF, RC);
128 if (CriticalPathSet.none())
129 CriticalPathSet = CPSet;
131 CriticalPathSet |= CPSet;
136 : CriticalPathSet.set_bits())
dbgs()
150 std::vector<unsigned> &KillIndices = State->GetKillIndices();
151 std::vector<unsigned> &DefIndices = State->GetDefIndices();
155 for (
const auto &LI : Succ->liveins()) {
158 State->UnionGroups(Reg, 0);
159 KillIndices[Reg] = BB->
size();
160 DefIndices[Reg] = ~0u;
169 for (
const MCPhysReg *
I = MF.getRegInfo().getCalleeSavedRegs(); *
I;
172 if (!IsReturnBlock && !Pristine.
test(Reg))
176 State->UnionGroups(AliasReg, 0);
177 KillIndices[AliasReg] = BB->
size();
178 DefIndices[AliasReg] = ~0u;
189 unsigned InsertPosIndex) {
190 assert(
Count < InsertPosIndex &&
"Instruction index out of expected range!");
192 std::set<MCRegister> PassthruRegs;
193 GetPassthruRegs(
MI, PassthruRegs);
194 PrescanInstruction(
MI,
Count, PassthruRegs);
201 std::vector<unsigned> &DefIndices = State->GetDefIndices();
202 for (
unsigned Reg = 1; Reg != TRI->getNumRegs(); ++Reg) {
209 if (State->IsLive(Reg)) {
211 <<
" " <<
printReg(Reg, TRI) <<
"=g" << State->GetGroup(Reg)
212 <<
"->g0(region live-out)");
213 State->UnionGroups(Reg, 0);
214 }
else if ((DefIndices[Reg] < InsertPosIndex)
215 && (DefIndices[Reg] >=
Count)) {
216 DefIndices[Reg] =
Count;
233 Op =
MI.findRegisterUseOperand(Reg,
nullptr,
true);
235 Op =
MI.findRegisterDefOperand(Reg,
nullptr);
237 return(
Op &&
Op->isImplicit());
240void AggressiveAntiDepBreaker::GetPassthruRegs(
242 for (
unsigned i = 0, e =
MI.getNumOperands(); i != e; ++i) {
244 if (!MO.
isReg())
continue;
245 if ((MO.
isDef() &&
MI.isRegTiedToUseOperand(i)) ||
246 IsImplicitDefUse(
MI, MO)) {
249 PassthruRegs.insert(
SubReg);
260 if (RegSet.
insert(Pred.getReg()).second)
261 Edges.push_back(&Pred);
270 unsigned NextDepth = 0;
274 const SUnit *PredSU = Pred.getSUnit();
275 unsigned PredLatency = Pred.getLatency();
276 unsigned PredTotalLatency = PredSU->
getDepth() + PredLatency;
279 if (NextDepth < PredTotalLatency ||
280 (NextDepth == PredTotalLatency && Pred.getKind() ==
SDep::Anti)) {
281 NextDepth = PredTotalLatency;
287 return (
Next) ?
Next->getSUnit() :
nullptr;
290void AggressiveAntiDepBreaker::HandleLastUse(
MCRegister Reg,
unsigned KillIdx,
293 const char *footer) {
294 std::vector<unsigned> &KillIndices = State->GetKillIndices();
295 std::vector<unsigned> &DefIndices = State->GetDefIndices();
296 std::multimap<MCRegister, AggressiveAntiDepState::RegisterReference>
297 &RegRefs = State->GetRegRefs();
303 for (MCRegAliasIterator AI(
Reg, TRI,
true); AI.isValid(); ++AI)
304 if (TRI->isSuperRegister(
Reg, *AI) && State->IsLive(*AI)) {
309 if (!State->IsLive(
Reg)) {
310 KillIndices[
Reg] = KillIdx;
311 DefIndices[
Reg] = ~0
u;
313 State->LeaveGroup(
Reg);
324 if (!State->IsLive(SubregReg)) {
325 KillIndices[SubregReg] = KillIdx;
326 DefIndices[SubregReg] = ~0
u;
327 RegRefs.erase(SubregReg);
328 State->LeaveGroup(SubregReg);
334 << State->GetGroup(SubregReg) << tag);
342void AggressiveAntiDepBreaker::PrescanInstruction(
344 const std::set<MCRegister> &PassthruRegs) {
345 std::vector<unsigned> &DefIndices = State->GetDefIndices();
346 std::multimap<MCRegister, AggressiveAntiDepState::RegisterReference>
347 &RegRefs = State->GetRegRefs();
354 for (
const MachineOperand &MO :
MI.all_defs()) {
363 for (
unsigned i = 0, e =
MI.getNumOperands(); i != e; ++i) {
364 MachineOperand &MO =
MI.getOperand(i);
371 << State->GetGroup(
Reg));
378 if (
MI.isCall() ||
MI.hasExtraDefRegAllocReq() || TII->isPredicated(
MI) ||
381 State->UnionGroups(
Reg, 0);
386 for (MCRegAliasIterator AI(
Reg, TRI,
false); AI.isValid(); ++AI) {
387 MCRegister AliasReg = *AI;
388 if (State->IsLive(AliasReg)) {
389 State->UnionGroups(
Reg, AliasReg);
396 const TargetRegisterClass *RC =
nullptr;
397 if (i <
MI.getDesc().getNumOperands())
398 RC = TII->getRegClass(
MI.getDesc(), i, TRI, MF);
399 AggressiveAntiDepState::RegisterReference RR = { &MO, RC };
407 for (
const MachineOperand &MO :
MI.all_defs()) {
412 if (
MI.isKill() || (PassthruRegs.count(
Reg) != 0))
416 for (MCRegAliasIterator AI(
Reg, TRI,
true); AI.isValid(); ++AI) {
423 if (TRI->isSuperRegister(
Reg, *AI) && State->IsLive(*AI))
426 DefIndices[(*AI).id()] =
Count;
434 std::multimap<MCRegister, AggressiveAntiDepState::RegisterReference>
435 &RegRefs = State->GetRegRefs();
454 bool Special =
MI.isCall() ||
MI.hasExtraSrcRegAllocReq() ||
455 TII->isPredicated(
MI) ||
MI.isInlineAsm();
459 for (
unsigned i = 0, e =
MI.getNumOperands(); i != e; ++i) {
460 MachineOperand &MO =
MI.getOperand(i);
467 << State->GetGroup(
Reg));
476 State->UnionGroups(
Reg, 0);
480 const TargetRegisterClass *RC =
nullptr;
481 if (i <
MI.getDesc().getNumOperands())
482 RC = TII->getRegClass(
MI.getDesc(), i, TRI, MF);
483 AggressiveAntiDepState::RegisterReference RR = { &MO, RC };
495 for (
const MachineOperand &MO :
MI.operands()) {
496 if (!MO.
isReg())
continue;
503 State->UnionGroups(FirstReg,
Reg);
515 BitVector BV(TRI->getNumRegs(),
false);
521 for (
const auto &Q :
make_range(State->GetRegRefs().equal_range(
Reg))) {
522 const TargetRegisterClass *RC = Q.second.RC;
525 BitVector RCBV = TRI->getAllocatableSet(MF, RC);
539bool AggressiveAntiDepBreaker::FindSuitableFreeRegisters(
540 MCRegister SuperReg,
unsigned AntiDepGroupIndex,
541 RenameOrderType &RenameOrder, std::map<MCRegister, MCRegister> &RenameMap) {
542 std::vector<unsigned> &KillIndices = State->GetKillIndices();
543 std::vector<unsigned> &DefIndices = State->GetDefIndices();
544 std::multimap<MCRegister, AggressiveAntiDepState::RegisterReference>
545 &RegRefs = State->GetRegRefs();
550 std::vector<MCRegister> Regs;
551 State->GetGroupRegs(AntiDepGroupIndex, Regs, &RegRefs);
552 assert(!Regs.empty() &&
"Empty register group!");
558 LLVM_DEBUG(
dbgs() <<
"\tRename Candidates for Group g" << AntiDepGroupIndex
560 std::map<MCRegister, BitVector> RenameRegisterMap;
561 for (MCRegister
Reg : Regs) {
563 if (RegRefs.count(
Reg) > 0) {
566 BitVector &BV = RenameRegisterMap[
Reg];
568 BV = GetRenameRegisters(
Reg);
580 for (MCRegister
Reg : Regs) {
581 if (
Reg == SuperReg)
continue;
582 bool IsSub = TRI->isSubRegister(SuperReg,
Reg);
593 static int renamecnt = 0;
597 dbgs() <<
"*** Performing rename " <<
printReg(SuperReg, TRI)
598 <<
" for debug ***\n";
610 const TargetRegisterClass *SuperRC =
611 TRI->getMinimalPhysRegClass(SuperReg, MVT::Other);
621 RenameOrder.insert(RenameOrderType::value_type(SuperRC, Order.
size()));
623 unsigned OrigR = RenameOrder[SuperRC];
624 unsigned EndR = ((OrigR == Order.
size()) ? 0 : OrigR);
627 if (R == 0)
R = Order.
size();
629 const MCRegister NewSuperReg = Order[
R];
631 if (!MRI.isAllocatable(NewSuperReg))
continue;
633 if (NewSuperReg == SuperReg)
continue;
641 for (MCRegister
Reg : Regs) {
643 if (
Reg == SuperReg) {
644 NewReg = NewSuperReg;
646 unsigned NewSubRegIdx = TRI->getSubRegIndex(SuperReg,
Reg);
647 if (NewSubRegIdx != 0)
648 NewReg = TRI->getSubReg(NewSuperReg, NewSubRegIdx);
654 if (!RenameRegisterMap[
Reg].
test(NewReg)) {
663 if (State->IsLive(NewReg) || (KillIndices[
Reg] > DefIndices[NewReg])) {
668 for (MCRegAliasIterator AI(NewReg, TRI,
false); AI.isValid(); ++AI) {
669 MCRegister AliasReg = *AI;
670 if (State->IsLive(AliasReg) ||
671 (KillIndices[
Reg] > DefIndices[AliasReg])) {
673 <<
"(alias " <<
printReg(AliasReg, TRI) <<
" live)");
700 if (!Q.second.Operand->isDef() || !Q.second.Operand->isEarlyClobber())
711 RenameMap.insert(std::make_pair(
Reg, NewReg));
716 RenameOrder.erase(SuperRC);
717 RenameOrder.insert(RenameOrderType::value_type(SuperRC, R));
734 const std::vector<SUnit> &SUnits,
737 unsigned InsertPosIndex,
739 std::vector<unsigned> &KillIndices = State->GetKillIndices();
740 std::vector<unsigned> &DefIndices = State->GetDefIndices();
741 std::multimap<MCRegister, AggressiveAntiDepState::RegisterReference>
742 &RegRefs = State->GetRegRefs();
746 if (SUnits.empty())
return 0;
749 RenameOrderType RenameOrder;
752 std::map<MachineInstr *, const SUnit *> MISUnitMap;
753 for (
const SUnit &SU : SUnits)
754 MISUnitMap.insert(std::make_pair(SU.getInstr(), &SU));
759 const SUnit *CriticalPathSU =
nullptr;
761 if (CriticalPathSet.any()) {
762 for (
const SUnit &SU : SUnits) {
763 if (!CriticalPathSU ||
764 ((SU.getDepth() + SU.Latency) >
766 CriticalPathSU = &SU;
769 assert(CriticalPathSU &&
"Failed to find SUnit critical path");
770 CriticalPathMI = CriticalPathSU->
getInstr();
774 LLVM_DEBUG(
dbgs() <<
"\n===== Aggressive anti-dependency breaking\n");
776 for (
unsigned Reg = 1; Reg < TRI->getNumRegs(); ++Reg) {
777 if (!State->IsLive(Reg))
789 unsigned Count = InsertPosIndex - 1;
794 if (
MI.isDebugInstr())
800 std::set<MCRegister> PassthruRegs;
801 GetPassthruRegs(
MI, PassthruRegs);
804 PrescanInstruction(
MI,
Count, PassthruRegs);
808 std::vector<const SDep *> Edges;
809 const SUnit *PathSU = MISUnitMap[&
MI];
815 if (&
MI == CriticalPathMI) {
817 CriticalPathMI = (CriticalPathSU) ? CriticalPathSU->
getInstr() :
nullptr;
818 }
else if (CriticalPathSet.any()) {
819 ExcludeRegs = &CriticalPathSet;
826 for (
const SDep *Edge : Edges) {
827 SUnit *NextSU = Edge->getSUnit();
832 MCRegister AntiDepReg = Edge->getReg().asMCReg();
834 assert(AntiDepReg &&
"Anti-dependence on reg0?");
836 if (!MRI.isAllocatable(AntiDepReg)) {
840 }
else if (ExcludeRegs && ExcludeRegs->
test(AntiDepReg.
id())) {
845 }
else if (PassthruRegs.count(AntiDepReg) != 0) {
854 MI.findRegisterDefOperand(AntiDepReg,
nullptr);
855 assert(AntiDepOp &&
"Can't find index for defined register operand");
871 if (Pred.getSUnit() == NextSU ? (Pred.getKind() !=
SDep::Anti ||
872 Pred.getReg() != AntiDepReg)
874 Pred.getReg() == AntiDepReg)) {
880 if ((Pred.getSUnit() == NextSU) && (Pred.getKind() !=
SDep::Anti) &&
885 }
else if ((Pred.getSUnit() != NextSU) &&
887 (Pred.getReg() == AntiDepReg)) {
901 const unsigned GroupIndex = State->GetGroup(AntiDepReg);
902 if (GroupIndex == 0) {
910 std::map<MCRegister, MCRegister> RenameMap;
911 if (FindSuitableFreeRegisters(AntiDepReg, GroupIndex, RenameOrder,
914 <<
printReg(AntiDepReg, TRI) <<
":");
917 for (
const auto &
P : RenameMap) {
923 << RegRefs.count(CurrReg) <<
" refs)");
927 for (
const auto &Q :
make_range(RegRefs.equal_range(CurrReg))) {
928 Q.second.Operand->setReg(NewReg);
932 const SUnit *SU = MISUnitMap[Q.second.Operand->getParent()];
941 State->UnionGroups(NewReg, 0);
942 RegRefs.erase(NewReg);
943 DefIndices[NewReg] = DefIndices[CurrReg];
944 KillIndices[NewReg] = KillIndices[CurrReg];
946 State->UnionGroups(CurrReg, 0);
947 RegRefs.erase(CurrReg);
948 DefIndices[CurrReg] = KillIndices[CurrReg];
949 KillIndices[CurrReg] = ~0u;
950 assert(((KillIndices[CurrReg] == ~0u) !=
951 (DefIndices[CurrReg] == ~0u)) &&
952 "Kill and Def maps aren't consistent for AntiDepReg!");
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static void AntiDepEdges(const SUnit *SU, std::vector< const SDep * > &Edges)
AntiDepEdges - Return in Edges the anti- and output- dependencies in SU that we want to consider for ...
static const SUnit * CriticalPathStep(const SUnit *SU)
CriticalPathStep - Return the next SUnit after SU on the bottom-up critical path.
static cl::opt< int > DebugDiv("agg-antidep-debugdiv", cl::desc("Debug control for aggressive anti-dep breaker"), cl::init(0), cl::Hidden)
static cl::opt< int > DebugMod("agg-antidep-debugmod", cl::desc("Debug control for aggressive anti-dep breaker"), cl::init(0), cl::Hidden)
Register const TargetRegisterInfo * TRI
Promote Memory to Register
This file defines the SmallSet class.
void Observe(MachineInstr &MI, unsigned Count, unsigned InsertPosIndex) override
Update liveness information to account for the current instruction, which will not be scheduled.
void FinishBlock() override
Finish anti-dep breaking for a basic block.
~AggressiveAntiDepBreaker() 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 StartBlock(MachineBasicBlock *BB) override
Initialize anti-dep breaking for a new basic block.
AggressiveAntiDepBreaker(MachineFunction &MFi, const RegisterClassInfo &RCI, TargetSubtargetInfo::RegClassVector &CriticalPathRCs)
Contains all the state necessary for anti-dep breaking.
AggressiveAntiDepState(const unsigned TargetRegs, MachineBasicBlock *BB)
void GetGroupRegs(unsigned Group, std::vector< MCRegister > &Regs, std::multimap< MCRegister, AggressiveAntiDepState::RegisterReference > *RegRefs)
unsigned LeaveGroup(MCRegister Reg)
bool IsLive(MCRegister Reg)
Return true if Reg is live.
unsigned GetGroup(MCRegister Reg)
unsigned UnionGroups(MCRegister Reg1, MCRegister Reg2)
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
size_t size() const
size - Get the array size.
bool empty() const
empty - Check if the array is empty.
bool test(unsigned Idx) const
iterator_range< const_set_bits_iterator > set_bits() const
bool empty() const
empty - Tests whether there are no bits in this bitvector.
MCRegAliasIterator enumerates all registers aliasing Reg.
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()
MachineInstrBundleIterator< MachineInstr > iterator
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.
Representation of each machine instruction.
const MachineBasicBlock * getParent() const
bool readsRegister(Register Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr reads the specified register.
const MachineOperand & getOperand(unsigned i) const
LLVM_ABI int findRegisterDefOperandIdx(Register Reg, const TargetRegisterInfo *TRI, bool isDead=false, bool Overlap=false) const
Returns the operand index that is a def of the specified register or -1 if it is not found.
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isEarlyClobber() const
Register getReg() const
getReg - Returns the register number.
Wrapper class representing virtual and physical registers.
MCRegister asMCReg() const
Utility to check-convert this value to a MCRegister.
@ Output
A register output-dependence (aka WAW).
@ 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 short Latency
Node latency.
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.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
SmallVectorImpl< const TargetRegisterClass * > RegClassVector
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
AntiDepBreaker * createAggressiveAntiDepBreaker(MachineFunction &MFi, const RegisterClassInfo &RCI, TargetSubtargetInfo::RegClassVector &CriticalPathRCs)
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionAddr VTableAddr Count
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
FunctionAddr VTableAddr Next
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
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.