1 //===- HexagonMachineScheduler.cpp - MI Scheduler for Hexagon -------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // MachineScheduler schedules machine instructions after phi elimination. It
11 // preserves LiveIntervals so it can be invoked before register allocation.
13 //===----------------------------------------------------------------------===//
15 #define DEBUG_TYPE "misched"
17 #include "HexagonMachineScheduler.h"
23 static cl::opt<bool> ForceTopDown("vliw-misched-topdown", cl::Hidden,
24 cl::desc("Force top-down list scheduling"));
25 static cl::opt<bool> ForceBottomUp("vliw-misched-bottomup", cl::Hidden,
26 cl::desc("Force bottom-up list scheduling"));
29 static cl::opt<bool> ViewMISchedDAGs("vliw-view-misched-dags", cl::Hidden,
30 cl::desc("Pop up a window to show MISched dags after they are processed"));
32 static cl::opt<unsigned> MISchedCutoff("vliw-misched-cutoff", cl::Hidden,
33 cl::desc("Stop scheduling after N instructions"), cl::init(~0U));
35 static bool ViewMISchedDAGs = false;
38 /// Decrement this iterator until reaching the top or a non-debug instr.
39 static MachineBasicBlock::iterator
40 priorNonDebug(MachineBasicBlock::iterator I, MachineBasicBlock::iterator Beg) {
41 assert(I != Beg && "reached the top of the region, cannot decrement");
43 if (!I->isDebugValue())
49 /// If this iterator is a debug value, increment until reaching the End or a
50 /// non-debug instruction.
51 static MachineBasicBlock::iterator
52 nextIfDebug(MachineBasicBlock::iterator I, MachineBasicBlock::iterator End) {
53 for(; I != End; ++I) {
54 if (!I->isDebugValue())
60 /// ReleaseSucc - Decrement the NumPredsLeft count of a successor. When
61 /// NumPredsLeft reaches zero, release the successor node.
63 /// FIXME: Adjust SuccSU height based on MinLatency.
64 void VLIWMachineScheduler::releaseSucc(SUnit *SU, SDep *SuccEdge) {
65 SUnit *SuccSU = SuccEdge->getSUnit();
68 if (SuccSU->NumPredsLeft == 0) {
69 dbgs() << "*** Scheduling failed! ***\n";
71 dbgs() << " has been released too many times!\n";
75 --SuccSU->NumPredsLeft;
76 if (SuccSU->NumPredsLeft == 0 && SuccSU != &ExitSU)
77 SchedImpl->releaseTopNode(SuccSU);
80 /// releaseSuccessors - Call releaseSucc on each of SU's successors.
81 void VLIWMachineScheduler::releaseSuccessors(SUnit *SU) {
82 for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end();
88 /// ReleasePred - Decrement the NumSuccsLeft count of a predecessor. When
89 /// NumSuccsLeft reaches zero, release the predecessor node.
91 /// FIXME: Adjust PredSU height based on MinLatency.
92 void VLIWMachineScheduler::releasePred(SUnit *SU, SDep *PredEdge) {
93 SUnit *PredSU = PredEdge->getSUnit();
96 if (PredSU->NumSuccsLeft == 0) {
97 dbgs() << "*** Scheduling failed! ***\n";
99 dbgs() << " has been released too many times!\n";
103 --PredSU->NumSuccsLeft;
104 if (PredSU->NumSuccsLeft == 0 && PredSU != &EntrySU)
105 SchedImpl->releaseBottomNode(PredSU);
108 /// releasePredecessors - Call releasePred on each of SU's predecessors.
109 void VLIWMachineScheduler::releasePredecessors(SUnit *SU) {
110 for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
112 releasePred(SU, &*I);
116 void VLIWMachineScheduler::moveInstruction(MachineInstr *MI,
117 MachineBasicBlock::iterator InsertPos) {
118 // Advance RegionBegin if the first instruction moves down.
119 if (&*RegionBegin == MI)
122 // Update the instruction stream.
123 BB->splice(InsertPos, BB, MI);
125 // Update LiveIntervals
128 // Recede RegionBegin if an instruction moves above the first.
129 if (RegionBegin == InsertPos)
133 bool VLIWMachineScheduler::checkSchedLimit() {
135 if (NumInstrsScheduled == MISchedCutoff && MISchedCutoff != ~0U) {
136 CurrentTop = CurrentBottom;
139 ++NumInstrsScheduled;
144 /// enterRegion - Called back from MachineScheduler::runOnMachineFunction after
145 /// crossing a scheduling boundary. [begin, end) includes all instructions in
146 /// the region, including the boundary itself and single-instruction regions
147 /// that don't get scheduled.
148 void VLIWMachineScheduler::enterRegion(MachineBasicBlock *bb,
149 MachineBasicBlock::iterator begin,
150 MachineBasicBlock::iterator end,
153 ScheduleDAGInstrs::enterRegion(bb, begin, end, endcount);
155 // For convenience remember the end of the liveness region.
157 (RegionEnd == bb->end()) ? RegionEnd : llvm::next(RegionEnd);
160 // Setup the register pressure trackers for the top scheduled top and bottom
161 // scheduled regions.
162 void VLIWMachineScheduler::initRegPressure() {
163 TopRPTracker.init(&MF, RegClassInfo, LIS, BB, RegionBegin);
164 BotRPTracker.init(&MF, RegClassInfo, LIS, BB, LiveRegionEnd);
166 // Close the RPTracker to finalize live ins.
167 RPTracker.closeRegion();
169 DEBUG(RPTracker.getPressure().dump(TRI));
171 // Initialize the live ins and live outs.
172 TopRPTracker.addLiveRegs(RPTracker.getPressure().LiveInRegs);
173 BotRPTracker.addLiveRegs(RPTracker.getPressure().LiveOutRegs);
175 // Close one end of the tracker so we can call
176 // getMaxUpward/DownwardPressureDelta before advancing across any
177 // instructions. This converts currently live regs into live ins/outs.
178 TopRPTracker.closeTop();
179 BotRPTracker.closeBottom();
181 // Account for liveness generated by the region boundary.
182 if (LiveRegionEnd != RegionEnd)
183 BotRPTracker.recede();
185 assert(BotRPTracker.getPos() == RegionEnd && "Can't find the region bottom");
187 // Cache the list of excess pressure sets in this region. This will also track
188 // the max pressure in the scheduled code for these sets.
189 RegionCriticalPSets.clear();
190 std::vector<unsigned> RegionPressure = RPTracker.getPressure().MaxSetPressure;
191 for (unsigned i = 0, e = RegionPressure.size(); i < e; ++i) {
192 unsigned Limit = TRI->getRegPressureSetLimit(i);
193 DEBUG(dbgs() << TRI->getRegPressureSetName(i)
195 << " Actual " << RegionPressure[i] << "\n");
196 if (RegionPressure[i] > Limit)
197 RegionCriticalPSets.push_back(PressureElement(i, 0));
199 DEBUG(dbgs() << "Excess PSets: ";
200 for (unsigned i = 0, e = RegionCriticalPSets.size(); i != e; ++i)
201 dbgs() << TRI->getRegPressureSetName(
202 RegionCriticalPSets[i].PSetID) << " ";
208 // FIXME: When the pressure tracker deals in pressure differences then we won't
209 // iterate over all RegionCriticalPSets[i].
210 void VLIWMachineScheduler::
211 updateScheduledPressure(std::vector<unsigned> NewMaxPressure) {
212 for (unsigned i = 0, e = RegionCriticalPSets.size(); i < e; ++i) {
213 unsigned ID = RegionCriticalPSets[i].PSetID;
214 int &MaxUnits = RegionCriticalPSets[i].UnitIncrease;
215 if ((int)NewMaxPressure[ID] > MaxUnits)
216 MaxUnits = NewMaxPressure[ID];
220 /// Check if scheduling of this SU is possible
221 /// in the current packet.
222 /// It is _not_ precise (statefull), it is more like
223 /// another heuristic. Many corner cases are figured
225 bool VLIWResourceModel::isResourceAvailable(SUnit *SU) {
226 if (!SU || !SU->getInstr())
229 // First see if the pipeline could receive this instruction
230 // in the current cycle.
231 switch (SU->getInstr()->getOpcode()) {
233 if (!ResourcesModel->canReserveResources(SU->getInstr()))
235 case TargetOpcode::EXTRACT_SUBREG:
236 case TargetOpcode::INSERT_SUBREG:
237 case TargetOpcode::SUBREG_TO_REG:
238 case TargetOpcode::REG_SEQUENCE:
239 case TargetOpcode::IMPLICIT_DEF:
240 case TargetOpcode::COPY:
241 case TargetOpcode::INLINEASM:
245 // Now see if there are no other dependencies to instructions already
247 for (unsigned i = 0, e = Packet.size(); i != e; ++i) {
248 if (Packet[i]->Succs.size() == 0)
250 for (SUnit::const_succ_iterator I = Packet[i]->Succs.begin(),
251 E = Packet[i]->Succs.end(); I != E; ++I) {
252 // Since we do not add pseudos to packets, might as well
253 // ignore order dependencies.
257 if (I->getSUnit() == SU)
264 /// Keep track of available resources.
265 bool VLIWResourceModel::reserveResources(SUnit *SU) {
266 bool startNewCycle = false;
267 // If this SU does not fit in the packet
269 if (!isResourceAvailable(SU)) {
270 ResourcesModel->clearResources();
273 startNewCycle = true;
276 switch (SU->getInstr()->getOpcode()) {
278 ResourcesModel->reserveResources(SU->getInstr());
280 case TargetOpcode::EXTRACT_SUBREG:
281 case TargetOpcode::INSERT_SUBREG:
282 case TargetOpcode::SUBREG_TO_REG:
283 case TargetOpcode::REG_SEQUENCE:
284 case TargetOpcode::IMPLICIT_DEF:
285 case TargetOpcode::KILL:
286 case TargetOpcode::PROLOG_LABEL:
287 case TargetOpcode::EH_LABEL:
288 case TargetOpcode::COPY:
289 case TargetOpcode::INLINEASM:
292 Packet.push_back(SU);
295 DEBUG(dbgs() << "Packet[" << TotalPackets << "]:\n");
296 for (unsigned i = 0, e = Packet.size(); i != e; ++i) {
297 DEBUG(dbgs() << "\t[" << i << "] SU(");
298 DEBUG(dbgs() << Packet[i]->NodeNum << ")\t");
299 DEBUG(Packet[i]->getInstr()->dump());
303 // If packet is now full, reset the state so in the next cycle
305 if (Packet.size() >= InstrItins->SchedModel->IssueWidth) {
306 ResourcesModel->clearResources();
309 startNewCycle = true;
312 return startNewCycle;
315 // Release all DAG roots for scheduling.
316 void VLIWMachineScheduler::releaseRoots() {
317 SmallVector<SUnit*, 16> BotRoots;
319 for (std::vector<SUnit>::iterator
320 I = SUnits.begin(), E = SUnits.end(); I != E; ++I) {
321 // A SUnit is ready to top schedule if it has no predecessors.
322 if (I->Preds.empty())
323 SchedImpl->releaseTopNode(&(*I));
324 // A SUnit is ready to bottom schedule if it has no successors.
325 if (I->Succs.empty())
326 BotRoots.push_back(&(*I));
328 // Release bottom roots in reverse order so the higher priority nodes appear
329 // first. This is more natural and slightly more efficient.
330 for (SmallVectorImpl<SUnit*>::const_reverse_iterator
331 I = BotRoots.rbegin(), E = BotRoots.rend(); I != E; ++I)
332 SchedImpl->releaseBottomNode(*I);
335 /// schedule - Called back from MachineScheduler::runOnMachineFunction
336 /// after setting up the current scheduling region. [RegionBegin, RegionEnd)
337 /// only includes instructions that have DAG nodes, not scheduling boundaries.
338 void VLIWMachineScheduler::schedule() {
340 << "********** MI Converging Scheduling VLIW BB#" << BB->getNumber()
341 << " " << BB->getName()
342 << " in_func " << BB->getParent()->getFunction()->getName()
343 << " at loop depth " << MLI->getLoopDepth(BB)
346 // Initialize the register pressure tracker used by buildSchedGraph.
347 RPTracker.init(&MF, RegClassInfo, LIS, BB, LiveRegionEnd);
349 // Account for liveness generate by the region boundary.
350 if (LiveRegionEnd != RegionEnd)
353 // Build the DAG, and compute current register pressure.
354 buildSchedGraph(AA, &RPTracker);
356 // Initialize top/bottom trackers after computing region pressure.
359 // To view Height/Depth correctly, they should be accessed at least once.
360 DEBUG(unsigned maxH = 0;
361 for (unsigned su = 0, e = SUnits.size(); su != e; ++su)
362 if (SUnits[su].getHeight() > maxH)
363 maxH = SUnits[su].getHeight();
364 dbgs() << "Max Height " << maxH << "\n";);
365 DEBUG(unsigned maxD = 0;
366 for (unsigned su = 0, e = SUnits.size(); su != e; ++su)
367 if (SUnits[su].getDepth() > maxD)
368 maxD = SUnits[su].getDepth();
369 dbgs() << "Max Depth " << maxD << "\n";);
370 DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su)
371 SUnits[su].dumpAll(this));
373 if (ViewMISchedDAGs) viewGraph();
375 SchedImpl->initialize(this);
377 // Release edges from the special Entry node or to the special Exit node.
378 releaseSuccessors(&EntrySU);
379 releasePredecessors(&ExitSU);
381 // Release all DAG roots for scheduling.
384 CurrentTop = nextIfDebug(RegionBegin, RegionEnd);
385 CurrentBottom = RegionEnd;
386 bool IsTopNode = false;
387 while (SUnit *SU = SchedImpl->pickNode(IsTopNode)) {
388 if (!checkSchedLimit())
391 // Move the instruction to its new location in the instruction stream.
392 MachineInstr *MI = SU->getInstr();
395 assert(SU->isTopReady() && "node still has unscheduled dependencies");
396 if (&*CurrentTop == MI)
397 CurrentTop = nextIfDebug(++CurrentTop, CurrentBottom);
399 moveInstruction(MI, CurrentTop);
400 TopRPTracker.setPos(MI);
403 // Update top scheduled pressure.
404 TopRPTracker.advance();
405 assert(TopRPTracker.getPos() == CurrentTop && "out of sync");
406 updateScheduledPressure(TopRPTracker.getPressure().MaxSetPressure);
408 // Release dependent instructions for scheduling.
409 releaseSuccessors(SU);
411 assert(SU->isBottomReady() && "node still has unscheduled dependencies");
412 MachineBasicBlock::iterator priorII =
413 priorNonDebug(CurrentBottom, CurrentTop);
415 CurrentBottom = priorII;
417 if (&*CurrentTop == MI) {
418 CurrentTop = nextIfDebug(++CurrentTop, priorII);
419 TopRPTracker.setPos(CurrentTop);
421 moveInstruction(MI, CurrentBottom);
424 // Update bottom scheduled pressure.
425 BotRPTracker.recede();
426 assert(BotRPTracker.getPos() == CurrentBottom && "out of sync");
427 updateScheduledPressure(BotRPTracker.getPressure().MaxSetPressure);
429 // Release dependent instructions for scheduling.
430 releasePredecessors(SU);
432 SU->isScheduled = true;
433 SchedImpl->schedNode(SU, IsTopNode);
435 assert(CurrentTop == CurrentBottom && "Nonempty unscheduled zone.");
440 /// Reinsert any remaining debug_values, just like the PostRA scheduler.
441 void VLIWMachineScheduler::placeDebugValues() {
442 // If first instruction was a DBG_VALUE then put it back.
444 BB->splice(RegionBegin, BB, FirstDbgValue);
445 RegionBegin = FirstDbgValue;
448 for (std::vector<std::pair<MachineInstr *, MachineInstr *> >::iterator
449 DI = DbgValues.end(), DE = DbgValues.begin(); DI != DE; --DI) {
450 std::pair<MachineInstr *, MachineInstr *> P = *prior(DI);
451 MachineInstr *DbgValue = P.first;
452 MachineBasicBlock::iterator OrigPrevMI = P.second;
453 BB->splice(++OrigPrevMI, BB, DbgValue);
454 if (OrigPrevMI == llvm::prior(RegionEnd))
455 RegionEnd = DbgValue;
458 FirstDbgValue = NULL;
461 void ConvergingVLIWScheduler::initialize(VLIWMachineScheduler *dag) {
467 // Initialize the HazardRecognizers.
468 const TargetMachine &TM = DAG->MF.getTarget();
469 const InstrItineraryData *Itin = TM.getInstrItineraryData();
470 Top.HazardRec = TM.getInstrInfo()->CreateTargetMIHazardRecognizer(Itin, DAG);
471 Bot.HazardRec = TM.getInstrInfo()->CreateTargetMIHazardRecognizer(Itin, DAG);
473 Top.ResourceModel = new VLIWResourceModel(TM);
474 Bot.ResourceModel = new VLIWResourceModel(TM);
476 assert((!ForceTopDown || !ForceBottomUp) &&
477 "-misched-topdown incompatible with -misched-bottomup");
480 void ConvergingVLIWScheduler::releaseTopNode(SUnit *SU) {
484 for (SUnit::succ_iterator I = SU->Preds.begin(), E = SU->Preds.end();
486 unsigned PredReadyCycle = I->getSUnit()->TopReadyCycle;
487 unsigned MinLatency = I->getMinLatency();
489 Top.MaxMinLatency = std::max(MinLatency, Top.MaxMinLatency);
491 if (SU->TopReadyCycle < PredReadyCycle + MinLatency)
492 SU->TopReadyCycle = PredReadyCycle + MinLatency;
494 Top.releaseNode(SU, SU->TopReadyCycle);
497 void ConvergingVLIWScheduler::releaseBottomNode(SUnit *SU) {
501 assert(SU->getInstr() && "Scheduled SUnit must have instr");
503 for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end();
505 unsigned SuccReadyCycle = I->getSUnit()->BotReadyCycle;
506 unsigned MinLatency = I->getMinLatency();
508 Bot.MaxMinLatency = std::max(MinLatency, Bot.MaxMinLatency);
510 if (SU->BotReadyCycle < SuccReadyCycle + MinLatency)
511 SU->BotReadyCycle = SuccReadyCycle + MinLatency;
513 Bot.releaseNode(SU, SU->BotReadyCycle);
516 /// Does this SU have a hazard within the current instruction group.
518 /// The scheduler supports two modes of hazard recognition. The first is the
519 /// ScheduleHazardRecognizer API. It is a fully general hazard recognizer that
520 /// supports highly complicated in-order reservation tables
521 /// (ScoreboardHazardRecognizer) and arbitrary target-specific logic.
523 /// The second is a streamlined mechanism that checks for hazards based on
524 /// simple counters that the scheduler itself maintains. It explicitly checks
525 /// for instruction dispatch limitations, including the number of micro-ops that
526 /// can dispatch per cycle.
528 /// TODO: Also check whether the SU must start a new group.
529 bool ConvergingVLIWScheduler::SchedBoundary::checkHazard(SUnit *SU) {
530 if (HazardRec->isEnabled())
531 return HazardRec->getHazardType(SU) != ScheduleHazardRecognizer::NoHazard;
533 if (IssueCount + DAG->getNumMicroOps(SU->getInstr()) > DAG->getIssueWidth())
539 void ConvergingVLIWScheduler::SchedBoundary::releaseNode(SUnit *SU,
540 unsigned ReadyCycle) {
541 if (ReadyCycle < MinReadyCycle)
542 MinReadyCycle = ReadyCycle;
544 // Check for interlocks first. For the purpose of other heuristics, an
545 // instruction that cannot issue appears as if it's not in the ReadyQueue.
546 if (ReadyCycle > CurrCycle || checkHazard(SU))
553 /// Move the boundary of scheduled code by one cycle.
554 void ConvergingVLIWScheduler::SchedBoundary::bumpCycle() {
555 unsigned Width = DAG->getIssueWidth();
556 IssueCount = (IssueCount <= Width) ? 0 : IssueCount - Width;
558 assert(MinReadyCycle < UINT_MAX && "MinReadyCycle uninitialized");
559 unsigned NextCycle = std::max(CurrCycle + 1, MinReadyCycle);
561 if (!HazardRec->isEnabled()) {
562 // Bypass HazardRec virtual calls.
563 CurrCycle = NextCycle;
565 // Bypass getHazardType calls in case of long latency.
566 for (; CurrCycle != NextCycle; ++CurrCycle) {
568 HazardRec->AdvanceCycle();
570 HazardRec->RecedeCycle();
575 DEBUG(dbgs() << "*** " << Available.getName() << " cycle "
576 << CurrCycle << '\n');
579 /// Move the boundary of scheduled code by one SUnit.
580 void ConvergingVLIWScheduler::SchedBoundary::bumpNode(SUnit *SU) {
581 bool startNewCycle = false;
583 // Update the reservation table.
584 if (HazardRec->isEnabled()) {
585 if (!isTop() && SU->isCall) {
586 // Calls are scheduled with their preceding instructions. For bottom-up
587 // scheduling, clear the pipeline state before emitting.
590 HazardRec->EmitInstruction(SU);
594 startNewCycle = ResourceModel->reserveResources(SU);
596 // Check the instruction group dispatch limit.
597 // TODO: Check if this SU must end a dispatch group.
598 IssueCount += DAG->getNumMicroOps(SU->getInstr());
600 DEBUG(dbgs() << "*** Max instrs at cycle " << CurrCycle << '\n');
604 DEBUG(dbgs() << "*** IssueCount " << IssueCount
605 << " at cycle " << CurrCycle << '\n');
608 /// Release pending ready nodes in to the available queue. This makes them
609 /// visible to heuristics.
610 void ConvergingVLIWScheduler::SchedBoundary::releasePending() {
611 // If the available queue is empty, it is safe to reset MinReadyCycle.
612 if (Available.empty())
613 MinReadyCycle = UINT_MAX;
615 // Check to see if any of the pending instructions are ready to issue. If
616 // so, add them to the available queue.
617 for (unsigned i = 0, e = Pending.size(); i != e; ++i) {
618 SUnit *SU = *(Pending.begin()+i);
619 unsigned ReadyCycle = isTop() ? SU->TopReadyCycle : SU->BotReadyCycle;
621 if (ReadyCycle < MinReadyCycle)
622 MinReadyCycle = ReadyCycle;
624 if (ReadyCycle > CurrCycle)
631 Pending.remove(Pending.begin()+i);
634 CheckPending = false;
637 /// Remove SU from the ready set for this boundary.
638 void ConvergingVLIWScheduler::SchedBoundary::removeReady(SUnit *SU) {
639 if (Available.isInQueue(SU))
640 Available.remove(Available.find(SU));
642 assert(Pending.isInQueue(SU) && "bad ready count");
643 Pending.remove(Pending.find(SU));
647 /// If this queue only has one ready candidate, return it. As a side effect,
648 /// advance the cycle until at least one node is ready. If multiple instructions
649 /// are ready, return NULL.
650 SUnit *ConvergingVLIWScheduler::SchedBoundary::pickOnlyChoice() {
654 for (unsigned i = 0; Available.empty(); ++i) {
655 assert(i <= (HazardRec->getMaxLookAhead() + MaxMinLatency) &&
656 "permanent hazard"); (void)i;
660 if (Available.size() == 1)
661 return *Available.begin();
666 void ConvergingVLIWScheduler::traceCandidate(const char *Label,
668 SUnit *SU, PressureElement P) {
669 dbgs() << Label << " " << Q.getName() << " ";
671 dbgs() << TRI->getRegPressureSetName(P.PSetID) << ":" << P.UnitIncrease
679 /// getSingleUnscheduledPred - If there is exactly one unscheduled predecessor
680 /// of SU, return it, otherwise return null.
681 static SUnit *getSingleUnscheduledPred(SUnit *SU) {
682 SUnit *OnlyAvailablePred = 0;
683 for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
685 SUnit &Pred = *I->getSUnit();
686 if (!Pred.isScheduled) {
687 // We found an available, but not scheduled, predecessor. If it's the
688 // only one we have found, keep track of it... otherwise give up.
689 if (OnlyAvailablePred && OnlyAvailablePred != &Pred)
691 OnlyAvailablePred = &Pred;
694 return OnlyAvailablePred;
697 /// getSingleUnscheduledSucc - If there is exactly one unscheduled successor
698 /// of SU, return it, otherwise return null.
699 static SUnit *getSingleUnscheduledSucc(SUnit *SU) {
700 SUnit *OnlyAvailableSucc = 0;
701 for (SUnit::const_succ_iterator I = SU->Succs.begin(), E = SU->Succs.end();
703 SUnit &Succ = *I->getSUnit();
704 if (!Succ.isScheduled) {
705 // We found an available, but not scheduled, successor. If it's the
706 // only one we have found, keep track of it... otherwise give up.
707 if (OnlyAvailableSucc && OnlyAvailableSucc != &Succ)
709 OnlyAvailableSucc = &Succ;
712 return OnlyAvailableSucc;
715 // Constants used to denote relative importance of
716 // heuristic components for cost computation.
717 static const unsigned PriorityOne = 200;
718 static const unsigned PriorityTwo = 100;
719 static const unsigned PriorityThree = 50;
720 static const unsigned PriorityFour = 20;
721 static const unsigned ScaleTwo = 10;
722 static const unsigned FactorOne = 2;
724 /// Single point to compute overall scheduling cost.
725 /// TODO: More heuristics will be used soon.
726 int ConvergingVLIWScheduler::SchedulingCost(ReadyQueue &Q, SUnit *SU,
727 SchedCandidate &Candidate,
728 RegPressureDelta &Delta,
730 // Initial trivial priority.
733 // Do not waste time on a node that is already scheduled.
734 if (!SU || SU->isScheduled)
737 // Forced priority is high.
738 if (SU->isScheduleHigh)
739 ResCount += PriorityOne;
741 // Critical path first.
742 if (Q.getID() == TopQID) {
743 ResCount += (SU->getHeight() * ScaleTwo);
745 // If resources are available for it, multiply the
746 // chance of scheduling.
747 if (Top.ResourceModel->isResourceAvailable(SU))
748 ResCount <<= FactorOne;
750 ResCount += (SU->getDepth() * ScaleTwo);
752 // If resources are available for it, multiply the
753 // chance of scheduling.
754 if (Bot.ResourceModel->isResourceAvailable(SU))
755 ResCount <<= FactorOne;
758 unsigned NumNodesBlocking = 0;
759 if (Q.getID() == TopQID) {
760 // How many SUs does it block from scheduling?
761 // Look at all of the successors of this node.
762 // Count the number of nodes that
763 // this node is the sole unscheduled node for.
764 for (SUnit::const_succ_iterator I = SU->Succs.begin(), E = SU->Succs.end();
766 if (getSingleUnscheduledPred(I->getSUnit()) == SU)
769 // How many unscheduled predecessors block this node?
770 for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
772 if (getSingleUnscheduledSucc(I->getSUnit()) == SU)
775 ResCount += (NumNodesBlocking * ScaleTwo);
777 // Factor in reg pressure as a heuristic.
778 ResCount -= (Delta.Excess.UnitIncrease*PriorityThree);
779 ResCount -= (Delta.CriticalMax.UnitIncrease*PriorityThree);
781 DEBUG(if (verbose) dbgs() << " Total(" << ResCount << ")");
786 /// Pick the best candidate from the top queue.
788 /// TODO: getMaxPressureDelta results can be mostly cached for each SUnit during
789 /// DAG building. To adjust for the current scheduling location we need to
790 /// maintain the number of vreg uses remaining to be top-scheduled.
791 ConvergingVLIWScheduler::CandResult ConvergingVLIWScheduler::
792 pickNodeFromQueue(ReadyQueue &Q, const RegPressureTracker &RPTracker,
793 SchedCandidate &Candidate) {
796 // getMaxPressureDelta temporarily modifies the tracker.
797 RegPressureTracker &TempTracker = const_cast<RegPressureTracker&>(RPTracker);
799 // BestSU remains NULL if no top candidates beat the best existing candidate.
800 CandResult FoundCandidate = NoCand;
801 for (ReadyQueue::iterator I = Q.begin(), E = Q.end(); I != E; ++I) {
802 RegPressureDelta RPDelta;
803 TempTracker.getMaxPressureDelta((*I)->getInstr(), RPDelta,
804 DAG->getRegionCriticalPSets(),
805 DAG->getRegPressure().MaxSetPressure);
807 int CurrentCost = SchedulingCost(Q, *I, Candidate, RPDelta, false);
809 // Initialize the candidate if needed.
812 Candidate.RPDelta = RPDelta;
813 Candidate.SCost = CurrentCost;
814 FoundCandidate = NodeOrder;
819 if (CurrentCost > Candidate.SCost) {
820 DEBUG(traceCandidate("CCAND", Q, *I));
822 Candidate.RPDelta = RPDelta;
823 Candidate.SCost = CurrentCost;
824 FoundCandidate = BestCost;
828 // Fall through to original instruction order.
829 // Only consider node order if Candidate was chosen from this Q.
830 if (FoundCandidate == NoCand)
833 return FoundCandidate;
836 /// Pick the best candidate node from either the top or bottom queue.
837 SUnit *ConvergingVLIWScheduler::pickNodeBidrectional(bool &IsTopNode) {
838 // Schedule as far as possible in the direction of no choice. This is most
839 // efficient, but also provides the best heuristics for CriticalPSets.
840 if (SUnit *SU = Bot.pickOnlyChoice()) {
844 if (SUnit *SU = Top.pickOnlyChoice()) {
848 SchedCandidate BotCand;
849 // Prefer bottom scheduling when heuristics are silent.
850 CandResult BotResult = pickNodeFromQueue(Bot.Available,
851 DAG->getBotRPTracker(), BotCand);
852 assert(BotResult != NoCand && "failed to find the first candidate");
854 // If either Q has a single candidate that provides the least increase in
855 // Excess pressure, we can immediately schedule from that Q.
857 // RegionCriticalPSets summarizes the pressure within the scheduled region and
858 // affects picking from either Q. If scheduling in one direction must
859 // increase pressure for one of the excess PSets, then schedule in that
860 // direction first to provide more freedom in the other direction.
861 if (BotResult == SingleExcess || BotResult == SingleCritical) {
865 // Check if the top Q has a better candidate.
866 SchedCandidate TopCand;
867 CandResult TopResult = pickNodeFromQueue(Top.Available,
868 DAG->getTopRPTracker(), TopCand);
869 assert(TopResult != NoCand && "failed to find the first candidate");
871 if (TopResult == SingleExcess || TopResult == SingleCritical) {
875 // If either Q has a single candidate that minimizes pressure above the
876 // original region's pressure pick it.
877 if (BotResult == SingleMax) {
881 if (TopResult == SingleMax) {
885 if (TopCand.SCost > BotCand.SCost) {
889 // Otherwise prefer the bottom candidate in node order.
894 /// Pick the best node to balance the schedule. Implements MachineSchedStrategy.
895 SUnit *ConvergingVLIWScheduler::pickNode(bool &IsTopNode) {
896 if (DAG->top() == DAG->bottom()) {
897 assert(Top.Available.empty() && Top.Pending.empty() &&
898 Bot.Available.empty() && Bot.Pending.empty() && "ReadyQ garbage");
903 SU = Top.pickOnlyChoice();
905 SchedCandidate TopCand;
906 CandResult TopResult =
907 pickNodeFromQueue(Top.Available, DAG->getTopRPTracker(), TopCand);
908 assert(TopResult != NoCand && "failed to find the first candidate");
913 } else if (ForceBottomUp) {
914 SU = Bot.pickOnlyChoice();
916 SchedCandidate BotCand;
917 CandResult BotResult =
918 pickNodeFromQueue(Bot.Available, DAG->getBotRPTracker(), BotCand);
919 assert(BotResult != NoCand && "failed to find the first candidate");
925 SU = pickNodeBidrectional(IsTopNode);
927 if (SU->isTopReady())
929 if (SU->isBottomReady())
932 DEBUG(dbgs() << "*** " << (IsTopNode ? "Top" : "Bottom")
933 << " Scheduling Instruction in cycle "
934 << (IsTopNode ? Top.CurrCycle : Bot.CurrCycle) << '\n';
939 /// Update the scheduler's state after scheduling a node. This is the same node
940 /// that was just returned by pickNode(). However, VLIWMachineScheduler needs
941 /// to update it's state based on the current cycle before MachineSchedStrategy
943 void ConvergingVLIWScheduler::schedNode(SUnit *SU, bool IsTopNode) {
945 SU->TopReadyCycle = Top.CurrCycle;
948 SU->BotReadyCycle = Bot.CurrCycle;