18 #define DEBUG_TYPE "pre-RA-sched"
39 STATISTIC(NumBacktracks,
"Number of times scheduler backtracked");
40 STATISTIC(NumUnfolds,
"Number of nodes unfolded");
41 STATISTIC(NumDups,
"Number of duplicated nodes");
42 STATISTIC(NumPRCopies,
"Number of physical register copies");
46 "Bottom-up register reduction list scheduling",
50 "Similar to list-burr but schedules in source "
51 "order when possible",
56 "Bottom-up register pressure aware list scheduling "
57 "which tries to balance latency and register pressure",
62 "Bottom-up register pressure aware list scheduling "
63 "which tries to balance ILP and register pressure",
68 cl::desc(
"Disable cycle-level precision during preRA scheduling"));
74 cl::desc(
"Disable regpressure priority in sched=list-ilp"));
77 cl::desc(
"Disable live use priority in sched=list-ilp"));
80 cl::desc(
"Disable virtual register cycle interference checks"));
83 cl::desc(
"Disable physreg def-use affinity"));
86 cl::desc(
"Disable no-stall priority in sched=list-ilp"));
89 cl::desc(
"Disable critical path priority in sched=list-ilp"));
92 cl::desc(
"Disable scheduled-height priority in sched=list-ilp"));
95 cl::desc(
"Disable scheduler's two-address hack"));
99 cl::desc(
"Number of instructions to allow ahead of the critical path "
100 "in sched=list-ilp"));
104 cl::desc(
"Average inst/cycle whan no target itinerary exists."));
124 std::vector<SUnit*> PendingQueue;
133 unsigned MinAvailableCycle;
142 unsigned NumLiveRegs;
143 std::vector<SUnit*> LiveRegDefs;
144 std::vector<SUnit*> LiveRegGens;
165 NeedLatency(needlatency), AvailableQueue(availqueue), CurCycle(0),
175 ~ScheduleDAGRRList() {
177 delete AvailableQueue;
185 bool IsReachable(
const SUnit *SU,
const SUnit *TargetSU) {
186 return Topo.IsReachable(SU, TargetSU);
191 bool WillCreateCycle(
SUnit *SU,
SUnit *TargetSU) {
192 return Topo.WillCreateCycle(SU, TargetSU);
206 void RemovePred(
SUnit *SU,
const SDep &D) {
212 bool isReady(
SUnit *SU) {
214 AvailableQueue->isReady(SU);
217 void ReleasePred(
SUnit *SU,
const SDep *PredEdge);
218 void ReleasePredecessors(
SUnit *SU);
219 void ReleasePending();
220 void AdvanceToCycle(
unsigned NextCycle);
221 void AdvancePastStalls(
SUnit *SU);
222 void EmitNode(
SUnit *SU);
223 void ScheduleNodeBottomUp(
SUnit*);
224 void CapturePred(
SDep *PredEdge);
225 void UnscheduleNodeBottomUp(
SUnit*);
226 void RestoreHazardCheckerBottomUp();
229 void InsertCopiesAndMoveSuccs(
SUnit*,
unsigned,
235 void releaseInterferences(
unsigned Reg = 0);
237 SUnit *PickNodeToScheduleBottomUp();
238 void ListScheduleBottomUp();
243 unsigned NumSUnits = SUnits.size();
244 SUnit *NewNode = newSUnit(N);
246 if (NewNode->
NodeNum >= NumSUnits)
247 Topo.InitDAGTopologicalSorting();
254 unsigned NumSUnits = SUnits.size();
255 SUnit *NewNode = Clone(N);
257 if (NewNode->
NodeNum >= NumSUnits)
258 Topo.InitDAGTopologicalSorting();
264 bool forceUnitLatencies()
const {
278 unsigned &RegClass,
unsigned &Cost,
291 RegClass = RC->
getID();
298 unsigned DstRCIdx = cast<ConstantSDNode>(Node->
getOperand(0))->getZExtValue();
300 RegClass = RC->
getID();
305 unsigned Idx = RegDefPos.
GetIdx();
308 RegClass = RC->
getID();
319 void ScheduleDAGRRList::Schedule() {
321 <<
"********** List Scheduling BB#" << BB->getNumber()
322 <<
" '" << BB->getName() <<
"' **********\n");
330 LiveRegDefs.resize(TRI->getNumRegs() + 1, NULL);
331 LiveRegGens.resize(TRI->getNumRegs() + 1, NULL);
332 CallSeqEndForStart.clear();
333 assert(Interferences.empty() && LRegsMap.empty() &&
"stale Interferences");
336 BuildSchedGraph(NULL);
338 DEBUG(
for (
unsigned su = 0, e = SUnits.size(); su != e; ++su)
339 SUnits[su].dumpAll(
this));
340 Topo.InitDAGTopologicalSorting();
342 AvailableQueue->initNodes(SUnits);
347 ListScheduleBottomUp();
349 AvailableQueue->releaseState();
352 dbgs() <<
"*** Final schedule ***\n";
364 void ScheduleDAGRRList::ReleasePred(
SUnit *SU,
const SDep *PredEdge) {
369 dbgs() <<
"*** Scheduling failed! ***\n";
371 dbgs() <<
" has been released too many times!\n";
377 if (!forceUnitLatencies()) {
389 if (Height < MinAvailableCycle)
390 MinAvailableCycle = Height;
392 if (isReady(PredSU)) {
393 AvailableQueue->push(PredSU);
399 PendingQueue.push_back(PredSU);
438 goto found_chain_operand;
441 found_chain_operand:;
465 unsigned BestMaxNest = MaxNest;
467 unsigned MyNestLevel = NestLevel;
468 unsigned MyMaxNest = MaxNest;
470 MyNestLevel, MyMaxNest,
TII))
471 if (!Best || (MyMaxNest > BestMaxNest)) {
473 BestMaxNest = MyMaxNest;
477 MaxNest = BestMaxNest;
485 MaxNest = std::max(MaxNest, NestLevel);
488 assert(NestLevel != 0);
498 goto found_chain_operand;
501 found_chain_operand:;
524 void ScheduleDAGRRList::ReleasePredecessors(
SUnit *SU) {
528 ReleasePred(SU, &*
I);
529 if (
I->isAssignedRegDep()) {
534 SUnit *RegDef = LiveRegDefs[
I->getReg()]; (void)RegDef;
535 assert((!RegDef || RegDef == SU || RegDef ==
I->getSUnit()) &&
536 "interference on register dependence");
537 LiveRegDefs[
I->getReg()] =
I->getSUnit();
538 if (!LiveRegGens[
I->getReg()]) {
540 LiveRegGens[
I->getReg()] = SU;
548 unsigned CallResource = TRI->getNumRegs();
549 if (!LiveRegDefs[CallResource])
551 if (Node->isMachineOpcode() &&
552 Node->getMachineOpcode() == (
unsigned)
TII->getCallFrameDestroyOpcode()) {
553 unsigned NestLevel = 0;
554 unsigned MaxNest = 0;
558 CallSeqEndForStart[
Def] = SU;
561 LiveRegDefs[CallResource] =
Def;
562 LiveRegGens[CallResource] = SU;
569 void ScheduleDAGRRList::ReleasePending() {
571 assert(PendingQueue.empty() &&
"pending instrs not allowed in this mode");
576 if (AvailableQueue->empty())
577 MinAvailableCycle = UINT_MAX;
581 for (
unsigned i = 0, e = PendingQueue.size(); i != e; ++i) {
582 unsigned ReadyCycle = PendingQueue[i]->
getHeight();
583 if (ReadyCycle < MinAvailableCycle)
584 MinAvailableCycle = ReadyCycle;
587 if (!isReady(PendingQueue[i]))
589 AvailableQueue->push(PendingQueue[i]);
591 PendingQueue[i]->isPending =
false;
592 PendingQueue[i] = PendingQueue.back();
593 PendingQueue.pop_back();
599 void ScheduleDAGRRList::AdvanceToCycle(
unsigned NextCycle) {
600 if (NextCycle <= CurCycle)
604 AvailableQueue->setCurCycle(NextCycle);
605 if (!HazardRec->isEnabled()) {
607 CurCycle = NextCycle;
610 for (; CurCycle != NextCycle; ++CurCycle) {
611 HazardRec->RecedeCycle();
621 void ScheduleDAGRRList::AdvancePastStalls(
SUnit *SU) {
638 AdvanceToCycle(ReadyCycle);
651 HazardRec->getHazardType(SU, -Stalls);
658 AdvanceToCycle(CurCycle + Stalls);
663 void ScheduleDAGRRList::EmitNode(
SUnit *SU) {
664 if (!HazardRec->isEnabled())
674 "This target-independent node should not be scheduled.");
697 HazardRec->EmitInstruction(SU);
705 void ScheduleDAGRRList::ScheduleNodeBottomUp(
SUnit *SU) {
706 DEBUG(
dbgs() <<
"\n*** Scheduling [" << CurCycle <<
"]: ");
710 if (CurCycle < SU->getHeight())
712 <<
"] pipeline stall!\n");
726 AvailableQueue->scheduledNode(SU);
731 if (!HazardRec->isEnabled() &&
AvgIPC < 2)
732 AdvanceToCycle(CurCycle + 1);
736 ReleasePredecessors(SU);
742 if (
I->isAssignedRegDep() && LiveRegDefs[
I->getReg()] == SU) {
743 assert(NumLiveRegs > 0 &&
"NumLiveRegs is already zero!");
745 LiveRegDefs[
I->getReg()] = NULL;
746 LiveRegGens[
I->getReg()] = NULL;
747 releaseInterferences(
I->getReg());
752 unsigned CallResource = TRI->getNumRegs();
753 if (LiveRegDefs[CallResource] == SU)
756 if (SUNode->isMachineOpcode() &&
757 SUNode->getMachineOpcode() == (
unsigned)
TII->getCallFrameSetupOpcode()) {
758 assert(NumLiveRegs > 0 &&
"NumLiveRegs is already zero!");
760 LiveRegDefs[CallResource] = NULL;
761 LiveRegGens[CallResource] = NULL;
762 releaseInterferences(CallResource);
778 if (HazardRec->isEnabled() ||
AvgIPC > 1) {
781 if ((HazardRec->isEnabled() && HazardRec->atIssueLimit())
782 || (!HazardRec->isEnabled() && IssueCount ==
AvgIPC))
783 AdvanceToCycle(CurCycle + 1);
790 void ScheduleDAGRRList::CapturePred(
SDep *PredEdge) {
795 AvailableQueue->remove(PredSU);
798 assert(PredSU->
NumSuccsLeft < UINT_MAX &&
"NumSuccsLeft will overflow!");
804 void ScheduleDAGRRList::UnscheduleNodeBottomUp(
SUnit *SU) {
811 if (
I->isAssignedRegDep() && SU == LiveRegGens[
I->getReg()]){
812 assert(NumLiveRegs > 0 &&
"NumLiveRegs is already zero!");
813 assert(LiveRegDefs[
I->getReg()] ==
I->getSUnit() &&
814 "Physical register dependency violated?");
816 LiveRegDefs[
I->getReg()] = NULL;
817 LiveRegGens[
I->getReg()] = NULL;
818 releaseInterferences(
I->getReg());
824 unsigned CallResource = TRI->getNumRegs();
827 if (SUNode->isMachineOpcode() &&
828 SUNode->getMachineOpcode() == (
unsigned)
TII->getCallFrameSetupOpcode()) {
830 LiveRegDefs[CallResource] = SU;
831 LiveRegGens[CallResource] = CallSeqEndForStart[SU];
837 if (LiveRegGens[CallResource] == SU)
840 if (SUNode->isMachineOpcode() &&
841 SUNode->getMachineOpcode() == (
unsigned)
TII->getCallFrameDestroyOpcode()) {
842 assert(NumLiveRegs > 0 &&
"NumLiveRegs is already zero!");
844 LiveRegDefs[CallResource] = NULL;
845 LiveRegGens[CallResource] = NULL;
846 releaseInterferences(CallResource);
852 if (
I->isAssignedRegDep()) {
853 if (!LiveRegDefs[
I->getReg()])
857 LiveRegDefs[
I->getReg()] = SU;
858 if (LiveRegGens[
I->getReg()] == NULL ||
859 I->getSUnit()->getHeight() < LiveRegGens[
I->getReg()]->getHeight())
860 LiveRegGens[
I->getReg()] =
I->getSUnit();
872 PendingQueue.push_back(SU);
875 AvailableQueue->push(SU);
877 AvailableQueue->unscheduledNode(SU);
882 void ScheduleDAGRRList::RestoreHazardCheckerBottomUp() {
885 unsigned LookAhead = std::min((
unsigned)
Sequence.size(),
886 HazardRec->getMaxLookAhead());
890 std::vector<SUnit*>::const_iterator
I = (
Sequence.end() - LookAhead);
891 unsigned HazardCycle = (*I)->getHeight();
892 for (std::vector<SUnit*>::const_iterator E =
Sequence.end(); I != E; ++
I) {
894 for (; SU->
getHeight() > HazardCycle; ++HazardCycle) {
895 HazardRec->RecedeCycle();
903 void ScheduleDAGRRList::BacktrackBottomUp(
SUnit *SU,
SUnit *BtSU) {
909 UnscheduleNodeBottomUp(OldSU);
910 AvailableQueue->setCurCycle(CurCycle);
916 assert(!SU->
isSucc(OldSU) &&
"Something is wrong!");
918 RestoreHazardCheckerBottomUp();
928 if (SUNode->isOperandOf(N))
936 SUnit *ScheduleDAGRRList::CopyAndMoveSuccessors(
SUnit *SU) {
945 bool TryUnfold =
false;
946 for (
unsigned i = 0, e = N->
getNumValues(); i != e; ++i) {
962 if (!
TII->unfoldMemoryOperand(*DAG, N, NewNodes))
967 if (NewNodes.
size() == 3)
971 assert(NewNodes.
size() == 2 &&
"Expected a load folding node!");
974 SDNode *LoadNode = NewNodes[0];
975 unsigned NumVals = N->getNumValues();
977 for (
unsigned i = 0; i != NumVals; ++i)
979 DAG->ReplaceAllUsesOfValueWith(
SDValue(SU->
getNode(), OldNumVals-1),
985 bool isNewLoad =
true;
991 LoadSU = CreateNewSUnit(LoadNode);
994 InitNumRegDefsLeft(LoadSU);
995 computeLatency(LoadSU);
998 SUnit *NewSU = CreateNewSUnit(N);
999 assert(N->getNodeId() == -1 &&
"Node already inserted!");
1012 InitNumRegDefsLeft(NewSU);
1013 computeLatency(NewSU);
1039 for (
unsigned i = 0, e = ChainPreds.
size(); i != e; ++i) {
1040 const SDep &Pred = ChainPreds[i];
1041 RemovePred(SU, Pred);
1043 AddPred(LoadSU, Pred);
1045 for (
unsigned i = 0, e = LoadPreds.
size(); i != e; ++i) {
1046 const SDep &Pred = LoadPreds[i];
1047 RemovePred(SU, Pred);
1049 AddPred(LoadSU, Pred);
1051 for (
unsigned i = 0, e = NodePreds.
size(); i != e; ++i) {
1052 const SDep &Pred = NodePreds[i];
1053 RemovePred(SU, Pred);
1054 AddPred(NewSU, Pred);
1056 for (
unsigned i = 0, e = NodeSuccs.
size(); i != e; ++i) {
1057 SDep D = NodeSuccs[i];
1060 RemovePred(SuccDep, D);
1062 AddPred(SuccDep, D);
1064 if (AvailableQueue->tracksRegPressure() && SuccDep->
isScheduled
1068 for (
unsigned i = 0, e = ChainSuccs.
size(); i != e; ++i) {
1069 SDep D = ChainSuccs[i];
1072 RemovePred(SuccDep, D);
1075 AddPred(SuccDep, D);
1086 AvailableQueue->addNode(LoadSU);
1087 AvailableQueue->addNode(NewSU);
1099 NewSU = CreateClone(SU);
1104 if (!I->isArtificial())
1112 if (I->isArtificial())
1114 SUnit *SuccSU = I->getSUnit();
1120 DelDeps.
push_back(std::make_pair(SuccSU, D));
1123 for (
unsigned i = 0, e = DelDeps.
size(); i != e; ++i)
1124 RemovePred(DelDeps[i].first, DelDeps[i].second);
1126 AvailableQueue->updateNode(SU);
1127 AvailableQueue->addNode(NewSU);
1135 void ScheduleDAGRRList::InsertCopiesAndMoveSuccs(
SUnit *SU,
unsigned Reg,
1139 SUnit *CopyFromSU = CreateNewSUnit(NULL);
1143 SUnit *CopyToSU = CreateNewSUnit(NULL);
1152 if (I->isArtificial())
1154 SUnit *SuccSU = I->getSUnit();
1159 DelDeps.
push_back(std::make_pair(SuccSU, *I));
1168 for (
unsigned i = 0, e = DelDeps.
size(); i != e; ++i)
1169 RemovePred(DelDeps[i].first, DelDeps[i].second);
1172 FromDep.setLatency(SU->
Latency);
1173 AddPred(CopyFromSU, FromDep);
1175 ToDep.setLatency(CopyFromSU->
Latency);
1176 AddPred(CopyToSU, ToDep);
1178 AvailableQueue->updateNode(SU);
1179 AvailableQueue->addNode(CopyFromSU);
1180 AvailableQueue->addNode(CopyToSU);
1193 assert(MCID.
ImplicitDefs &&
"Physical reg def must be in implicit def list!");
1195 for (
const uint16_t *ImpDef = MCID.
getImplicitDefs(); *ImpDef; ++ImpDef) {
1206 std::vector<SUnit*> &LiveRegDefs,
1213 if (!LiveRegDefs[*AliasI])
continue;
1216 if (LiveRegDefs[*AliasI] == SU)
continue;
1219 if (RegAdded.
insert(*AliasI)) {
1228 std::vector<SUnit*> &LiveRegDefs,
1232 for (
unsigned i = 1, e = LiveRegDefs.size()-1; i != e; ++i) {
1233 if (!LiveRegDefs[i])
continue;
1234 if (LiveRegDefs[i] == SU)
continue;
1246 return Op->getRegMask();
1254 bool ScheduleDAGRRList::
1256 if (NumLiveRegs == 0)
1266 if (I->isAssignedRegDep() && LiveRegDefs[I->getReg()] != SU)
1268 RegAdded, LRegs, TRI);
1274 unsigned NumOps = Node->getNumOperands();
1275 if (Node->getOperand(NumOps-1).getValueType() ==
MVT::Glue)
1278 for (
unsigned i = InlineAsm::Op_FirstOperand; i != NumOps;) {
1280 cast<ConstantSDNode>(Node->getOperand(i))->getZExtValue();
1288 for (; NumVals; --NumVals, ++i) {
1289 unsigned Reg = cast<RegisterSDNode>(Node->getOperand(i))->
getReg();
1299 if (!Node->isMachineOpcode())
1304 if (Node->getMachineOpcode() == (
unsigned)
TII->getCallFrameDestroyOpcode()) {
1306 unsigned CallResource = TRI->getNumRegs();
1307 if (LiveRegDefs[CallResource]) {
1308 SDNode *Gen = LiveRegGens[CallResource]->getNode();
1325 return !LRegs.
empty();
1328 void ScheduleDAGRRList::releaseInterferences(
unsigned Reg) {
1330 for (
unsigned i = Interferences.size(); i > 0; --i) {
1331 SUnit *SU = Interferences[i-1];
1332 LRegsMapT::iterator LRegsPos = LRegsMap.find(SU);
1344 AvailableQueue->push(SU);
1346 if (i < Interferences.size())
1347 Interferences[i-1] = Interferences.back();
1348 Interferences.pop_back();
1349 LRegsMap.erase(LRegsPos);
1357 SUnit *ScheduleDAGRRList::PickNodeToScheduleBottomUp() {
1358 SUnit *CurSU = AvailableQueue->empty() ? 0 : AvailableQueue->pop();
1361 if (!DelayForLiveRegsBottomUp(CurSU, LRegs))
1364 (LRegs[0] == TRI->getNumRegs() ?
"CallResource"
1365 : TRI->getName(LRegs[0]))
1366 <<
" SU #" << CurSU->
NodeNum <<
'\n');
1367 std::pair<LRegsMapT::iterator, bool> LRegsPair =
1368 LRegsMap.insert(std::make_pair(CurSU, LRegs));
1369 if (LRegsPair.second) {
1371 Interferences.push_back(CurSU);
1374 assert(CurSU->
isPending &&
"Intereferences are pending");
1376 LRegsPair.first->second = LRegs;
1378 CurSU = AvailableQueue->pop();
1386 for (
unsigned i = 0, e = Interferences.size(); i != e; ++i) {
1387 SUnit *TrySU = Interferences[i];
1393 unsigned LiveCycle = UINT_MAX;
1394 for (
unsigned j = 0, ee = LRegs.
size(); j != ee; ++j) {
1395 unsigned Reg = LRegs[j];
1396 if (LiveRegGens[Reg]->getHeight() < LiveCycle) {
1397 BtSU = LiveRegGens[
Reg];
1401 if (!WillCreateCycle(TrySU, BtSU)) {
1403 BacktrackBottomUp(TrySU, BtSU);
1410 AvailableQueue->remove(BtSU);
1419 CurSU = AvailableQueue->pop();
1421 AvailableQueue->remove(TrySU);
1435 SUnit *TrySU = Interferences[0];
1437 assert(LRegs.
size() == 1 &&
"Can't handle this yet!");
1438 unsigned Reg = LRegs[0];
1442 TRI->getMinimalPhysRegClass(Reg, VT);
1454 NewDef = CopyAndMoveSuccessors(LRDef);
1455 if (!DestRC && !NewDef)
1461 InsertCopiesAndMoveSuccs(LRDef, Reg, DestRC, RC, Copies);
1465 NewDef = Copies.
back();
1469 <<
" to SU #" << TrySU->
NodeNum <<
"\n");
1470 LiveRegDefs[
Reg] = NewDef;
1475 assert(CurSU &&
"Unable to resolve live physical register dependencies!");
1481 void ScheduleDAGRRList::ListScheduleBottomUp() {
1483 ReleasePredecessors(&ExitSU);
1486 if (!SUnits.empty()) {
1487 SUnit *RootSU = &SUnits[DAG->getRoot().getNode()->getNodeId()];
1488 assert(RootSU->
Succs.empty() &&
"Graph root shouldn't have successors!");
1490 AvailableQueue->push(RootSU);
1496 while (!AvailableQueue->empty() || !Interferences.empty()) {
1497 DEBUG(
dbgs() <<
"\nExamining Available:\n";
1498 AvailableQueue->dump(
this));
1502 SUnit *SU = PickNodeToScheduleBottomUp();
1504 AdvancePastStalls(SU);
1506 ScheduleNodeBottomUp(SU);
1508 while (AvailableQueue->empty() && !PendingQueue.empty()) {
1510 assert(MinAvailableCycle < UINT_MAX &&
"MinAvailableCycle uninitialized");
1511 AdvanceToCycle(std::max(CurCycle + 1, MinAvailableCycle));
1519 VerifyScheduledSequence(
true);
1531 class RegReductionPQBase;
1533 struct queue_sort :
public std::binary_function<SUnit*, SUnit*, bool> {
1534 bool isReady(
SUnit* SU,
unsigned CurCycle)
const {
return true; }
1539 struct reverse_sort :
public queue_sort {
1541 reverse_sort(SF &sf) : SortFunc(sf) {}
1542 reverse_sort(
const reverse_sort &RHS) : SortFunc(RHS.SortFunc) {}
1544 bool operator()(
SUnit* left,
SUnit* right)
const {
1547 return SortFunc(right, left);
1554 struct bu_ls_rr_sort :
public queue_sort {
1557 HasReadyFilter =
false
1560 RegReductionPQBase *SPQ;
1561 bu_ls_rr_sort(RegReductionPQBase *spq) : SPQ(spq) {}
1562 bu_ls_rr_sort(
const bu_ls_rr_sort &RHS) : SPQ(RHS.SPQ) {}
1564 bool operator()(
SUnit* left,
SUnit* right)
const;
1568 struct src_ls_rr_sort :
public queue_sort {
1571 HasReadyFilter =
false
1574 RegReductionPQBase *SPQ;
1575 src_ls_rr_sort(RegReductionPQBase *spq)
1577 src_ls_rr_sort(
const src_ls_rr_sort &RHS)
1580 bool operator()(
SUnit* left,
SUnit* right)
const;
1584 struct hybrid_ls_rr_sort :
public queue_sort {
1587 HasReadyFilter =
false
1590 RegReductionPQBase *SPQ;
1591 hybrid_ls_rr_sort(RegReductionPQBase *spq)
1593 hybrid_ls_rr_sort(
const hybrid_ls_rr_sort &RHS)
1596 bool isReady(
SUnit *SU,
unsigned CurCycle)
const;
1598 bool operator()(
SUnit* left,
SUnit* right)
const;
1603 struct ilp_ls_rr_sort :
public queue_sort {
1606 HasReadyFilter =
false
1609 RegReductionPQBase *SPQ;
1610 ilp_ls_rr_sort(RegReductionPQBase *spq)
1612 ilp_ls_rr_sort(
const ilp_ls_rr_sort &RHS)
1615 bool isReady(
SUnit *SU,
unsigned CurCycle)
const;
1617 bool operator()(
SUnit* left,
SUnit* right)
const;
1622 std::vector<SUnit*> Queue;
1623 unsigned CurQueueId;
1624 bool TracksRegPressure;
1628 std::vector<SUnit> *SUnits;
1634 ScheduleDAGRRList *scheduleDAG;
1637 std::vector<unsigned> SethiUllmanNumbers;
1645 std::vector<unsigned> RegLimit;
1649 bool hasReadyFilter,
1656 CurQueueId(0), TracksRegPressure(tracksrp), SrcOrder(srcorder),
1657 MF(mf),
TII(tii), TRI(tri), TLI(tli), scheduleDAG(NULL) {
1658 if (TracksRegPressure) {
1659 unsigned NumRC = TRI->getNumRegClasses();
1660 RegLimit.resize(NumRC);
1662 std::fill(RegLimit.begin(), RegLimit.end(), 0);
1665 E = TRI->regclass_end(); I != E; ++
I)
1670 void setScheduleDAG(ScheduleDAGRRList *scheduleDag) {
1671 scheduleDAG = scheduleDag;
1675 return scheduleDAG->getHazardRec();
1678 void initNodes(std::vector<SUnit> &sunits);
1680 void addNode(
const SUnit *SU);
1682 void updateNode(
const SUnit *SU);
1684 void releaseState() {
1686 SethiUllmanNumbers.clear();
1690 unsigned getNodePriority(
const SUnit *SU)
const;
1692 unsigned getNodeOrdering(
const SUnit *SU)
const {
1698 bool empty()
const {
return Queue.empty(); }
1700 void push(
SUnit *U) {
1701 assert(!U->
NodeQueueId &&
"Node in the queue already");
1706 void remove(
SUnit *SU) {
1707 assert(!Queue.empty() &&
"Queue is empty!");
1709 std::vector<SUnit *>::iterator I = std::find(Queue.begin(), Queue.end(),
1711 if (I !=
prior(Queue.end()))
1717 bool tracksRegPressure()
const {
return TracksRegPressure; }
1719 void dumpRegPressure()
const;
1721 bool HighRegPressure(
const SUnit *SU)
const;
1723 bool MayReduceRegPressure(
SUnit *SU)
const;
1725 int RegPressureDiff(
SUnit *SU,
unsigned &LiveUses)
const;
1727 void scheduledNode(
SUnit *SU);
1729 void unscheduledNode(
SUnit *SU);
1732 bool canClobber(
const SUnit *SU,
const SUnit *Op);
1733 void AddPseudoTwoAddrDeps();
1734 void PrescheduleNodesWithMultipleUses();
1735 void CalculateSethiUllmanNumbers();
1739 static SUnit *popFromQueueImpl(std::vector<SUnit*> &Q, SF &Picker) {
1740 std::vector<SUnit *>::iterator Best = Q.begin();
1741 for (std::vector<SUnit *>::iterator I =
llvm::next(Q.begin()),
1742 E = Q.end(); I != E; ++
I)
1743 if (Picker(*Best, *I))
1746 if (Best !=
prior(Q.end()))
1753 SUnit *popFromQueue(std::vector<SUnit*> &Q, SF &Picker,
ScheduleDAG *DAG) {
1756 reverse_sort<SF> RPicker(Picker);
1757 return popFromQueueImpl(Q, RPicker);
1761 return popFromQueueImpl(Q, Picker);
1765 class RegReductionPriorityQueue :
public RegReductionPQBase {
1775 : RegReductionPQBase(mf, SF::HasReadyFilter, tracksrp, srcorder,
1779 bool isBottomUp()
const {
return SF::IsBottomUp; }
1781 bool isReady(
SUnit *U)
const {
1782 return Picker.HasReadyFilter && Picker.isReady(U, getCurCycle());
1786 if (Queue.empty())
return NULL;
1788 SUnit *V = popFromQueue(Queue, Picker, scheduleDAG);
1793 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1796 std::vector<SUnit*> DumpQueue = Queue;
1797 SF DumpPicker = Picker;
1798 while (!DumpQueue.empty()) {
1799 SUnit *SU = popFromQueue(DumpQueue, DumpPicker, scheduleDAG);
1807 typedef RegReductionPriorityQueue<bu_ls_rr_sort>
1808 BURegReductionPriorityQueue;
1810 typedef RegReductionPriorityQueue<src_ls_rr_sort>
1811 SrcRegReductionPriorityQueue;
1813 typedef RegReductionPriorityQueue<hybrid_ls_rr_sort>
1814 HybridBURRPriorityQueue;
1816 typedef RegReductionPriorityQueue<ilp_ls_rr_sort>
1817 ILPBURRPriorityQueue;
1833 if (LSchedLow != RSchedLow)
1834 return LSchedLow < RSchedLow ? 1 : -1;
1842 unsigned &SethiUllmanNumber = SUNumbers[SU->
NodeNum];
1843 if (SethiUllmanNumber != 0)
1844 return SethiUllmanNumber;
1849 if (I->isCtrl())
continue;
1850 SUnit *PredSU = I->getSUnit();
1852 if (PredSethiUllman > SethiUllmanNumber) {
1853 SethiUllmanNumber = PredSethiUllman;
1855 }
else if (PredSethiUllman == SethiUllmanNumber)
1859 SethiUllmanNumber += Extra;
1861 if (SethiUllmanNumber == 0)
1862 SethiUllmanNumber = 1;
1864 return SethiUllmanNumber;
1869 void RegReductionPQBase::CalculateSethiUllmanNumbers() {
1870 SethiUllmanNumbers.assign(SUnits->size(), 0);
1872 for (
unsigned i = 0, e = SUnits->size(); i != e; ++i)
1876 void RegReductionPQBase::addNode(
const SUnit *SU) {
1877 unsigned SUSize = SethiUllmanNumbers.size();
1878 if (SUnits->size() > SUSize)
1879 SethiUllmanNumbers.resize(SUSize*2, 0);
1883 void RegReductionPQBase::updateNode(
const SUnit *SU) {
1884 SethiUllmanNumbers[SU->
NodeNum] = 0;
1890 unsigned RegReductionPQBase::getNodePriority(
const SUnit *SU)
const {
1891 assert(SU->
NodeNum < SethiUllmanNumbers.size());
1915 return SethiUllmanNumbers[SU->
NodeNum];
1917 unsigned Priority = SethiUllmanNumbers[SU->
NodeNum];
1921 return (NP > 0) ? NP : 0;
1931 void RegReductionPQBase::dumpRegPressure()
const {
1932 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1934 E = TRI->regclass_end(); I != E; ++
I) {
1945 bool RegReductionPQBase::HighRegPressure(
const SUnit *SU)
const {
1953 SUnit *PredSU = I->getSUnit();
1960 RegDefPos.
IsValid(); RegDefPos.Advance()) {
1961 unsigned RCId, Cost;
1971 bool RegReductionPQBase::MayReduceRegPressure(
SUnit *SU)
const {
1978 for (
unsigned i = 0; i != NumDefs; ++i) {
1982 unsigned RCId = TLI->getRepRegClassFor(VT)->getID();
1996 int RegReductionPQBase::RegPressureDiff(
SUnit *SU,
unsigned &LiveUses)
const {
2003 SUnit *PredSU = I->getSUnit();
2012 RegDefPos.
IsValid(); RegDefPos.Advance()) {
2013 MVT VT = RegDefPos.GetValue();
2014 unsigned RCId = TLI->getRepRegClassFor(VT)->getID();
2025 for (
unsigned i = 0; i != NumDefs; ++i) {
2029 unsigned RCId = TLI->getRepRegClassFor(VT)->getID();
2036 void RegReductionPQBase::scheduledNode(
SUnit *SU) {
2037 if (!TracksRegPressure)
2047 SUnit *PredSU = I->getSUnit();
2071 RegDefPos.
IsValid(); RegDefPos.Advance(), --SkipRegDefs) {
2075 unsigned RCId, Cost;
2087 RegDefPos.
IsValid(); RegDefPos.Advance(), --SkipRegDefs) {
2088 if (SkipRegDefs > 0)
2090 unsigned RCId, Cost;
2105 void RegReductionPQBase::unscheduledNode(
SUnit *SU) {
2106 if (!TracksRegPressure)
2129 SUnit *PredSU = I->getSUnit();
2138 unsigned RCId = TLI->getRepRegClassFor(VT)->getID();
2139 RegPressure[RCId] += TLI->getRepRegClassCostFor(VT);
2150 unsigned RCId = TLI->getRepRegClassFor(VT)->getID();
2151 RegPressure[RCId] += TLI->getRepRegClassCostFor(VT);
2155 for (
unsigned i = 0; i != NumDefs; ++i) {
2159 unsigned RCId = TLI->getRepRegClassFor(VT)->getID();
2160 if (
RegPressure[RCId] < TLI->getRepRegClassCostFor(VT))
2164 RegPressure[RCId] -= TLI->getRepRegClassCostFor(VT);
2172 for (
unsigned i = NumDefs, e = N->
getNumValues(); i != e; ++i) {
2178 unsigned RCId = TLI->getRepRegClassFor(VT)->getID();
2179 RegPressure[RCId] += TLI->getRepRegClassCostFor(VT);
2193 unsigned MaxHeight = 0;
2196 if (I->isCtrl())
continue;
2197 unsigned Height = I->getSUnit()->getHeight();
2200 if (I->getSUnit()->getNode() &&
2203 if (Height > MaxHeight)
2212 unsigned Scratches = 0;
2215 if (I->isCtrl())
continue;
2224 bool RetVal =
false;
2227 if (I->isCtrl())
continue;
2228 const SUnit *PredSU = I->getSUnit();
2247 bool RetVal =
false;
2250 if (I->isCtrl())
continue;
2251 const SUnit *SuccSU = I->getSUnit();
2288 if (I->isCtrl())
continue;
2289 I->getSUnit()->isVRegCycle =
true;
2301 if (I->isCtrl())
continue;
2302 SUnit *PredSU = I->getSUnit();
2305 "VRegCycle def must be CopyFromReg");
2320 if (I->isCtrl())
continue;
2321 if (I->getSUnit()->isVRegCycle &&
2334 if ((
int)SPQ->getCurCycle() < Height)
return true;
2335 if (SPQ->getHazardRec()->getHazardType(SU, 0)
2344 RegReductionPQBase *SPQ) {
2349 int LHeight = (int)left->
getHeight() + LPenalty;
2350 int RHeight = (int)right->
getHeight() + RPenalty;
2363 if (LHeight != RHeight)
2364 return LHeight > RHeight ? 1 : -1;
2376 if (!SPQ->getHazardRec()->isEnabled()) {
2377 if (LHeight != RHeight)
2378 return LHeight > RHeight ? 1 : -1;
2380 int LDepth = left->
getDepth() - LPenalty;
2381 int RDepth = right->
getDepth() - RPenalty;
2382 if (LDepth != RDepth) {
2384 <<
") depth " << LDepth <<
" vs SU (" << right->
NodeNum
2385 <<
") depth " << RDepth <<
"\n");
2386 return LDepth < RDepth ? 1 : -1;
2402 if (LHasPhysReg != RHasPhysReg) {
2404 static const char *
const PhysRegMsg[] = {
" has no physreg",
2405 " defines a physreg" };
2408 << PhysRegMsg[LHasPhysReg] <<
" SU(" << right->
NodeNum <<
") "
2409 << PhysRegMsg[RHasPhysReg] <<
"\n");
2410 return LHasPhysReg < RHasPhysReg;
2415 unsigned LPriority = SPQ->getNodePriority(left);
2416 unsigned RPriority = SPQ->getNodePriority(right);
2422 RPriority = (RPriority > RNumVals) ? (RPriority - RNumVals) : 0;
2426 LPriority = (LPriority > LNumVals) ? (LPriority - LNumVals) : 0;
2429 if (LPriority != RPriority)
2430 return LPriority > RPriority;
2435 unsigned LOrder = SPQ->getNodeOrdering(left);
2436 unsigned ROrder = SPQ->getNodeOrdering(right);
2440 if ((LOrder || ROrder) && LOrder != ROrder)
2441 return LOrder != 0 && (LOrder < ROrder || ROrder == 0);
2464 return LDist < RDist;
2469 if (LScratch != RScratch)
2470 return LScratch > RScratch;
2474 if ((left->
isCall && RPriority > 0) || (right->
isCall && LPriority > 0))
2493 "NodeQueueId cannot be zero");
2498 bool bu_ls_rr_sort::operator()(
SUnit *left,
SUnit *right)
const {
2506 bool src_ls_rr_sort::operator()(
SUnit *left,
SUnit *right)
const {
2510 unsigned LOrder = SPQ->getNodeOrdering(left);
2511 unsigned ROrder = SPQ->getNodeOrdering(right);
2515 if ((LOrder || ROrder) && LOrder != ROrder)
2516 return LOrder != 0 && (LOrder < ROrder || ROrder == 0);
2525 bool hybrid_ls_rr_sort::isReady(
SUnit *SU,
unsigned CurCycle)
const {
2526 static const unsigned ReadyDelay = 3;
2528 if (SPQ->MayReduceRegPressure(SU))
return true;
2530 if (SU->
getHeight() > (CurCycle + ReadyDelay))
return false;
2532 if (SPQ->getHazardRec()->getHazardType(SU, -ReadyDelay)
2540 bool hybrid_ls_rr_sort::operator()(
SUnit *left,
SUnit *right)
const {
2548 bool LHigh = SPQ->HighRegPressure(left);
2549 bool RHigh = SPQ->HighRegPressure(right);
2552 if (LHigh && !RHigh) {
2557 else if (!LHigh && RHigh) {
2562 if (!LHigh && !RHigh) {
2572 bool ilp_ls_rr_sort::isReady(
SUnit *SU,
unsigned CurCycle)
const {
2573 if (SU->
getHeight() > CurCycle)
return false;
2575 if (SPQ->getHazardRec()->getHazardType(SU, 0)
2606 bool ilp_ls_rr_sort::operator()(
SUnit *left,
SUnit *right)
const {
2614 unsigned LLiveUses = 0, RLiveUses = 0;
2615 int LPDiff = 0, RPDiff = 0;
2617 LPDiff = SPQ->RegPressureDiff(left, LLiveUses);
2618 RPDiff = SPQ->RegPressureDiff(right, RLiveUses);
2622 <<
" != SU(" << right->
NodeNum <<
"): " << RPDiff <<
"\n");
2623 return LPDiff > RPDiff;
2629 if (LReduce && !RReduce)
return false;
2630 if (RReduce && !LReduce)
return true;
2635 <<
" != SU(" << right->
NodeNum <<
"): " << RLiveUses <<
"\n");
2636 return LLiveUses < RLiveUses;
2642 if (LStall != RStall)
2665 void RegReductionPQBase::initNodes(std::vector<SUnit> &sunits) {
2669 AddPseudoTwoAddrDeps();
2671 if (!TracksRegPressure && !SrcOrder)
2672 PrescheduleNodesWithMultipleUses();
2674 CalculateSethiUllmanNumbers();
2677 if (scheduleDAG->BB->isSuccessor(scheduleDAG->BB)) {
2678 for (
unsigned i = 0, e = sunits.size(); i != e; ++i) {
2688 bool RegReductionPQBase::canClobber(
const SUnit *SU,
const SUnit *Op) {
2694 for (
unsigned i = 0; i != NumOps; ++i) {
2710 ScheduleDAGRRList *scheduleDAG,
2713 const uint16_t *ImpDefs
2716 if(!ImpDefs && !RegMask)
2721 SUnit *SuccSU = SI->getSUnit();
2723 PE = SuccSU->
Preds.end(); PI != PE; ++PI) {
2724 if (!PI->isAssignedRegDep())
2728 scheduleDAG->IsReachable(DepSU, PI->getSUnit()))
2732 for (
const uint16_t *ImpDef = ImpDefs; *ImpDef; ++ImpDef)
2737 scheduleDAG->IsReachable(DepSU, PI->getSUnit()))
2752 assert(ImpDefs &&
"Caller should check hasPhysRegDefs");
2755 if (!SUNode->isMachineOpcode())
2757 const uint16_t *SUImpDefs =
2758 TII->
get(SUNode->getMachineOpcode()).getImplicitDefs();
2760 if (!SUImpDefs && !SURegMask)
2762 for (
unsigned i = NumDefs, e = N->
getNumValues(); i != e; ++i) {
2768 unsigned Reg = ImpDefs[i - NumDefs];
2773 for (;*SUImpDefs; ++SUImpDefs) {
2774 unsigned SUReg = *SUImpDefs;
2814 void RegReductionPQBase::PrescheduleNodesWithMultipleUses() {
2816 for (
unsigned i = 0, e = SUnits->size(); i != e; ++i) {
2817 SUnit *SU = &(*SUnits)[i];
2837 EE = SU->
Preds.end(); II != EE; ++II)
2838 if (!II->isCtrl()) {
2839 PredSU = II->getSUnit();
2861 EE = PredSU->
Succs.end(); II != EE; ++II) {
2862 SUnit *PredSuccSU = II->getSUnit();
2863 if (PredSuccSU == SU)
continue;
2867 goto outer_loop_continue;
2871 goto outer_loop_continue;
2873 if (scheduleDAG->IsReachable(SU, PredSuccSU))
2874 goto outer_loop_continue;
2880 <<
" next to PredSU #" << PredSU->
NodeNum
2881 <<
" to guide scheduling in the presence of multiple uses\n");
2882 for (
unsigned i = 0; i != PredSU->
Succs.size(); ++i) {
2888 scheduleDAG->RemovePred(SuccSU, Edge);
2889 scheduleDAG->AddPred(SU, Edge);
2891 scheduleDAG->AddPred(SuccSU, Edge);
2895 outer_loop_continue:;
2906 void RegReductionPQBase::AddPseudoTwoAddrDeps() {
2907 for (
unsigned i = 0, e = SUnits->size(); i != e; ++i) {
2908 SUnit *SU = &(*SUnits)[i];
2921 for (
unsigned j = 0; j != NumOps; ++j) {
2928 if (!DUSU)
continue;
2930 E = DUSU->
Succs.end(); I != E; ++
I) {
2931 if (I->isCtrl())
continue;
2932 SUnit *SuccSU = I->getSUnit();
2944 while (SuccSU->
Succs.size() == 1 &&
2948 SuccSU = SuccSU->
Succs.front().getSUnit();
2966 (!canClobber(SuccSU, DUSU) ||
2969 !scheduleDAG->IsReachable(SuccSU, SU)) {
2970 DEBUG(
dbgs() <<
" Adding a pseudo-two-addr edge from SU #"
2990 BURegReductionPriorityQueue *PQ =
2991 new BURegReductionPriorityQueue(*IS->
MF,
false,
false, TII, TRI, 0);
2992 ScheduleDAGRRList *SD =
new ScheduleDAGRRList(*IS->
MF,
false, PQ, OptLevel);
2993 PQ->setScheduleDAG(SD);
3004 SrcRegReductionPriorityQueue *PQ =
3005 new SrcRegReductionPriorityQueue(*IS->
MF,
false,
true, TII, TRI, 0);
3006 ScheduleDAGRRList *SD =
new ScheduleDAGRRList(*IS->
MF,
false, PQ, OptLevel);
3007 PQ->setScheduleDAG(SD);
3019 HybridBURRPriorityQueue *PQ =
3020 new HybridBURRPriorityQueue(*IS->
MF,
true,
false, TII, TRI, TLI);
3022 ScheduleDAGRRList *SD =
new ScheduleDAGRRList(*IS->
MF,
true, PQ, OptLevel);
3023 PQ->setScheduleDAG(SD);
3035 ILPBURRPriorityQueue *PQ =
3036 new ILPBURRPriorityQueue(*IS->
MF,
true,
false, TII, TRI, TLI);
3037 ScheduleDAGRRList *SD =
new ScheduleDAGRRList(*IS->
MF,
true, PQ, OptLevel);
3038 PQ->setScheduleDAG(SD);
void push_back(const T &Elt)
bool isCtrl() const
isCtrl - Shorthand for getKind() != SDep::Data.
const SDNode * GetNode() const
const uint16_t * getImplicitDefs() const
bool isSucc(SUnit *N)
isSucc - Test if node N is a successor of this node.
static int BUCompareLatency(SUnit *left, SUnit *right, bool checkPref, RegReductionPQBase *SPQ)
bool isCommutable() const
static bool canEnableCoalescing(SUnit *SU)
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions. Register definitions always occur...
static cl::opt< bool > DisableSchedRegPressure("disable-sched-reg-pressure", cl::Hidden, cl::init(false), cl::desc("Disable regpressure priority in sched=list-ilp"))
static cl::opt< unsigned > AvgIPC("sched-avg-ipc", cl::Hidden, cl::init(1), cl::desc("Average inst/cycle whan no target itinerary exists."))
SDNode * getGluedNode() const
static void GetCostForDef(const ScheduleDAGSDNodes::RegDefIter &RegDefPos, const TargetLowering *TLI, const TargetInstrInfo *TII, const TargetRegisterInfo *TRI, unsigned &RegClass, unsigned &Cost, const MachineFunction &MF)
static bool isVirtualRegister(unsigned Reg)
unsigned getOpcode() const
static bool isClobberKind(unsigned Flag)
static void CheckForLiveRegDef(SUnit *SU, unsigned Reg, std::vector< SUnit * > &LiveRegDefs, SmallSet< unsigned, 4 > &RegAdded, SmallVectorImpl< unsigned > &LRegs, const TargetRegisterInfo *TRI)
unsigned getNumOperands() const
static bool canClobberReachingPhysRegUse(const SUnit *DepSU, const SUnit *SU, ScheduleDAGRRList *scheduleDAG, const TargetInstrInfo *TII, const TargetRegisterInfo *TRI)
static EVT getPhysicalRegisterVT(SDNode *N, unsigned Reg, const TargetInstrInfo *TII)
const SDValue & getOperand(unsigned Num) const
int getCallFrameSetupOpcode() const
void removePred(const SDep &D)
static cl::opt< bool > DisableSchedVRegCycle("disable-sched-vrcycle", cl::Hidden, cl::init(false), cl::desc("Disable virtual register cycle interference checks"))
void setNodeId(int Id)
setNodeId - Set unique node id.
static unsigned CalcNodeSethiUllmanNumber(const SUnit *SU, std::vector< unsigned > &SUNumbers)
bool isAssignedRegDep() const
static bool hasVRegCycleUse(const SUnit *SU)
const TargetRegisterClass * CopyDstRC
EntryToken - This is the marker used to indicate the start of a region.
virtual const TargetRegisterClass * getRepRegClassFor(MVT VT) const
unsigned getResNo() const
get the index which selects a specific result in the SDNode
SmallVector< SDep, 4 > Preds
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
static SDNode * FindCallSeqStart(SDNode *N, unsigned &NestLevel, unsigned &MaxNest, const TargetInstrInfo *TII)
unsigned getHeight() const
static int checkSpecialNodes(const SUnit *left, const SUnit *right)
const HexagonInstrInfo * TII
const char * getName() const
#define llvm_unreachable(msg)
EVT getValueType(unsigned ResNo) const
const TargetRegisterClass * getRegClass(unsigned i) const
Regular data dependence (aka true-dependence).
const TargetLowering * getTargetLowering() const
const TargetRegisterClass * getRegClass(unsigned Reg) const
static bool isRegDefEarlyClobberKind(unsigned Flag)
static const uint32_t * getNodeRegMask(const SDNode *N)
getNodeRegMask - Returns the register mask attached to an SDNode, if any.
unsigned getIROrder() const
unsigned getNumValues() const
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
ScheduleDAGSDNodes * createHybridListDAGScheduler(SelectionDAGISel *IS, CodeGenOpt::Level)
static bool isRegDefKind(unsigned Flag)
ScheduleDAGSDNodes * createSourceListDAGScheduler(SelectionDAGISel *IS, CodeGenOpt::Level OptLevel)
Sequence
A sequence of states that a pointer may go through in which an objc_retain and objc_release are actua...
static RegisterScheduler burrListDAGScheduler("list-burr","Bottom-up register reduction list scheduling", createBURRListDAGScheduler)
SDNode * getNode() const
get the SDNode which holds the desired result
void setHeightToAtLeast(unsigned NewHeight)
initializer< Ty > init(const Ty &Val)
static RegisterScheduler hybridListDAGScheduler("list-hybrid","Bottom-up register pressure aware list scheduling ""which tries to balance latency and register pressure", createHybridListDAGScheduler)
bool regsOverlap(unsigned regA, unsigned regB) const
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
static cl::opt< bool > DisableSchedStalls("disable-sched-stalls", cl::Hidden, cl::init(true), cl::desc("Disable no-stall priority in sched=list-ilp"))
ScheduleDAGSDNodes * createBURRListDAGScheduler(SelectionDAGISel *IS, CodeGenOpt::Level OptLevel)
static bool isOperandOf(const SUnit *SU, SDNode *N)
static RegisterScheduler ILPListDAGScheduler("list-ilp","Bottom-up register pressure aware list scheduling ""which tries to balance ILP and register pressure", createILPListDAGScheduler)
static unsigned calcMaxScratches(const SUnit *SU)
static bool IsChainDependent(SDNode *Outer, SDNode *Inner, unsigned NestLevel, const TargetInstrInfo *TII)
static bool BUHasStall(SUnit *SU, int Height, RegReductionPQBase *SPQ)
static unsigned getNumOperandRegisters(unsigned Flag)
static cl::opt< bool > DisableSchedCriticalPath("disable-sched-critical-path", cl::Hidden, cl::init(false), cl::desc("Disable critical path priority in sched=list-ilp"))
ItTy next(ItTy it, Dist n)
unsigned getLatency() const
for(unsigned i=0, e=MI->getNumOperands();i!=e;++i)
static bool canClobberPhysRegDefs(const SUnit *SuccSU, const SUnit *SU, const TargetInstrInfo *TII, const TargetRegisterInfo *TRI)
static void resetVRegCycle(SUnit *SU)
static cl::opt< bool > DisableSchedLiveUses("disable-sched-live-uses", cl::Hidden, cl::init(true), cl::desc("Disable live use priority in sched=list-ilp"))
static bool hasOnlyLiveInOpers(const SUnit *SU)
static unsigned closestSucc(const SUnit *SU)
Sched::Preference SchedulingPref
static void CheckForLiveRegDefMasked(SUnit *SU, const uint32_t *RegMask, std::vector< SUnit * > &LiveRegDefs, SmallSet< unsigned, 4 > &RegAdded, SmallVectorImpl< unsigned > &LRegs)
int getOperandConstraint(unsigned OpNum, MCOI::OperandConstraint Constraint) const
Returns the value of the specific constraint if it is set. Returns -1 if it is not set...
const MCInstrDesc & get(unsigned Opcode) const
static bool BURRSort(SUnit *left, SUnit *right, RegReductionPQBase *SPQ)
virtual const TargetInstrInfo * getInstrInfo() const
ScheduleDAGSDNodes * createILPListDAGScheduler(SelectionDAGISel *IS, CodeGenOpt::Level)
static cl::opt< bool > DisableSchedHeight("disable-sched-height", cl::Hidden, cl::init(false), cl::desc("Disable scheduled-height priority in sched=list-ilp"))
static void initVRegCycle(SUnit *SU)
const TargetRegisterClass * CopySrcRC
raw_ostream & dbgs()
dbgs - Return a circular-buffered debug stream.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
static bool clobbersPhysReg(const uint32_t *RegMask, unsigned PhysReg)
virtual ScheduleHazardRecognizer * CreateTargetHazardRecognizer(const TargetMachine *TM, const ScheduleDAG *DAG) const
unsigned getDepth() const
void setLatency(unsigned Lat)
setLatency - Set the latency for this edge.
static bool isPhysicalRegister(unsigned Reg)
bool hasAnyUseOfValue(unsigned Value) const
MachineRegisterInfo & getRegInfo()
static bool hasOnlyLiveOutUses(const SUnit *SU)
IMPLICIT_DEF - This is the MachineInstr-level equivalent of undef.
static cl::opt< bool > DisableSchedPhysRegJoin("disable-sched-physreg-join", cl::Hidden, cl::init(false), cl::desc("Disable physreg def-use affinity"))
static cl::opt< int > MaxReorderWindow("max-sched-reorder", cl::Hidden, cl::init(6), cl::desc("Number of instructions to allow ahead of the critical path ""in sched=list-ilp"))
unsigned short NumRegDefsLeft
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
const TargetMachine & getTarget() const
virtual const TargetRegisterInfo * getRegisterInfo() const
static cl::opt< bool > Disable2AddrHack("disable-2addr-hack", cl::Hidden, cl::init(true), cl::desc("Disable scheduler's two-address hack"))
static cl::opt< bool > DisableSchedCycles("disable-sched-cycles", cl::Hidden, cl::init(false), cl::desc("Disable cycle-level precision during preRA scheduling"))
static RegisterScheduler sourceListDAGScheduler("source","Similar to list-burr but schedules in source ""order when possible", createSourceListDAGScheduler)
virtual unsigned getRegPressureLimit(const TargetRegisterClass *RC, MachineFunction &MF) const
STATISTIC(NumBacktracks,"Number of times scheduler backtracked")
const uint16_t * ImplicitDefs
bool addPred(const SDep &D, bool Required=true)
SmallVector< SDep, 4 > Succs
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction. Note that variadic (isVari...
Arbitrary strong DAG edge (no real dependence).
ItTy prior(ItTy it, Dist n)
virtual uint8_t getRepRegClassCostFor(MVT VT) const
const TargetRegisterClass * getRegClass(const MCInstrDesc &TID, unsigned OpNum, const TargetRegisterInfo *TRI, const MachineFunction &MF) const
int getCallFrameDestroyOpcode() const
MVT getSimpleValueType(unsigned ResNo) const
const TargetRegisterClass *const * regclass_iterator
void dump(const ScheduleDAG *G) const
SUnit - Scheduling unit. This is a node in the scheduling DAG.
bool isMachineOpcode() const
unsigned getMachineOpcode() const