LLVM: lib/CodeGen/VLIWMachineScheduler.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
33#include
34#include
35#include
36#include
37#include
38#include
39
40using namespace llvm;
41
42#define DEBUG_TYPE "machine-scheduler"
43
46
49
52
53
54
57
58
59
60
63 cl::desc("High register pressure threhold."));
64
67 : TII(STI.getInstrInfo()), SchedModel(SM) {
69
70
71
73
77}
78
82}
83
85
86
88 if (SUd->Succs.size() == 0)
89 return false;
90
91 for (const auto &S : SUd->Succs) {
92
93
94 if (S.isCtrl())
95 continue;
96
97 if (S.getSUnit() == SUu && S.getLatency() > 0)
98 return true;
99 }
100 return false;
101}
102
103
104
105
106
107
110 return false;
111
112
113
115 default:
117 return false;
118 break;
119 case TargetOpcode::EXTRACT_SUBREG:
120 case TargetOpcode::INSERT_SUBREG:
121 case TargetOpcode::SUBREG_TO_REG:
122 case TargetOpcode::REG_SEQUENCE:
123 case TargetOpcode::IMPLICIT_DEF:
124 case TargetOpcode::COPY:
125 case TargetOpcode::INLINEASM:
126 case TargetOpcode::INLINEASM_BR:
127 break;
128 }
129
130
131
132 if (IsTop) {
135 return false;
136 } else {
139 return false;
140 }
141 return true;
142}
143
144
146 bool startNewCycle = false;
147
148 if (!SU) {
151 return false;
152 }
153
154
159 startNewCycle = true;
160 }
161
163 default:
165 break;
166 case TargetOpcode::EXTRACT_SUBREG:
167 case TargetOpcode::INSERT_SUBREG:
168 case TargetOpcode::SUBREG_TO_REG:
169 case TargetOpcode::REG_SEQUENCE:
170 case TargetOpcode::IMPLICIT_DEF:
171 case TargetOpcode::KILL:
172 case TargetOpcode::CFI_INSTRUCTION:
173 case TargetOpcode::EH_LABEL:
174 case TargetOpcode::COPY:
175 case TargetOpcode::INLINEASM:
176 case TargetOpcode::INLINEASM_BR:
177 break;
178 }
179 Packet.push_back(SU);
180
181#ifndef NDEBUG
183 for (unsigned i = 0, e = Packet.size(); i != e; ++i) {
187 }
188#endif
189
190 return startNewCycle;
191}
192
196}
197
198
199
200
202 LLVM_DEBUG(dbgs() << "********** MI Converging Scheduling VLIW "
206
208
210
211
213
216
217
219
221 unsigned maxH = 0;
223 if (SU.getHeight() > maxH)
224 maxH = SU.getHeight();
225 dbgs() << "Max Height " << maxH << "\n";
226 });
228 unsigned maxD = 0;
230 if (SU.getDepth() > maxD)
231 maxD = SU.getDepth();
232 dbgs() << "Max Depth " << maxD << "\n";
233 });
237
239
240 bool IsTopNode = false;
241 while (true) {
243 dbgs() << "** VLIWMachineScheduler::schedule picking next node\n");
245 if (!SU)
246 break;
247
249 break;
250
252
253
254 SchedImpl->schedNode(SU, IsTopNode);
255
257 }
259
261
263 dbgs() << "*** Final schedule for "
266 dbgs() << '\n';
267 });
268}
269
273
276
277
278
286
291
292 const std::vector &MaxPressure =
295 for (unsigned i = 0, e = MaxPressure.size(); i < e; ++i) {
298 ((float)MaxPressure[i] > ((float)Limit * RPThreshold));
299 }
300}
301
305}
306
308 for (const SDep &PI : SU->Preds) {
310 unsigned MinLatency = PI.getLatency();
311#ifndef NDEBUG
313#endif
314 if (SU->TopReadyCycle < PredReadyCycle + MinLatency)
316 }
317
320}
321
323 assert(SU->getInstr() && "Scheduled SUnit must have instr");
324
326 ++I) {
327 unsigned SuccReadyCycle = I->getSUnit()->BotReadyCycle;
328 unsigned MinLatency = I->getLatency();
329#ifndef NDEBUG
331#endif
332 if (SU->BotReadyCycle < SuccReadyCycle + MinLatency)
334 }
335
338}
339
343}
344
345
346
347
348
349
350
351
352
353
354
355
356
357
359 if (HazardRec->isEnabled())
361
364 return true;
365
366 return false;
367}
368
370 SUnit *SU, unsigned ReadyCycle) {
371 if (ReadyCycle < MinReadyCycle)
372 MinReadyCycle = ReadyCycle;
373
374
375
376 if (ReadyCycle > CurrCycle || checkHazard(SU))
377
378 Pending.push(SU);
379 else
381}
382
383
386 IssueCount = (IssueCount <= Width) ? 0 : IssueCount - Width;
387
388 assert(MinReadyCycle < std::numeric_limits::max() &&
389 "MinReadyCycle uninitialized");
390 unsigned NextCycle = std::max(CurrCycle + 1, MinReadyCycle);
391
392 if (!HazardRec->isEnabled()) {
393
394 CurrCycle = NextCycle;
395 } else {
396
397 for (; CurrCycle != NextCycle; ++CurrCycle) {
398 if (isTop())
399 HazardRec->AdvanceCycle();
400 else
401 HazardRec->RecedeCycle();
402 }
403 }
404 CheckPending = true;
405
407 << CurrCycle << '\n');
408}
409
410
412 bool startNewCycle = false;
413
414
415 if (HazardRec->isEnabled()) {
416 if (!isTop() && SU->isCall) {
417
418
419 HazardRec->Reset();
420 }
421 HazardRec->EmitInstruction(SU);
422 }
423
424
425 startNewCycle = ResourceModel->reserveResources(SU, isTop());
426
427
428
430 if (startNewCycle) {
431 LLVM_DEBUG(dbgs() << "*** Max instrs at cycle " << CurrCycle << '\n');
432 bumpCycle();
433 } else
434 LLVM_DEBUG(dbgs() << "*** IssueCount " << IssueCount << " at cycle "
435 << CurrCycle << '\n');
436}
437
438
439
441
443 MinReadyCycle = std::numeric_limits::max();
444
445
446
447 for (unsigned i = 0, e = Pending.size(); i != e; ++i) {
448 SUnit *SU = *(Pending.begin() + i);
450
451 if (ReadyCycle < MinReadyCycle)
452 MinReadyCycle = ReadyCycle;
453
454 if (ReadyCycle > CurrCycle)
455 continue;
456
457 if (checkHazard(SU))
458 continue;
459
461 Pending.remove(Pending.begin() + i);
462 --i;
463 --e;
464 }
465 CheckPending = false;
466}
467
468
472 else {
473 assert(Pending.isInQueue(SU) && "bad ready count");
474 Pending.remove(Pending.find(SU));
475 }
476}
477
478
479
480
482 if (CheckPending)
483 releasePending();
484
485 auto AdvanceCycle = [this]() {
487 return true;
488 if (Available.size() == 1 && Pending.size() > 0)
489 return !ResourceModel->isResourceAvailable(*Available.begin(), isTop()) ||
491 return false;
492 };
493 for (unsigned i = 0; AdvanceCycle(); ++i) {
494 assert(i <= (HazardRec->getMaxLookAhead() + MaxMinLatency) &&
495 "permanent hazard");
496 (void)i;
497 ResourceModel->reserveResources(nullptr, isTop());
498 bumpCycle();
499 releasePending();
500 }
503 return nullptr;
504}
505
506#ifndef NDEBUG
510 dbgs() << Label << " " << Q.getName() << " ";
511 if (P.isValid())
513 << P.getUnitInc() << " ";
514 else
515 dbgs() << " ";
516 dbgs() << "cost(" << Cost << ")\t";
518}
519
520
525
532 std::stringstream dbgstr;
533 dbgstr << "SU(" << std::setw(3) << (*I)->NodeNum << ")";
534 dbgs() << dbgstr.str();
536 dbgs() << "\t";
537 (*I)->getInstr()->dump();
538 }
539 dbgs() << "\n";
540}
541#endif
542
543
544
547 return false;
548
549 for (auto &Pred : SU->Preds) {
550
551 if (!Pred.getSUnit()->isScheduled && (Pred.getSUnit() != SU2))
552 return false;
553 }
554
555 return true;
556}
557
558
559
562 return false;
563
564 for (auto &Succ : SU->Succs) {
565
566 if (!Succ.getSUnit()->isScheduled && (Succ.getSUnit() != SU2))
567 return false;
568 }
569 return true;
570}
571
572
573
574
575
576
579 for (const auto &P : PD) {
580 if (.isValid())
581 continue;
582
583
584
586 return (isBotUp ? P.getUnitInc() : -P.getUnitInc());
587 }
588 return 0;
589}
590
591
592
596 bool verbose) {
597
598 int ResCount = 1;
599
600
602 return ResCount;
603
605 << ((Q.getID() == TopQID) ? "(top|" : "(bot|"));
606
610 }
611
612 unsigned IsAvailableAmt = 0;
613
618 }
619
621 std::stringstream dbgstr;
622 dbgstr << "h" << std::setw(3) << SU->getHeight() << "|";
623 dbgs() << dbgstr.str();
624 });
625
626
627
630 ResCount += IsAvailableAmt;
632 } else
634 } else {
638 }
639
641 std::stringstream dbgstr;
642 dbgstr << "d" << std::setw(3) << SU->getDepth() << "|";
643 dbgs() << dbgstr.str();
644 });
645
646
647
650 ResCount += IsAvailableAmt;
652 } else
654 }
655
656 unsigned NumNodesBlocking = 0;
658
659
660
661
665 ++NumNodesBlocking;
666 } else {
667
671 ++NumNodesBlocking;
672 }
673 ResCount += (NumNodesBlocking * ScaleTwo);
674
676 std::stringstream dbgstr;
677 dbgstr << "blk " << std::setw(2) << NumNodesBlocking << ")|";
678 dbgs() << dbgstr.str();
679 });
680
681
683
685
687
688
690
691
692
696 ResCount -= IsAvailableAmt;
701 });
702 }
703
704
705
707 for (const SDep &PI : SU->Preds) {
713 }
714 }
716 for (const SDep &SI : SU->Succs) {
717 if (!SI.getSUnit()->getInstr()->isPseudo() && SI.isAssignedRegDep() &&
718 SI.getLatency() == 0 &&
722 }
723 }
724 }
725
726
727
728
729
730
733 for (const auto &PI : SU->Preds) {
734 if (PI.getLatency() > 0 &&
738 }
739 }
740 } else {
741 for (const auto &SI : SU->Succs) {
742 if (SI.getLatency() > 0 &&
746 }
747 }
748 }
749 }
750
752 std::stringstream dbgstr;
753 dbgstr << "Total " << std::setw(4) << ResCount << ")";
754 dbgs() << dbgstr.str();
755 });
756
757 return ResCount;
758}
759
760
761
762
763
764
772 else Q.dump(););
773
774
776
777
781 TempTracker.getMaxPressureDelta((*I)->getInstr(), RPDelta,
784
785 int CurrentCost = SchedulingCost(Q, *I, Candidate, RPDelta, false);
786
787
788 if (!Candidate.SU) {
791 Candidate.RPDelta = RPDelta;
792 Candidate.SCost = CurrentCost;
794 continue;
795 }
796
797
798
799 if (CurrentCost < 0 && Candidate.SCost < 0) {
804 Candidate.RPDelta = RPDelta;
805 Candidate.SCost = CurrentCost;
807 }
808 continue;
809 }
810
811
812 if (CurrentCost > Candidate.SCost) {
815 Candidate.RPDelta = RPDelta;
816 Candidate.SCost = CurrentCost;
818 continue;
819 }
820
821
824 if (CurrWeak != CandWeak) {
825 if (CurrWeak < CandWeak) {
828 Candidate.RPDelta = RPDelta;
829 Candidate.SCost = CurrentCost;
830 FoundCandidate = Weak;
831 }
832 continue;
833 }
834
836 unsigned CurrSize, CandSize;
838 CurrSize = (*I)->Succs.size();
839 CandSize = Candidate.SU->Succs.size();
840 } else {
841 CurrSize = (*I)->Preds.size();
842 CandSize = Candidate.SU->Preds.size();
843 }
844 if (CurrSize > CandSize) {
847 Candidate.RPDelta = RPDelta;
848 Candidate.SCost = CurrentCost;
850 }
851
852
853 if (CurrSize != CandSize)
854 continue;
855 }
856
857
858
859
865 Candidate.RPDelta = RPDelta;
866 Candidate.SCost = CurrentCost;
868 continue;
869 }
870 }
871
872
873
874 if (FoundCandidate == NoCand)
875 continue;
876 }
877 return FoundCandidate;
878}
879
880
882
883
886 IsTopNode = false;
887 return SU;
888 }
891 IsTopNode = true;
892 return SU;
893 }
895
898 assert(BotResult != NoCand && "failed to find the first candidate");
899
900
901
902
903
904
905
906
909 IsTopNode = false;
910 return BotCand.SU;
911 }
912
916 assert(TopResult != NoCand && "failed to find the first candidate");
917
920 IsTopNode = true;
921 return TopCand.SU;
922 }
923
924
926 LLVM_DEBUG(dbgs() << "Prefered Bottom Node SingleMax\n");
927 IsTopNode = false;
928 return BotCand.SU;
929 }
931 LLVM_DEBUG(dbgs() << "Prefered Top Node SingleMax\n");
932 IsTopNode = true;
933 return TopCand.SU;
934 }
937 IsTopNode = true;
938 return TopCand.SU;
939 }
940
941 LLVM_DEBUG(dbgs() << "Prefered Bottom in Node order\n");
942 IsTopNode = false;
943 return BotCand.SU;
944}
945
946
951 return nullptr;
952 }
956 if (!SU) {
960 assert(TopResult != NoCand && "failed to find the first candidate");
961 (void)TopResult;
962 SU = TopCand.SU;
963 }
964 IsTopNode = true;
967 if (!SU) {
971 assert(BotResult != NoCand && "failed to find the first candidate");
972 (void)BotResult;
973 SU = BotCand.SU;
974 }
975 IsTopNode = false;
976 } else {
978 }
983
984 LLVM_DEBUG(dbgs() << "*** " << (IsTopNode ? "Top" : "Bottom")
985 << " Scheduling instruction in cycle "
989 return SU;
990}
991
992
993
994
995
997 if (IsTopNode) {
1000 } else {
1003 }
1004}
static const Function * getParent(const Value *V)
@ Available
We know the block is fully available. This is a fixpoint.
const HexagonInstrInfo * TII
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
static bool isSingleUnscheduledPred(SUnit *SU, SUnit *SU2)
isSingleUnscheduledPred - If SU2 is the only unscheduled predecessor of SU, return true (we may have ...
static cl::opt< bool > CheckEarlyAvail("check-early-avail", cl::Hidden, cl::init(true))
static cl::opt< bool > IgnoreBBRegPressure("ignore-bb-reg-pressure", cl::Hidden, cl::init(false))
static cl::opt< float > RPThreshold("vliw-misched-reg-pressure", cl::Hidden, cl::init(0.75f), cl::desc("High register pressure threhold."))
static cl::opt< bool > UseNewerCandidate("use-newer-candidate", cl::Hidden, cl::init(true))
static bool isSingleUnscheduledSucc(SUnit *SU, SUnit *SU2)
isSingleUnscheduledSucc - If SU2 is the only unscheduled successor of SU, return true (we may have du...
static cl::opt< unsigned > SchedDebugVerboseLevel("misched-verbose-level", cl::Hidden, cl::init(1))
VLIWMachineScheduler * DAG
void releaseBottomNode(SUnit *SU) override
When all successor dependencies have been resolved, free this node for bottom-up scheduling.
static constexpr unsigned PriorityOne
SUnit * pickNode(bool &IsTopNode) override
Pick the best node to balance the schedule. Implements MachineSchedStrategy.
virtual VLIWResourceModel * createVLIWResourceModel(const TargetSubtargetInfo &STI, const TargetSchedModel *SchedModel) const
int pressureChange(const SUnit *SU, bool isBotUp)
Check if the instruction changes the register pressure of a register in the high pressure set.
SmallVector< bool > HighPressureSets
List of pressure sets that have a high pressure level in the region.
static constexpr unsigned ScaleTwo
CandResult pickNodeFromQueue(VLIWSchedBoundary &Zone, const RegPressureTracker &RPTracker, SchedCandidate &Candidate)
Pick the best candidate from the top queue.
void schedNode(SUnit *SU, bool IsTopNode) override
Update the scheduler's state after scheduling a node.
void readyQueueVerboseDump(const RegPressureTracker &RPTracker, SchedCandidate &Candidate, ReadyQueue &Q)
void releaseTopNode(SUnit *SU) override
When all predecessor dependencies have been resolved, free this node for top-down scheduling.
SUnit * pickNodeBidrectional(bool &IsTopNode)
Pick the best candidate node from either the top or bottom queue.
static constexpr unsigned PriorityTwo
static constexpr unsigned PriorityThree
const TargetSchedModel * SchedModel
void initialize(ScheduleDAGMI *dag) override
Initialize the strategy after building the DAG for a new region.
virtual int SchedulingCost(ReadyQueue &Q, SUnit *SU, SchedCandidate &Candidate, RegPressureDelta &Delta, bool verbose)
Single point to compute overall scheduling cost.
void traceCandidate(const char *Label, const ReadyQueue &Q, SUnit *SU, int Cost, PressureChange P=PressureChange())
CandResult
Represent the type of SchedCandidate found within a single queue.
bool canReserveResources(const MCInstrDesc *MID)
void reserveResources(const MCInstrDesc *MID)
Itinerary data supplied by a subtarget to be used by a target.
unsigned getLoopDepth(const BlockT *BB) const
Return the loop nesting level of the specified block.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
StringRef getName() const
Return the name of the corresponding LLVM basic block, or an empty string.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
bool isPseudo(QueryType Type=IgnoreBundle) const
Return true if this is a pseudo instruction that doesn't correspond to a real machine instruction.
Capture a change in pressure for a single pressure set.
List of PressureChanges in order of increasing, unique PSetID.
Helpers for implementing custom MachineSchedStrategy classes.
std::vector< SUnit * >::iterator iterator
StringRef getName() const
Track the current register pressure at some position in the instruction stream, and remember the high...
void getMaxPressureDelta(const MachineInstr *MI, RegPressureDelta &Delta, ArrayRef< PressureChange > CriticalPSets, ArrayRef< unsigned > MaxPressureLimit)
Find the pressure set with the most change beyond its pressure limit after traversing this instructio...
unsigned getRegPressureSetLimit(unsigned Idx) const
Get the register unit limit for the given pressure set index.
unsigned getLatency() const
Returns the latency value for this edge, which roughly means the minimum number of cycles that must e...
bool isAssignedRegDep() const
Tests if this is a Data dependence that is associated with a register.
Scheduling unit. This is a node in the scheduling DAG.
bool isCall
Is a function call.
unsigned TopReadyCycle
Cycle relative to start when node is ready.
unsigned NodeNum
Entry # of node in the node vector.
unsigned getHeight() const
Returns the height of this node, which is the length of the maximum path down to any node which has n...
bool isScheduleHigh
True if preferable to schedule high.
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...
bool isScheduled
True once scheduled.
unsigned BotReadyCycle
Cycle relative to end when node is ready.
SmallVector< SDep, 4 > Succs
All sunit successors.
bool isBottomReady() const
SmallVector< SDep, 4 > Preds
All sunit predecessors.
SmallVectorImpl< SDep >::iterator succ_iterator
MachineInstr * getInstr() const
Returns the representative MachineInstr for this SUnit.
MachineBasicBlock * BB
The block in which to insert instructions.
const TargetSchedModel * getSchedModel() const
Gets the machine model for instruction scheduling.
ScheduleDAGTopologicalSort Topo
Topo - A topological ordering for SUnits which permits fast IsReachable and similar queries.
void dumpNode(const SUnit &SU) const override
MachineBasicBlock::iterator begin() const
Returns an iterator to the top of the current scheduling region.
const MachineLoopInfo * MLI
void scheduleMI(SUnit *SU, bool IsTopNode)
Move an instruction and update register pressure.
PressureDiff & getPressureDiff(const SUnit *SU)
void initQueues(ArrayRef< SUnit * > TopRoots, ArrayRef< SUnit * > BotRoots)
Release ExitSU predecessors and setup scheduler queues.
void buildDAGWithRegPressure()
Call ScheduleDAGInstrs::buildSchedGraph with register pressure tracking enabled.
const RegPressureTracker & getBotRPTracker() const
const RegPressureTracker & getTopRPTracker() const
const IntervalPressure & getRegPressure() const
Get register pressure for the entire scheduling region before scheduling.
void dump() const override
const std::vector< PressureChange > & getRegionCriticalPSets() const
ScheduleDAGMI is an implementation of ScheduleDAGInstrs that simply schedules machine instructions ac...
void dumpSchedule() const
dump the scheduled Sequence.
std::unique_ptr< MachineSchedStrategy > SchedImpl
void postProcessDAG()
Apply each ScheduleDAGMutation step in order.
MachineBasicBlock::iterator top() const
void findRootsAndBiasEdges(SmallVectorImpl< SUnit * > &TopRoots, SmallVectorImpl< SUnit * > &BotRoots)
MachineBasicBlock::iterator bottom() const
MachineBasicBlock::iterator CurrentBottom
The bottom of the unscheduled zone.
void viewGraph() override
Out-of-line implementation with no arguments is handy for gdb.
void updateQueues(SUnit *SU, bool IsTopNode)
Update scheduler DAG and queues after scheduling an instruction.
void placeDebugValues()
Reinsert debug_values recorded in ScheduleDAGInstrs::DbgValues.
MachineBasicBlock::iterator CurrentTop
The top of the unscheduled zone.
void InitDAGTopologicalSorting()
Creates the initial topological ordering from the DAG to be scheduled.
std::vector< SUnit > SUnits
The scheduling units.
const TargetRegisterInfo * TRI
Target processor register info.
MachineFunction & MF
Machine function.
void assign(size_type NumElts, ValueParamT Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
TargetInstrInfo - Interface to description of machine instruction set.
virtual DFAPacketizer * CreateTargetScheduleState(const TargetSubtargetInfo &) const
Create machine specific model for scheduling.
virtual const char * getRegPressureSetName(unsigned Idx) const =0
Get the name of this register unit pressure set.
Provide an instruction scheduling machine model to CodeGen passes.
unsigned getIssueWidth() const
Maximum number of micro-ops that may be scheduled per cycle.
unsigned getNumMicroOps(const MachineInstr *MI, const MCSchedClassDesc *SC=nullptr) const
Return the number of issue slots required for this MI.
const InstrItineraryData * getInstrItineraries() const
TargetSubtargetInfo - Generic base class for all target subtargets.
virtual const TargetInstrInfo * getInstrInfo() const
Extend the standard ScheduleDAGMILive to provide more context and override the top-level schedule() d...
RegisterClassInfo * getRegClassInfo()
void schedule() override
Schedule - This is called back from ScheduleDAGInstrs::Run() when it's time to do some work.
unsigned TotalPackets
Total packets created.
virtual ~VLIWResourceModel()
virtual bool hasDependence(const SUnit *SUd, const SUnit *SUu)
Return true if there is a dependence between SUd and SUu.
virtual DFAPacketizer * createPacketizer(const TargetSubtargetInfo &STI) const
virtual bool reserveResources(SUnit *SU, bool IsTop)
Keep track of available resources.
bool isInPacket(SUnit *SU) const
DFAPacketizer * ResourcesModel
ResourcesModel - Represents VLIW state.
SmallVector< SUnit * > Packet
Local packet/bundle model.
const TargetSchedModel * SchedModel
VLIWResourceModel(const TargetSubtargetInfo &STI, const TargetSchedModel *SM)
virtual bool isResourceAvailable(SUnit *SU, bool IsTop)
Check if scheduling of this SU is possible in the current packet.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
unsigned getWeakLeft(const SUnit *SU, bool isTop)
cl::opt< bool > ViewMISchedDAGs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
cl::opt< MISched::Direction > PreRADirection
Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
Store the state used by ConvergingVLIWScheduler heuristics, required for the lifetime of one invocati...
Each Scheduling boundary is associated with ready queues.
bool isLatencyBound(SUnit *SU)
void releaseNode(SUnit *SU, unsigned ReadyCycle)
void removeReady(SUnit *SU)
Remove SU from the ready set for this boundary.
ScheduleHazardRecognizer * HazardRec
void bumpNode(SUnit *SU)
Move the boundary of scheduled code by one SUnit.
VLIWResourceModel * ResourceModel
void releasePending()
Release pending ready nodes in to the available queue.
SUnit * pickOnlyChoice()
If this queue only has one ready candidate, return it.
void init(VLIWMachineScheduler *dag, const TargetSchedModel *smodel)
void bumpCycle()
Move the boundary of scheduled code by one cycle.
bool checkHazard(SUnit *SU)
Does this SU have a hazard within the current instruction group.
Store the effects of a change in pressure on things that MI scheduler cares about.
PressureChange CriticalMax
PressureChange CurrentMax
std::vector< unsigned > MaxSetPressure
Map of max reg pressure indexed by pressure set ID, not class ID.