38 #define DEBUG_TYPE "pre-RA-sched"
40 STATISTIC(NumNoops ,
"Number of noops inserted");
41 STATISTIC(NumStalls,
"Number of pipeline stalls");
62 std::vector<SUnit*> PendingQueue;
79 ~ScheduleDAGVLIW()
override {
81 delete AvailableQueue;
84 void Schedule()
override;
88 void releaseSuccessors(
SUnit *SU);
89 void scheduleNodeTopDown(
SUnit *SU,
unsigned CurCycle);
90 void listScheduleTopDown();
95 void ScheduleDAGVLIW::Schedule() {
97 <<
"********** List Scheduling BB#" << BB->getNumber()
98 <<
" '" << BB->getName() <<
"' **********\n");
103 AvailableQueue->initNodes(SUnits);
105 listScheduleTopDown();
107 AvailableQueue->releaseState();
116 void ScheduleDAGVLIW::releaseSucc(
SUnit *SU,
const SDep &
D) {
121 dbgs() <<
"*** Scheduling failed! ***\n";
123 dbgs() <<
" has been released too many times!\n";
127 assert(!D.
isWeak() &&
"unexpected artificial DAG edge");
136 PendingQueue.push_back(SuccSU);
140 void ScheduleDAGVLIW::releaseSuccessors(
SUnit *SU) {
144 assert(!
I->isAssignedRegDep() &&
145 "The list-td scheduler doesn't yet support physreg dependencies!");
154 void ScheduleDAGVLIW::scheduleNodeTopDown(
SUnit *SU,
unsigned CurCycle) {
155 DEBUG(
dbgs() <<
"*** Scheduling [" << CurCycle <<
"]: ");
159 assert(CurCycle >= SU->
getDepth() &&
"Node scheduled above its depth!");
162 releaseSuccessors(SU);
164 AvailableQueue->scheduledNode(SU);
169 void ScheduleDAGVLIW::listScheduleTopDown() {
170 unsigned CurCycle = 0;
173 releaseSuccessors(&EntrySU);
176 for (
unsigned i = 0, e = SUnits.size();
i != e; ++
i) {
178 if (SUnits[
i].Preds.empty()) {
179 AvailableQueue->push(&SUnits[
i]);
180 SUnits[
i].isAvailable =
true;
186 std::vector<SUnit*> NotReady;
188 while (!AvailableQueue->empty() || !PendingQueue.empty()) {
191 for (
unsigned i = 0, e = PendingQueue.size();
i != e; ++
i) {
192 if (PendingQueue[
i]->getDepth() == CurCycle) {
193 AvailableQueue->push(PendingQueue[
i]);
194 PendingQueue[
i]->isAvailable =
true;
195 PendingQueue[
i] = PendingQueue.back();
196 PendingQueue.pop_back();
200 assert(PendingQueue[i]->getDepth() > CurCycle &&
"Negative latency?");
206 if (AvailableQueue->empty()) {
208 AvailableQueue->scheduledNode(
nullptr);
213 SUnit *FoundSUnit =
nullptr;
215 bool HasNoopHazards =
false;
216 while (!AvailableQueue->empty()) {
217 SUnit *CurSUnit = AvailableQueue->pop();
220 HazardRec->getHazardType(CurSUnit, 0);
222 FoundSUnit = CurSUnit;
229 NotReady.push_back(CurSUnit);
233 if (!NotReady.empty()) {
234 AvailableQueue->push_all(NotReady);
240 scheduleNodeTopDown(FoundSUnit, CurCycle);
241 HazardRec->EmitInstruction(FoundSUnit);
247 }
else if (!HasNoopHazards) {
250 DEBUG(
dbgs() <<
"*** Advancing cycle, no work to do\n");
251 HazardRec->AdvanceCycle();
259 HazardRec->EmitNoop();
267 VerifyScheduledSequence(
false);
STATISTIC(NumFunctions,"Total number of functions")
SchedulingPriorityQueue - This interface is used to plug different priorities computation algorithms ...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
bool isWeak() const
isWeak - Test if this a weak dependence.
static GCRegistry::Add< StatepointGC > D("statepoint-example","an example strategy for statepoint")
static RegisterScheduler VLIWScheduler("vliw-td","VLIW scheduler", createVLIWDAGScheduler)
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
void setDepthToAtLeast(unsigned NewDepth)
setDepthToAtLeast - If NewDepth is greater than this node's depth value, set it to be the new depth v...
SDep - Scheduling dependency.
ScheduleDAGSDNodes - A ScheduleDAG for scheduling SDNode-based DAGs.
ScheduleDAGSDNodes * createVLIWDAGScheduler(SelectionDAGISel *IS, CodeGenOpt::Level OptLevel)
createVLIWDAGScheduler - Scheduler for VLIW targets.
HazardRecognizer - This determines whether or not an instruction can be issued this cycle...
unsigned getLatency() const
getLatency - Return the latency value for this edge, which roughly means the minimum number of cycles...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
unsigned getDepth() const
getDepth - Return the depth of this node, which is the length of the maximum path up to any node whic...
TargetSubtargetInfo - Generic base class for all target subtargets.
Sequence
A sequence of states that a pointer may go through in which an objc_retain and objc_release are actua...
virtual ScheduleHazardRecognizer * CreateTargetHazardRecognizer(const TargetSubtargetInfo *STI, const ScheduleDAG *DAG) const
Allocate and return a hazard recognizer to use for this target when scheduling the machine instructio...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
virtual const TargetInstrInfo * getInstrInfo() const
SmallVector< SDep, 4 > Succs
void dump(const ScheduleDAG *G) const
SUnit - Scheduling unit.
SUnit - Scheduling unit. This is a node in the scheduling DAG.