17 #define DEBUG_TYPE "post-RA-sched"
35 cl::desc(
"Debug control for aggressive anti-dep breaker"),
39 cl::desc(
"Debug control for aggressive anti-dep breaker"),
44 NumTargetRegs(TargetRegs), GroupNodes(TargetRegs, 0),
45 GroupNodeIndices(TargetRegs, 0),
46 KillIndices(TargetRegs, 0),
47 DefIndices(TargetRegs, 0)
49 const unsigned BBSize = BB->
size();
50 for (
unsigned i = 0; i < NumTargetRegs; ++i) {
53 GroupNodeIndices[i] = i;
56 DefIndices[i] = BBSize;
61 unsigned Node = GroupNodeIndices[
Reg];
62 while (GroupNodes[Node] != Node)
63 Node = GroupNodes[Node];
70 std::vector<unsigned> &Regs,
71 std::multimap<unsigned, AggressiveAntiDepState::RegisterReference> *RegRefs)
73 for (
unsigned Reg = 0;
Reg != NumTargetRegs; ++
Reg) {
81 assert(GroupNodes[0] == 0 &&
"GroupNode 0 not parent!");
82 assert(GroupNodeIndices[0] == 0 &&
"Reg 0 not in Group 0!");
89 unsigned Parent = (Group1 == 0) ? Group1 : Group2;
90 unsigned Other = (Parent == Group1) ? Group2 : Group1;
91 GroupNodes.at(Other) = Parent;
100 unsigned idx = GroupNodes.size();
101 GroupNodes.push_back(idx);
102 GroupNodeIndices[
Reg] = idx;
110 return((KillIndices[Reg] != ~0u) && (DefIndices[Reg] == ~0u));
120 MRI(MF.getRegInfo()),
121 TII(MF.getTarget().getInstrInfo()),
122 TRI(MF.getTarget().getRegisterInfo()),
127 for (
unsigned i = 0, e = CriticalPathRCs.
size(); i < e; ++i) {
129 if (CriticalPathSet.
none())
130 CriticalPathSet = CPSet;
132 CriticalPathSet |= CPSet;
135 DEBUG(
dbgs() <<
"AntiDep Critical-Path Registers:");
147 assert(State == NULL);
156 SE = BB->
succ_end(); SI != SE; ++SI)
158 E = (*SI)->livein_end();
I != E; ++
I) {
163 DefIndices[
Reg] = ~0u;
174 if (!IsReturnBlock && !Pristine.
test(Reg))
continue;
176 unsigned AliasReg = *AI;
178 KillIndices[AliasReg] = BB->
size();
179 DefIndices[AliasReg] = ~0u;
190 unsigned InsertPosIndex) {
191 assert(Count < InsertPosIndex &&
"Instruction index out of expected range!");
193 std::set<unsigned> PassthruRegs;
194 GetPassthruRegs(MI, PassthruRegs);
195 PrescanInstruction(MI, Count, PassthruRegs);
196 ScanInstruction(MI, Count);
215 }
else if ((DefIndices[
Reg] < InsertPosIndex)
216 && (DefIndices[
Reg] >= Count)) {
217 DefIndices[
Reg] = Count;
242 void AggressiveAntiDepBreaker::GetPassthruRegs(
MachineInstr *MI,
243 std::set<unsigned>& PassthruRegs) {
246 if (!MO.
isReg())
continue;
248 IsImplicitDefUse(MI, MO)) {
249 const unsigned Reg = MO.
getReg();
252 PassthruRegs.insert(*SubRegs);
264 unsigned Reg =
P->getReg();
265 if (RegSet.
count(Reg) == 0) {
266 Edges.push_back(&*
P);
276 const SDep *Next = 0;
277 unsigned NextDepth = 0;
282 const SUnit *PredSU =
P->getSUnit();
283 unsigned PredLatency =
P->getLatency();
284 unsigned PredTotalLatency = PredSU->
getDepth() + PredLatency;
287 if (NextDepth < PredTotalLatency ||
288 (NextDepth == PredTotalLatency &&
P->getKind() ==
SDep::Anti)) {
289 NextDepth = PredTotalLatency;
295 return (Next) ? Next->
getSUnit() : 0;
298 void AggressiveAntiDepBreaker::HandleLastUse(
unsigned Reg,
unsigned KillIdx,
301 const char *footer) {
304 std::multimap<unsigned, AggressiveAntiDepState::RegisterReference>&
307 if (!State->
IsLive(Reg)) {
308 KillIndices[
Reg] = KillIdx;
309 DefIndices[
Reg] = ~0u;
312 DEBUG(
if (header != NULL) {
313 dbgs() << header << TRI->
getName(Reg); header = NULL; });
318 unsigned SubregReg = *SubRegs;
319 if (!State->
IsLive(SubregReg)) {
320 KillIndices[SubregReg] = KillIdx;
321 DefIndices[SubregReg] = ~0u;
322 RegRefs.erase(SubregReg);
324 DEBUG(
if (header != NULL) {
325 dbgs() << header << TRI->
getName(Reg); header = NULL; });
331 DEBUG(
if ((header == NULL) && (footer != NULL))
dbgs() << footer);
334 void AggressiveAntiDepBreaker::PrescanInstruction(
MachineInstr *MI,
336 std::set<unsigned>& PassthruRegs) {
338 std::multimap<unsigned, AggressiveAntiDepState::RegisterReference>&
349 unsigned Reg = MO.
getReg();
350 if (Reg == 0)
continue;
352 HandleLastUse(Reg, Count + 1,
"",
"\tDead Def: ",
"\n");
359 unsigned Reg = MO.
getReg();
360 if (Reg == 0)
continue;
376 unsigned AliasReg = *AI;
377 if (State->
IsLive(AliasReg)) {
380 TRI->
getName(AliasReg) <<
")");
386 if (i < MI->getDesc().getNumOperands())
389 RegRefs.insert(std::make_pair(Reg, RR));
399 unsigned Reg = MO.
getReg();
400 if (Reg == 0)
continue;
402 if (MI->
isKill() || (PassthruRegs.count(Reg) != 0))
407 DefIndices[*AI] = Count;
411 void AggressiveAntiDepBreaker::ScanInstruction(
MachineInstr *MI,
414 std::multimap<unsigned, AggressiveAntiDepState::RegisterReference>&
433 bool Special = MI->
isCall() ||
442 unsigned Reg = MO.
getReg();
443 if (Reg == 0)
continue;
445 DEBUG(
dbgs() <<
" " << TRI->getName(Reg) <<
"=g" <<
451 HandleLastUse(Reg, Count,
"(last-use)");
460 if (i < MI->getDesc().getNumOperands())
463 RegRefs.insert(std::make_pair(Reg, RR));
473 unsigned FirstReg = 0;
476 if (!MO.
isReg())
continue;
477 unsigned Reg = MO.
getReg();
478 if (Reg == 0)
continue;
481 DEBUG(
dbgs() <<
"=" << TRI->getName(Reg));
484 DEBUG(
dbgs() <<
" " << TRI->getName(Reg));
493 BitVector AggressiveAntiDepBreaker::GetRenameRegisters(
unsigned Reg) {
502 std::multimap<unsigned,
505 for (std::multimap<
unsigned,
507 QE = Range.second; Q != QE; ++Q) {
509 if (RC == NULL)
continue;
511 BitVector RCBV = TRI->getAllocatableSet(MF, RC);
525 bool AggressiveAntiDepBreaker::FindSuitableFreeRegisters(
526 unsigned AntiDepGroupIndex,
527 RenameOrderType& RenameOrder,
528 std::map<unsigned, unsigned> &RenameMap) {
531 std::multimap<unsigned, AggressiveAntiDepState::RegisterReference>&
537 std::vector<unsigned> Regs;
539 assert(Regs.size() > 0 &&
"Empty register group!");
540 if (Regs.size() == 0)
546 DEBUG(
dbgs() <<
"\tRename Candidates for Group g" << AntiDepGroupIndex
548 std::map<unsigned, BitVector> RenameRegisterMap;
549 unsigned SuperReg = 0;
550 for (
unsigned i = 0, e = Regs.size(); i != e; ++i) {
551 unsigned Reg = Regs[i];
552 if ((SuperReg == 0) || TRI->isSuperRegister(SuperReg, Reg))
556 if (RegRefs.count(Reg) > 0) {
557 DEBUG(
dbgs() <<
"\t\t" << TRI->getName(Reg) <<
":");
560 RenameRegisterMap.insert(std::pair<unsigned, BitVector>(Reg, BV));
563 DEBUG(
for (
int r = BV.find_first(); r != -1; r = BV.find_next(r))
564 dbgs() <<
" " << TRI->getName(r));
570 for (
unsigned i = 0, e = Regs.size(); i != e; ++i) {
571 unsigned Reg = Regs[i];
572 if (Reg == SuperReg)
continue;
573 bool IsSub = TRI->isSubRegister(SuperReg, Reg);
574 assert(IsSub &&
"Expecting group subregister");
582 static int renamecnt = 0;
586 dbgs() <<
"*** Performing rename " << TRI->getName(SuperReg) <<
600 TRI->getMinimalPhysRegClass(SuperReg,
MVT::Other);
604 DEBUG(
dbgs() <<
"\tEmpty Super Regclass!!\n");
610 if (RenameOrder.count(SuperRC) == 0)
611 RenameOrder.insert(RenameOrderType::value_type(SuperRC, Order.
size()));
613 unsigned OrigR = RenameOrder[SuperRC];
614 unsigned EndR = ((OrigR == Order.
size()) ? 0 : OrigR);
617 if (R == 0) R = Order.
size();
619 const unsigned NewSuperReg = Order[R];
623 if (NewSuperReg == SuperReg)
continue;
625 DEBUG(
dbgs() <<
" [" << TRI->getName(NewSuperReg) <<
':');
631 for (
unsigned i = 0, e = Regs.size(); i != e; ++i) {
632 unsigned Reg = Regs[i];
634 if (Reg == SuperReg) {
635 NewReg = NewSuperReg;
637 unsigned NewSubRegIdx = TRI->getSubRegIndex(SuperReg, Reg);
638 if (NewSubRegIdx != 0)
639 NewReg = TRI->getSubReg(NewSuperReg, NewSubRegIdx);
642 DEBUG(
dbgs() <<
" " << TRI->getName(NewReg));
646 if (!BV.test(NewReg)) {
655 if (State->
IsLive(NewReg) || (KillIndices[
Reg] > DefIndices[NewReg])) {
661 unsigned AliasReg = *AI;
662 if (State->
IsLive(AliasReg) ||
663 (KillIndices[
Reg] > DefIndices[AliasReg])) {
664 DEBUG(
dbgs() <<
"(alias " << TRI->getName(AliasReg) <<
" live)");
674 RenameMap.insert(std::pair<unsigned, unsigned>(Reg, NewReg));
679 RenameOrder.erase(SuperRC);
680 RenameOrder.insert(RenameOrderType::value_type(SuperRC, R));
698 const std::vector<SUnit>& SUnits,
701 unsigned InsertPosIndex,
706 std::multimap<unsigned, AggressiveAntiDepState::RegisterReference>&
711 if (SUnits.empty())
return 0;
714 RenameOrderType RenameOrder;
717 std::map<MachineInstr *, const SUnit *> MISUnitMap;
718 for (
unsigned i = 0, e = SUnits.size(); i != e; ++i) {
719 const SUnit *SU = &SUnits[i];
720 MISUnitMap.insert(std::pair<MachineInstr *, const SUnit *>(SU->
getInstr(),
727 const SUnit *CriticalPathSU = 0;
729 if (CriticalPathSet.
any()) {
730 for (
unsigned i = 0, e = SUnits.size(); i != e; ++i) {
731 const SUnit *SU = &SUnits[i];
732 if (!CriticalPathSU ||
739 CriticalPathMI = CriticalPathSU->
getInstr();
743 DEBUG(
dbgs() <<
"\n===== Aggressive anti-dependency breaking\n");
745 for (
unsigned Reg = 0; Reg < TRI->getNumRegs(); ++
Reg) {
747 DEBUG(
dbgs() <<
" " << TRI->getName(Reg));
756 unsigned Count = InsertPosIndex - 1;
767 std::set<unsigned> PassthruRegs;
768 GetPassthruRegs(MI, PassthruRegs);
771 PrescanInstruction(MI, Count, PassthruRegs);
775 std::vector<const SDep *> Edges;
776 const SUnit *PathSU = MISUnitMap[
MI];
782 if (MI == CriticalPathMI) {
784 CriticalPathMI = (CriticalPathSU) ? CriticalPathSU->
getInstr() : 0;
785 }
else if (CriticalPathSet.
any()) {
786 ExcludeRegs = &CriticalPathSet;
793 for (
unsigned i = 0, e = Edges.size(); i != e; ++i) {
794 const SDep *Edge = Edges[i];
800 unsigned AntiDepReg = Edge->
getReg();
801 DEBUG(
dbgs() <<
"\tAntidep reg: " << TRI->getName(AntiDepReg));
802 assert(AntiDepReg != 0 &&
"Anti-dependence on reg0?");
808 }
else if ((ExcludeRegs != NULL) && ExcludeRegs->
test(AntiDepReg)) {
811 DEBUG(
dbgs() <<
" (not critical-path)\n");
813 }
else if (PassthruRegs.count(AntiDepReg) != 0) {
822 assert(AntiDepOp != NULL &&
823 "Can't find index for defined register operand");
824 if ((AntiDepOp == NULL) || AntiDepOp->
isImplicit()) {
839 PE = PathSU->
Preds.end();
P != PE; ++
P) {
840 if (
P->getSUnit() == NextSU ?
841 (
P->getKind() !=
SDep::Anti ||
P->getReg() != AntiDepReg) :
842 (
P->getKind() ==
SDep::Data &&
P->getReg() == AntiDepReg)) {
848 PE = PathSU->
Preds.end();
P != PE; ++
P) {
849 if ((
P->getSUnit() == NextSU) && (
P->getKind() !=
SDep::Anti) &&
854 }
else if ((
P->getSUnit() != NextSU) &&
856 (
P->getReg() == AntiDepReg)) {
857 DEBUG(
dbgs() <<
" (other dependency)\n");
863 if (AntiDepReg == 0)
continue;
866 assert(AntiDepReg != 0);
867 if (AntiDepReg == 0)
continue;
870 const unsigned GroupIndex = State->
GetGroup(AntiDepReg);
871 if (GroupIndex == 0) {
879 std::map<unsigned, unsigned> RenameMap;
880 if (FindSuitableFreeRegisters(GroupIndex, RenameOrder, RenameMap)) {
881 DEBUG(
dbgs() <<
"\tBreaking anti-dependence edge on "
882 << TRI->getName(AntiDepReg) <<
":");
885 for (std::map<unsigned, unsigned>::iterator
886 S = RenameMap.begin(), E = RenameMap.end(); S != E; ++S) {
887 unsigned CurrReg = S->first;
888 unsigned NewReg = S->second;
890 DEBUG(
dbgs() <<
" " << TRI->getName(CurrReg) <<
"->" <<
891 TRI->getName(NewReg) <<
"(" <<
892 RegRefs.count(CurrReg) <<
" refs)");
896 std::pair<std::multimap<unsigned,
898 std::multimap<unsigned,
900 Range = RegRefs.equal_range(CurrReg);
901 for (std::multimap<
unsigned,
903 Q = Range.first, QE = Range.second; Q != QE; ++Q) {
908 const SUnit *SU = MISUnitMap[Q->second.Operand->getParent()];
910 for (DbgValueVector::iterator DVI = DbgValues.begin(),
911 DVE = DbgValues.end(); DVI != DVE; ++DVI)
912 if (DVI->second == Q->second.Operand->getParent())
920 RegRefs.erase(NewReg);
921 DefIndices[NewReg] = DefIndices[CurrReg];
922 KillIndices[NewReg] = KillIndices[CurrReg];
925 RegRefs.erase(CurrReg);
926 DefIndices[CurrReg] = KillIndices[CurrReg];
927 KillIndices[CurrReg] = ~0u;
928 assert(((KillIndices[CurrReg] == ~0u) !=
929 (DefIndices[CurrReg] == ~0u)) &&
930 "Kill and Def maps aren't consistent for AntiDepReg!");
939 ScanInstruction(MI, Count);
bool isValid() const
isValid - returns true if this iterator is not yet at the end.
MachineOperand * Operand
Operand - The registers operand.
bool none() const
none - Returns true if none of the bits are set.
void UpdateDbgValue(MachineInstr *MI, unsigned OldReg, unsigned NewReg)
int find_next(unsigned Prev) const
std::vector< unsigned >::const_iterator livein_iterator
AggressiveAntiDepState(const unsigned TargetRegs, MachineBasicBlock *BB)
MachineInstr * getInstr() const
const MCInstrDesc & getDesc() const
bool any() const
any - Returns true if any bit is set.
SmallVector< SDep, 4 > Preds
unsigned LeaveGroup(unsigned Reg)
A register anti-dependedence (aka WAR).
virtual const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF=0) const =0
~AggressiveAntiDepBreaker()
AggressiveAntiDepBreaker(MachineFunction &MFi, const RegisterClassInfo &RCI, TargetSubtargetInfo::RegClassVector &CriticalPathRCs)
unsigned GetGroup(unsigned Reg)
const HexagonInstrInfo * TII
const char * getName() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Regular data dependence (aka true-dependence).
std::vector< MachineBasicBlock * >::iterator succ_iterator
Abstract Stack Frame Information.
ArrayRef< MCPhysReg > getOrder(const TargetRegisterClass *RC) const
unsigned getNumOperands() const
unsigned getNumRegs() const
Return the number of registers this target has (useful for sizing arrays holding per register informa...
A register output-dependence (aka WAW).
static void AntiDepEdges(const SUnit *SU, std::vector< const SDep * > &Edges)
bool hasExtraSrcRegAllocReq(QueryType Type=AnyInBundle) const
void GetGroupRegs(unsigned Group, std::vector< unsigned > &Regs, std::multimap< unsigned, AggressiveAntiDepState::RegisterReference > *RegRefs)
unsigned UnionGroups(unsigned Reg1, unsigned Reg2)
size_t size() const
size - Get the array size.
void Observe(MachineInstr *MI, unsigned Count, unsigned InsertPosIndex)
bool isDebugValue() const
bundle_iterator< MachineInstr, instr_iterator > iterator
unsigned BreakAntiDependencies(const std::vector< SUnit > &SUnits, MachineBasicBlock::iterator Begin, MachineBasicBlock::iterator End, unsigned InsertPosIndex, DbgValueVector &DbgValues)
MachineOperand * findRegisterDefOperand(unsigned Reg, bool isDead=false, const TargetRegisterInfo *TRI=NULL)
initializer< Ty > init(const Ty &Val)
bool isReturn(QueryType Type=AnyInBundle) const
const MachineOperand & getOperand(unsigned i) const
BitVector getAllocatableSet(const MachineFunction &MF, const TargetRegisterClass *RC=NULL) const
void StartBlock(MachineBasicBlock *BB)
Start - Initialize anti-dep breaking for a new basic block.
static const SUnit * CriticalPathStep(const SUnit *SU)
bool empty() const
empty - Check if the array is empty.
succ_iterator succ_begin()
BitVector getPristineRegs(const MachineBasicBlock *MBB) const
MachineOperand * findRegisterUseOperand(unsigned Reg, bool isKill=false, const TargetRegisterInfo *TRI=NULL)
bool test(unsigned Idx) const
std::vector< unsigned > & GetDefIndices()
GetDefIndices - Return the define indices.
bool hasExtraDefRegAllocReq(QueryType Type=AnyInBundle) const
bool isAllocatable(unsigned PhysReg) const
MachineFrameInfo * getFrameInfo()
raw_ostream & dbgs()
dbgs - Return a circular-buffered debug stream.
unsigned getDepth() const
bool count(const T &V) const
count - Return true if the element is in the set.
std::multimap< unsigned, RegisterReference > & GetRegRefs()
GetRegRefs - Return the RegRefs map.
void setReg(unsigned Reg)
bool isCall(QueryType Type=AnyInBundle) const
Kind getKind() const
getKind - Return an enum value representing the kind of the dependence.
static cl::opt< int > DebugDiv("agg-antidep-debugdiv", cl::desc("Debug control for aggressive anti-dep breaker"), cl::init(0), cl::Hidden)
unsigned getReg() const
getReg - Returns the register number.
std::vector< std::pair< MachineInstr *, MachineInstr * > > DbgValueVector
const char * getName(unsigned RegNo) const
Return the human-readable symbolic target-specific name for the specified physical register...
virtual bool isPredicated(const MachineInstr *MI) const
const TargetRegisterClass * getRegClass(const MCInstrDesc &TID, unsigned OpNum, const TargetRegisterInfo *TRI, const MachineFunction &MF) const
const MCRegisterInfo & MRI
void FinishBlock()
Finish - Finish anti-dep breaking for a basic block.
static cl::opt< int > DebugMod("agg-antidep-debugmod", cl::desc("Debug control for aggressive anti-dep breaker"), cl::init(0), cl::Hidden)
bool isRegTiedToUseOperand(unsigned DefOpIdx, unsigned *UseOpIdx=0) const
bool IsLive(unsigned Reg)
IsLive - Return true if Reg is live.
std::vector< unsigned > & GetKillIndices()
GetKillIndices - Return the kill indices.
SUnit - Scheduling unit. This is a node in the scheduling DAG.