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];
72 while (GroupNodes[Node] != Node)
73 Node = GroupNodes[Node];
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) {
128 if (CriticalPathSet.
none())
129 CriticalPathSet = CPSet;
131 CriticalPathSet |= CPSet;
155 for (
const auto &LI : Succ->liveins()) {
159 KillIndices[Reg] = BB->
size();
160 DefIndices[Reg] = ~0u;
172 if (!IsReturnBlock && !Pristine.
test(Reg))
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);
195 ScanInstruction(
MI, Count);
202 for (
unsigned Reg = 1; Reg != TRI->
getNumRegs(); ++Reg) {
212 <<
"->g0(region live-out)");
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);
261 Edges.push_back(&Pred);
269 const SDep *Next =
nullptr;
270 unsigned NextDepth = 0;
276 unsigned PredTotalLatency = PredSU->
getDepth() + PredLatency;
279 if (NextDepth < PredTotalLatency ||
281 NextDepth = PredTotalLatency;
287 return (Next) ? Next->
getSUnit() :
nullptr;
290void AggressiveAntiDepBreaker::HandleLastUse(
MCRegister Reg,
unsigned KillIdx,
293 const char *footer) {
296 std::multimap<MCRegister, AggressiveAntiDepState::RegisterReference>
309 if (!State->
IsLive(Reg)) {
310 KillIndices[
Reg] = KillIdx;
311 DefIndices[
Reg] = ~0
u;
324 if (!State->
IsLive(SubregReg)) {
325 KillIndices[SubregReg] = KillIdx;
326 DefIndices[SubregReg] = ~0
u;
327 RegRefs.erase(SubregReg);
334 << State->
GetGroup(SubregReg) << tag);
342void AggressiveAntiDepBreaker::PrescanInstruction(
344 const std::set<MCRegister> &PassthruRegs) {
346 std::multimap<MCRegister, AggressiveAntiDepState::RegisterReference>
359 HandleLastUse(
Reg.asMCReg(), Count + 1,
"",
"\tDead Def: ",
"\n");
363 for (
unsigned i = 0, e =
MI.getNumOperands(); i != e; ++i) {
388 if (State->
IsLive(AliasReg)) {
397 if (i <
MI.getDesc().getNumOperands())
400 RegRefs.emplace(
Reg.asMCReg(), RR);
412 if (
MI.isKill() || (PassthruRegs.count(Reg) != 0))
426 DefIndices[(*AI).id()] = Count;
434 std::multimap<MCRegister, AggressiveAntiDepState::RegisterReference>
454 bool Special =
MI.isCall() ||
MI.hasExtraSrcRegAllocReq() ||
459 for (
unsigned i = 0, e =
MI.getNumOperands(); i != e; ++i) {
472 HandleLastUse(
Reg.asMCReg(), Count,
"(last-use)");
481 if (i <
MI.getDesc().getNumOperands())
484 RegRefs.emplace(
Reg.asMCReg(), RR);
496 if (!MO.
isReg())
continue;
539bool AggressiveAntiDepBreaker::FindSuitableFreeRegisters(
540 MCRegister SuperReg,
unsigned AntiDepGroupIndex,
541 RenameOrderType &RenameOrder, std::map<MCRegister, MCRegister> &RenameMap) {
544 std::multimap<MCRegister, AggressiveAntiDepState::RegisterReference>
550 std::vector<MCRegister> Regs;
552 assert(!Regs.empty() &&
"Empty register group!");
558 LLVM_DEBUG(
dbgs() <<
"\tRename Candidates for Group g" << AntiDepGroupIndex
560 std::map<MCRegister, BitVector> RenameRegisterMap;
563 if (RegRefs.count(Reg) > 0) {
568 BV = GetRenameRegisters(Reg);
581 if (Reg == SuperReg)
continue;
593 static int renamecnt = 0;
597 dbgs() <<
"*** Performing rename " <<
printReg(SuperReg, TRI)
598 <<
" for debug ***\n";
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();
633 if (NewSuperReg == SuperReg)
continue;
643 if (Reg == SuperReg) {
644 NewReg = NewSuperReg;
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])) {
670 if (State->
IsLive(AliasReg) ||
671 (KillIndices[Reg] > DefIndices[AliasReg])) {
673 <<
"(alias " <<
printReg(AliasReg, TRI) <<
" live)");
684 for (
const auto &Q :
make_range(RegRefs.equal_range(Reg))) {
699 for (
const auto &Q :
make_range(RegRefs.equal_range(Reg))) {
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,
741 std::multimap<MCRegister, AggressiveAntiDepState::RegisterReference>
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) {
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;
834 assert(AntiDepReg &&
"Anti-dependence on reg0?");
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");
872 Pred.
getReg() != AntiDepReg)
874 Pred.
getReg() == AntiDepReg)) {
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()];
942 RegRefs.erase(NewReg);
943 DefIndices[NewReg] = DefIndices[CurrReg];
944 KillIndices[NewReg] = KillIndices[CurrReg];
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!");
961 ScanInstruction(
MI, Count);
unsigned const MachineRegisterInfo * MRI
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)
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
const HexagonInstrInfo * TII
Register const TargetRegisterInfo * TRI
std::pair< BasicBlock *, BasicBlock * > Edge
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)
std::vector< unsigned > & GetDefIndices()
Return the define indices.
bool IsLive(MCRegister Reg)
Return true if Reg is live.
unsigned GetGroup(MCRegister Reg)
unsigned UnionGroups(MCRegister Reg1, MCRegister Reg2)
std::vector< unsigned > & GetKillIndices()
Return the kill indices.
std::multimap< MCRegister, RegisterReference > & GetRegRefs()
Return the RegRefs map.
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),...
size_t size() const
size - Get the array size.
bool empty() const
empty - Check if the array is empty.
bool test(unsigned Idx) const
bool any() const
any - Returns true if any bit is set.
bool none() const
none - Returns true if none of the bits are set.
iterator_range< const_set_bits_iterator > set_bits() const
bool empty() const
empty - Tests whether there are no bits in this bitvector.
This class represents an Operation in the Expression.
MCRegAliasIterator enumerates all registers aliasing Reg.
iterator_range< MCSubRegIterator > subregs_inclusive(MCRegister Reg) const
Return an iterator range over all sub-registers of Reg, including Reg.
bool isSubRegister(MCRegister RegA, MCRegister RegB) const
Returns true if RegB is a sub-register of RegA.
iterator_range< MCSubRegIterator > subregs(MCRegister Reg) const
Return an iterator range over all sub-registers of Reg, excluding Reg.
unsigned getSubRegIndex(MCRegister RegNo, MCRegister SubRegNo) const
For a given register pair, return the sub-register index if the second register is a sub-register of ...
bool isSuperRegister(MCRegister RegA, MCRegister RegB) const
Returns true if RegB is a super-register of RegA.
MCRegister getSubReg(MCRegister Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo.
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.
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.
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.
Kind getKind() const
Returns an enum value representing the kind of the dependence.
@ Output
A register output-dependence (aka WAW).
@ Anti
A register anti-dependence (aka WAR).
@ Data
Regular data dependence (aka true-dependence).
unsigned getLatency() const
Returns the latency value for this edge, which roughly means the minimum number of cycles that must e...
Register getReg() const
Returns the register associated with this edge.
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.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
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,...
const TargetRegisterClass * getMinimalPhysRegClass(MCRegister Reg, MVT VT=MVT::Other) const
Returns the Register Class of a physical register of the given type, picking the most sub register cl...
const char * getRegClassName(const TargetRegisterClass *Class) const
Returns the name of the register class.
BitVector getAllocatableSet(const MachineFunction &MF, const TargetRegisterClass *RC=nullptr) const
Returns a bitset indexed by register number indicating if a register is allocatable or not.
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
Reg
All possible values of the reg field in the ModR/M byte.
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.
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.
Information about a register reference within a liverange.