1 //===- HexagonMachineScheduler.cpp - MI Scheduler for Hexagon -------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // MachineScheduler schedules machine instructions after phi elimination. It
11 // preserves LiveIntervals so it can be invoked before register allocation.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "HexagonMachineScheduler.h"
16 #include "HexagonSubtarget.h"
17 #include "llvm/CodeGen/MachineLoopInfo.h"
18 #include "llvm/IR/Function.h"
19 
20 #include <iomanip>
21 #include <sstream>
22 
23 static cl::opt<bool> IgnoreBBRegPressure("ignore-bb-reg-pressure",
24     cl::Hidden, cl::ZeroOrMore, cl::init(false));
25 
26 static cl::opt<unsigned> SchedDebugVerboseLevel("misched-verbose-level",
27     cl::Hidden, cl::ZeroOrMore, cl::init(1));
28 
29 static cl::opt<bool> TopUseShorterTie("top-use-shorter-tie",
30     cl::Hidden, cl::ZeroOrMore, cl::init(false));
31 
32 static cl::opt<bool> BotUseShorterTie("bot-use-shorter-tie",
33     cl::Hidden, cl::ZeroOrMore, cl::init(false));
34 
35 static cl::opt<bool> DisableTCTie("disable-tc-tie",
36     cl::Hidden, cl::ZeroOrMore, cl::init(false));
37 
38 // Check if the scheduler should penalize instructions that are available to
39 // early due to a zero-latency dependence.
40 static cl::opt<bool> CheckEarlyAvail("check-early-avail", cl::Hidden,
41     cl::ZeroOrMore, cl::init(true));
42 
43 using namespace llvm;
44 
45 #define DEBUG_TYPE "machine-scheduler"
46 
47 /// Save the last formed packet
48 void VLIWResourceModel::savePacket() {
49   OldPacket = Packet;
50 }
51 
52 /// Check if scheduling of this SU is possible
53 /// in the current packet.
54 /// It is _not_ precise (statefull), it is more like
55 /// another heuristic. Many corner cases are figured
56 /// empirically.
57 bool VLIWResourceModel::isResourceAvailable(SUnit *SU) {
58   if (!SU || !SU->getInstr())
59     return false;
60 
61   // First see if the pipeline could receive this instruction
62   // in the current cycle.
63   switch (SU->getInstr()->getOpcode()) {
64   default:
65     if (!ResourcesModel->canReserveResources(*SU->getInstr()))
66       return false;
67   case TargetOpcode::EXTRACT_SUBREG:
68   case TargetOpcode::INSERT_SUBREG:
69   case TargetOpcode::SUBREG_TO_REG:
70   case TargetOpcode::REG_SEQUENCE:
71   case TargetOpcode::IMPLICIT_DEF:
72   case TargetOpcode::COPY:
73   case TargetOpcode::INLINEASM:
74     break;
75   }
76 
77   MachineFunction &MF = *SU->getInstr()->getParent()->getParent();
78   auto &QII = *MF.getSubtarget<HexagonSubtarget>().getInstrInfo();
79 
80   // Now see if there are no other dependencies to instructions already
81   // in the packet.
82   for (unsigned i = 0, e = Packet.size(); i != e; ++i) {
83     if (Packet[i]->Succs.size() == 0)
84       continue;
85 
86     // Enable .cur formation.
87     if (QII.mayBeCurLoad(*Packet[i]->getInstr()))
88       continue;
89 
90     for (SUnit::const_succ_iterator I = Packet[i]->Succs.begin(),
91          E = Packet[i]->Succs.end(); I != E; ++I) {
92       // Since we do not add pseudos to packets, might as well
93       // ignore order dependencies.
94       if (I->isCtrl())
95         continue;
96 
97       if (I->getSUnit() == SU)
98         return false;
99     }
100   }
101   return true;
102 }
103 
104 /// Keep track of available resources.
105 bool VLIWResourceModel::reserveResources(SUnit *SU) {
106   bool startNewCycle = false;
107   // Artificially reset state.
108   if (!SU) {
109     ResourcesModel->clearResources();
110     savePacket();
111     Packet.clear();
112     TotalPackets++;
113     return false;
114   }
115   // If this SU does not fit in the packet
116   // start a new one.
117   if (!isResourceAvailable(SU)) {
118     ResourcesModel->clearResources();
119     savePacket();
120     Packet.clear();
121     TotalPackets++;
122     startNewCycle = true;
123   }
124 
125   switch (SU->getInstr()->getOpcode()) {
126   default:
127     ResourcesModel->reserveResources(*SU->getInstr());
128     break;
129   case TargetOpcode::EXTRACT_SUBREG:
130   case TargetOpcode::INSERT_SUBREG:
131   case TargetOpcode::SUBREG_TO_REG:
132   case TargetOpcode::REG_SEQUENCE:
133   case TargetOpcode::IMPLICIT_DEF:
134   case TargetOpcode::KILL:
135   case TargetOpcode::CFI_INSTRUCTION:
136   case TargetOpcode::EH_LABEL:
137   case TargetOpcode::COPY:
138   case TargetOpcode::INLINEASM:
139     break;
140   }
141   Packet.push_back(SU);
142 
143 #ifndef NDEBUG
144   DEBUG(dbgs() << "Packet[" << TotalPackets << "]:\n");
145   for (unsigned i = 0, e = Packet.size(); i != e; ++i) {
146     DEBUG(dbgs() << "\t[" << i << "] SU(");
147     DEBUG(dbgs() << Packet[i]->NodeNum << ")\t");
148     DEBUG(Packet[i]->getInstr()->dump());
149   }
150 #endif
151 
152   // If packet is now full, reset the state so in the next cycle
153   // we start fresh.
154   if (Packet.size() >= SchedModel->getIssueWidth()) {
155     ResourcesModel->clearResources();
156     savePacket();
157     Packet.clear();
158     TotalPackets++;
159     startNewCycle = true;
160   }
161 
162   return startNewCycle;
163 }
164 
165 /// schedule - Called back from MachineScheduler::runOnMachineFunction
166 /// after setting up the current scheduling region. [RegionBegin, RegionEnd)
167 /// only includes instructions that have DAG nodes, not scheduling boundaries.
168 void VLIWMachineScheduler::schedule() {
169   DEBUG(dbgs()
170         << "********** MI Converging Scheduling VLIW BB#" << BB->getNumber()
171         << " " << BB->getName()
172         << " in_func " << BB->getParent()->getFunction()->getName()
173         << " at loop depth "  << MLI->getLoopDepth(BB)
174         << " \n");
175 
176   buildDAGWithRegPressure();
177 
178   SmallVector<SUnit*, 8> TopRoots, BotRoots;
179   findRootsAndBiasEdges(TopRoots, BotRoots);
180 
181   // Initialize the strategy before modifying the DAG.
182   SchedImpl->initialize(this);
183 
184   DEBUG(unsigned maxH = 0;
185         for (unsigned su = 0, e = SUnits.size(); su != e; ++su)
186           if (SUnits[su].getHeight() > maxH)
187             maxH = SUnits[su].getHeight();
188         dbgs() << "Max Height " << maxH << "\n";);
189   DEBUG(unsigned maxD = 0;
190         for (unsigned su = 0, e = SUnits.size(); su != e; ++su)
191           if (SUnits[su].getDepth() > maxD)
192             maxD = SUnits[su].getDepth();
193         dbgs() << "Max Depth " << maxD << "\n";);
194   DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su)
195           SUnits[su].dumpAll(this));
196 
197   initQueues(TopRoots, BotRoots);
198 
199   bool IsTopNode = false;
200   while (true) {
201     DEBUG(dbgs() << "** VLIWMachineScheduler::schedule picking next node\n");
202     SUnit *SU = SchedImpl->pickNode(IsTopNode);
203     if (!SU) break;
204 
205     if (!checkSchedLimit())
206       break;
207 
208     scheduleMI(SU, IsTopNode);
209 
210     updateQueues(SU, IsTopNode);
211 
212     // Notify the scheduling strategy after updating the DAG.
213     SchedImpl->schedNode(SU, IsTopNode);
214   }
215   assert(CurrentTop == CurrentBottom && "Nonempty unscheduled zone.");
216 
217   placeDebugValues();
218 
219   DEBUG({
220     unsigned BBNum = begin()->getParent()->getNumber();
221     dbgs() << "*** Final schedule for BB#" << BBNum << " ***\n";
222     dumpSchedule();
223     dbgs() << '\n';
224   });
225 }
226 
227 void ConvergingVLIWScheduler::initialize(ScheduleDAGMI *dag) {
228   DAG = static_cast<VLIWMachineScheduler*>(dag);
229   SchedModel = DAG->getSchedModel();
230 
231   Top.init(DAG, SchedModel);
232   Bot.init(DAG, SchedModel);
233 
234   // Initialize the HazardRecognizers. If itineraries don't exist, are empty, or
235   // are disabled, then these HazardRecs will be disabled.
236   const InstrItineraryData *Itin = DAG->getSchedModel()->getInstrItineraries();
237   const TargetSubtargetInfo &STI = DAG->MF.getSubtarget();
238   const TargetInstrInfo *TII = STI.getInstrInfo();
239   delete Top.HazardRec;
240   delete Bot.HazardRec;
241   Top.HazardRec = TII->CreateTargetMIHazardRecognizer(Itin, DAG);
242   Bot.HazardRec = TII->CreateTargetMIHazardRecognizer(Itin, DAG);
243 
244   delete Top.ResourceModel;
245   delete Bot.ResourceModel;
246   Top.ResourceModel = new VLIWResourceModel(STI, DAG->getSchedModel());
247   Bot.ResourceModel = new VLIWResourceModel(STI, DAG->getSchedModel());
248 
249   assert((!llvm::ForceTopDown || !llvm::ForceBottomUp) &&
250          "-misched-topdown incompatible with -misched-bottomup");
251 }
252 
253 void ConvergingVLIWScheduler::releaseTopNode(SUnit *SU) {
254   if (SU->isScheduled)
255     return;
256 
257   for (const SDep &PI : SU->Preds) {
258     unsigned PredReadyCycle = PI.getSUnit()->TopReadyCycle;
259     unsigned MinLatency = PI.getLatency();
260 #ifndef NDEBUG
261     Top.MaxMinLatency = std::max(MinLatency, Top.MaxMinLatency);
262 #endif
263     if (SU->TopReadyCycle < PredReadyCycle + MinLatency)
264       SU->TopReadyCycle = PredReadyCycle + MinLatency;
265   }
266   Top.releaseNode(SU, SU->TopReadyCycle);
267 }
268 
269 void ConvergingVLIWScheduler::releaseBottomNode(SUnit *SU) {
270   if (SU->isScheduled)
271     return;
272 
273   assert(SU->getInstr() && "Scheduled SUnit must have instr");
274 
275   for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end();
276        I != E; ++I) {
277     unsigned SuccReadyCycle = I->getSUnit()->BotReadyCycle;
278     unsigned MinLatency = I->getLatency();
279 #ifndef NDEBUG
280     Bot.MaxMinLatency = std::max(MinLatency, Bot.MaxMinLatency);
281 #endif
282     if (SU->BotReadyCycle < SuccReadyCycle + MinLatency)
283       SU->BotReadyCycle = SuccReadyCycle + MinLatency;
284   }
285   Bot.releaseNode(SU, SU->BotReadyCycle);
286 }
287 
288 /// Does this SU have a hazard within the current instruction group.
289 ///
290 /// The scheduler supports two modes of hazard recognition. The first is the
291 /// ScheduleHazardRecognizer API. It is a fully general hazard recognizer that
292 /// supports highly complicated in-order reservation tables
293 /// (ScoreboardHazardRecognizer) and arbitrary target-specific logic.
294 ///
295 /// The second is a streamlined mechanism that checks for hazards based on
296 /// simple counters that the scheduler itself maintains. It explicitly checks
297 /// for instruction dispatch limitations, including the number of micro-ops that
298 /// can dispatch per cycle.
299 ///
300 /// TODO: Also check whether the SU must start a new group.
301 bool ConvergingVLIWScheduler::VLIWSchedBoundary::checkHazard(SUnit *SU) {
302   if (HazardRec->isEnabled())
303     return HazardRec->getHazardType(SU) != ScheduleHazardRecognizer::NoHazard;
304 
305   unsigned uops = SchedModel->getNumMicroOps(SU->getInstr());
306   if (IssueCount + uops > SchedModel->getIssueWidth())
307     return true;
308 
309   return false;
310 }
311 
312 void ConvergingVLIWScheduler::VLIWSchedBoundary::releaseNode(SUnit *SU,
313                                                      unsigned ReadyCycle) {
314   if (ReadyCycle < MinReadyCycle)
315     MinReadyCycle = ReadyCycle;
316 
317   // Check for interlocks first. For the purpose of other heuristics, an
318   // instruction that cannot issue appears as if it's not in the ReadyQueue.
319   if (ReadyCycle > CurrCycle || checkHazard(SU))
320 
321     Pending.push(SU);
322   else
323     Available.push(SU);
324 }
325 
326 /// Move the boundary of scheduled code by one cycle.
327 void ConvergingVLIWScheduler::VLIWSchedBoundary::bumpCycle() {
328   unsigned Width = SchedModel->getIssueWidth();
329   IssueCount = (IssueCount <= Width) ? 0 : IssueCount - Width;
330 
331   assert(MinReadyCycle < UINT_MAX && "MinReadyCycle uninitialized");
332   unsigned NextCycle = std::max(CurrCycle + 1, MinReadyCycle);
333 
334   if (!HazardRec->isEnabled()) {
335     // Bypass HazardRec virtual calls.
336     CurrCycle = NextCycle;
337   } else {
338     // Bypass getHazardType calls in case of long latency.
339     for (; CurrCycle != NextCycle; ++CurrCycle) {
340       if (isTop())
341         HazardRec->AdvanceCycle();
342       else
343         HazardRec->RecedeCycle();
344     }
345   }
346   CheckPending = true;
347 
348   DEBUG(dbgs() << "*** Next cycle " << Available.getName() << " cycle "
349                << CurrCycle << '\n');
350 }
351 
352 /// Move the boundary of scheduled code by one SUnit.
353 void ConvergingVLIWScheduler::VLIWSchedBoundary::bumpNode(SUnit *SU) {
354   bool startNewCycle = false;
355 
356   // Update the reservation table.
357   if (HazardRec->isEnabled()) {
358     if (!isTop() && SU->isCall) {
359       // Calls are scheduled with their preceding instructions. For bottom-up
360       // scheduling, clear the pipeline state before emitting.
361       HazardRec->Reset();
362     }
363     HazardRec->EmitInstruction(SU);
364   }
365 
366   // Update DFA model.
367   startNewCycle = ResourceModel->reserveResources(SU);
368 
369   // Check the instruction group dispatch limit.
370   // TODO: Check if this SU must end a dispatch group.
371   IssueCount += SchedModel->getNumMicroOps(SU->getInstr());
372   if (startNewCycle) {
373     DEBUG(dbgs() << "*** Max instrs at cycle " << CurrCycle << '\n');
374     bumpCycle();
375   }
376   else
377     DEBUG(dbgs() << "*** IssueCount " << IssueCount
378           << " at cycle " << CurrCycle << '\n');
379 }
380 
381 /// Release pending ready nodes in to the available queue. This makes them
382 /// visible to heuristics.
383 void ConvergingVLIWScheduler::VLIWSchedBoundary::releasePending() {
384   // If the available queue is empty, it is safe to reset MinReadyCycle.
385   if (Available.empty())
386     MinReadyCycle = UINT_MAX;
387 
388   // Check to see if any of the pending instructions are ready to issue.  If
389   // so, add them to the available queue.
390   for (unsigned i = 0, e = Pending.size(); i != e; ++i) {
391     SUnit *SU = *(Pending.begin()+i);
392     unsigned ReadyCycle = isTop() ? SU->TopReadyCycle : SU->BotReadyCycle;
393 
394     if (ReadyCycle < MinReadyCycle)
395       MinReadyCycle = ReadyCycle;
396 
397     if (ReadyCycle > CurrCycle)
398       continue;
399 
400     if (checkHazard(SU))
401       continue;
402 
403     Available.push(SU);
404     Pending.remove(Pending.begin()+i);
405     --i; --e;
406   }
407   CheckPending = false;
408 }
409 
410 /// Remove SU from the ready set for this boundary.
411 void ConvergingVLIWScheduler::VLIWSchedBoundary::removeReady(SUnit *SU) {
412   if (Available.isInQueue(SU))
413     Available.remove(Available.find(SU));
414   else {
415     assert(Pending.isInQueue(SU) && "bad ready count");
416     Pending.remove(Pending.find(SU));
417   }
418 }
419 
420 /// If this queue only has one ready candidate, return it. As a side effect,
421 /// advance the cycle until at least one node is ready. If multiple instructions
422 /// are ready, return NULL.
423 SUnit *ConvergingVLIWScheduler::VLIWSchedBoundary::pickOnlyChoice() {
424   if (CheckPending)
425     releasePending();
426 
427   for (unsigned i = 0; Available.empty(); ++i) {
428     assert(i <= (HazardRec->getMaxLookAhead() + MaxMinLatency) &&
429            "permanent hazard"); (void)i;
430     ResourceModel->reserveResources(nullptr);
431     bumpCycle();
432     releasePending();
433   }
434   if (Available.size() == 1)
435     return *Available.begin();
436   return nullptr;
437 }
438 
439 #ifndef NDEBUG
440 void ConvergingVLIWScheduler::traceCandidate(const char *Label,
441       const ReadyQueue &Q, SUnit *SU, int Cost, PressureChange P) {
442   dbgs() << Label << " " << Q.getName() << " ";
443   if (P.isValid())
444     dbgs() << DAG->TRI->getRegPressureSetName(P.getPSet()) << ":"
445            << P.getUnitInc() << " ";
446   else
447     dbgs() << "     ";
448   dbgs() << "cost(" << Cost << ")\t";
449   SU->dump(DAG);
450 }
451 
452 // Very detailed queue dump, to be used with higher verbosity levels.
453 void ConvergingVLIWScheduler::readyQueueVerboseDump(
454       const RegPressureTracker &RPTracker, SchedCandidate &Candidate,
455       ReadyQueue &Q) {
456   RegPressureTracker &TempTracker = const_cast<RegPressureTracker &>(RPTracker);
457 
458   dbgs() << ">>> " << Q.getName() << "\n";
459   for (ReadyQueue::iterator I = Q.begin(), E = Q.end(); I != E; ++I) {
460     RegPressureDelta RPDelta;
461     TempTracker.getMaxPressureDelta((*I)->getInstr(), RPDelta,
462                                     DAG->getRegionCriticalPSets(),
463                                     DAG->getRegPressure().MaxSetPressure);
464     std::stringstream dbgstr;
465     dbgstr << "SU(" << std::setw(3) << (*I)->NodeNum << ")";
466     dbgs() << dbgstr.str();
467     SchedulingCost(Q, *I, Candidate, RPDelta, true);
468     dbgs() << "\t";
469     (*I)->getInstr()->dump();
470   }
471   dbgs() << "\n";
472 }
473 #endif
474 
475 /// isSingleUnscheduledPred - If SU2 is the only unscheduled predecessor
476 /// of SU, return true (we may have duplicates)
477 static inline bool isSingleUnscheduledPred(SUnit *SU, SUnit *SU2) {
478   if (SU->NumPredsLeft == 0)
479     return false;
480 
481   for (auto &Pred : SU->Preds) {
482     // We found an available, but not scheduled, predecessor.
483     if (!Pred.getSUnit()->isScheduled && (Pred.getSUnit() != SU2))
484       return false;
485   }
486 
487   return true;
488 }
489 
490 /// isSingleUnscheduledSucc - If SU2 is the only unscheduled successor
491 /// of SU, return true (we may have duplicates)
492 static inline bool isSingleUnscheduledSucc(SUnit *SU, SUnit *SU2) {
493   if (SU->NumSuccsLeft == 0)
494     return false;
495 
496   for (auto &Succ : SU->Succs) {
497     // We found an available, but not scheduled, successor.
498     if (!Succ.getSUnit()->isScheduled && (Succ.getSUnit() != SU2))
499       return false;
500   }
501   return true;
502 }
503 
504 // Constants used to denote relative importance of
505 // heuristic components for cost computation.
506 static const unsigned PriorityOne = 200;
507 static const unsigned PriorityTwo = 50;
508 static const unsigned PriorityThree = 75;
509 static const unsigned ScaleTwo = 10;
510 static const unsigned FactorOne = 2;
511 
512 /// Single point to compute overall scheduling cost.
513 /// TODO: More heuristics will be used soon.
514 int ConvergingVLIWScheduler::SchedulingCost(ReadyQueue &Q, SUnit *SU,
515                                             SchedCandidate &Candidate,
516                                             RegPressureDelta &Delta,
517                                             bool verbose) {
518   // Initial trivial priority.
519   int ResCount = 1;
520 
521   // Do not waste time on a node that is already scheduled.
522   if (!SU || SU->isScheduled)
523     return ResCount;
524 
525   MachineInstr &Instr = *SU->getInstr();
526 
527   DEBUG(if (verbose) dbgs() << ((Q.getID() == TopQID) ? "(top|" : "(bot|"));
528   // Forced priority is high.
529   if (SU->isScheduleHigh) {
530     ResCount += PriorityOne;
531     DEBUG(dbgs() << "H|");
532   }
533 
534   // Critical path first.
535   if (Q.getID() == TopQID) {
536     ResCount += (SU->getHeight() * ScaleTwo);
537 
538     DEBUG(if (verbose) {
539       std::stringstream dbgstr;
540       dbgstr << "h" << std::setw(3) << SU->getHeight() << "|";
541       dbgs() << dbgstr.str();
542     });
543 
544     // If resources are available for it, multiply the
545     // chance of scheduling.
546     if (Top.ResourceModel->isResourceAvailable(SU)) {
547       ResCount <<= FactorOne;
548       ResCount += PriorityThree;
549       DEBUG(if (verbose) dbgs() << "A|");
550     } else
551       DEBUG(if (verbose) dbgs() << " |");
552   } else {
553     ResCount += (SU->getDepth() * ScaleTwo);
554 
555     DEBUG(if (verbose) {
556       std::stringstream dbgstr;
557       dbgstr << "d" << std::setw(3) << SU->getDepth() << "|";
558       dbgs() << dbgstr.str();
559     });
560 
561     // If resources are available for it, multiply the
562     // chance of scheduling.
563     if (Bot.ResourceModel->isResourceAvailable(SU)) {
564       ResCount <<= FactorOne;
565       ResCount += PriorityThree;
566       DEBUG(if (verbose) dbgs() << "A|");
567     } else
568       DEBUG(if (verbose) dbgs() << " |");
569   }
570 
571   unsigned NumNodesBlocking = 0;
572   if (Q.getID() == TopQID) {
573     // How many SUs does it block from scheduling?
574     // Look at all of the successors of this node.
575     // Count the number of nodes that
576     // this node is the sole unscheduled node for.
577     for (const SDep &SI : SU->Succs)
578       if (isSingleUnscheduledPred(SI.getSUnit(), SU))
579         ++NumNodesBlocking;
580   } else {
581     // How many unscheduled predecessors block this node?
582     for (const SDep &PI : SU->Preds)
583       if (isSingleUnscheduledSucc(PI.getSUnit(), SU))
584         ++NumNodesBlocking;
585   }
586   ResCount += (NumNodesBlocking * ScaleTwo);
587 
588   DEBUG(if (verbose) {
589     std::stringstream dbgstr;
590     dbgstr << "blk " << std::setw(2) << NumNodesBlocking << ")|";
591     dbgs() << dbgstr.str();
592   });
593 
594   // Factor in reg pressure as a heuristic.
595   if (!IgnoreBBRegPressure) {
596     // Decrease priority by the amount that register pressure exceeds the limit.
597     ResCount -= (Delta.Excess.getUnitInc()*PriorityOne);
598     // Decrease priority if register pressure exceeds the limit.
599     ResCount -= (Delta.CriticalMax.getUnitInc()*PriorityOne);
600     // Decrease priority slightly if register pressure would increase over the
601     // current maximum.
602     ResCount -= (Delta.CurrentMax.getUnitInc()*PriorityTwo);
603     DEBUG(if (verbose) {
604         dbgs() << "RP " << Delta.Excess.getUnitInc() << "/"
605                << Delta.CriticalMax.getUnitInc() <<"/"
606                << Delta.CurrentMax.getUnitInc() << ")|";
607     });
608   }
609 
610   // Give a little extra priority to a .cur instruction if there is a resource
611   // available for it.
612   auto &QST = DAG->MF.getSubtarget<HexagonSubtarget>();
613   auto &QII = *QST.getInstrInfo();
614   if (SU->isInstr() && QII.mayBeCurLoad(*SU->getInstr())) {
615     if (Q.getID() == TopQID && Top.ResourceModel->isResourceAvailable(SU)) {
616       ResCount += PriorityTwo;
617       DEBUG(if (verbose) dbgs() << "C|");
618     } else if (Q.getID() == BotQID &&
619                Bot.ResourceModel->isResourceAvailable(SU)) {
620       ResCount += PriorityTwo;
621       DEBUG(if (verbose) dbgs() << "C|");
622     }
623   }
624 
625   // Give preference to a zero latency instruction if the dependent
626   // instruction is in the current packet.
627   if (Q.getID() == TopQID) {
628     for (const SDep &PI : SU->Preds) {
629       if (!PI.getSUnit()->getInstr()->isPseudo() && PI.isAssignedRegDep() &&
630           PI.getLatency() == 0 &&
631           Top.ResourceModel->isInPacket(PI.getSUnit())) {
632         ResCount += PriorityThree;
633         DEBUG(if (verbose) dbgs() << "Z|");
634       }
635     }
636   } else {
637     for (const SDep &SI : SU->Succs) {
638       if (!SI.getSUnit()->getInstr()->isPseudo() && SI.isAssignedRegDep() &&
639           SI.getLatency() == 0 &&
640           Bot.ResourceModel->isInPacket(SI.getSUnit())) {
641         ResCount += PriorityThree;
642         DEBUG(if (verbose) dbgs() << "Z|");
643       }
644     }
645   }
646 
647   // Give less preference to an instruction that will cause a stall with
648   // an instruction in the previous packet.
649   if (QII.isHVXVec(Instr)) {
650     // Check for stalls in the previous packet.
651     if (Q.getID() == TopQID) {
652       for (auto J : Top.ResourceModel->OldPacket)
653         if (QII.producesStall(*J->getInstr(), Instr))
654           ResCount -= PriorityOne;
655     } else {
656       for (auto J : Bot.ResourceModel->OldPacket)
657         if (QII.producesStall(Instr, *J->getInstr()))
658           ResCount -= PriorityOne;
659     }
660   }
661 
662   // If the instruction has a non-zero latency dependence with an instruction in
663   // the current packet, then it should not be scheduled yet. The case occurs
664   // when the dependent instruction is scheduled in a new packet, so the
665   // scheduler updates the current cycle and pending instructions become
666   // available.
667   if (CheckEarlyAvail) {
668     if (Q.getID() == TopQID) {
669       for (const auto &PI : SU->Preds) {
670         if (PI.getLatency() > 0 &&
671             Top.ResourceModel->isInPacket(PI.getSUnit())) {
672           ResCount -= PriorityOne;
673           DEBUG(if (verbose) dbgs() << "D|");
674         }
675       }
676     } else {
677       for (const auto &SI : SU->Succs) {
678         if (SI.getLatency() > 0 &&
679             Bot.ResourceModel->isInPacket(SI.getSUnit())) {
680           ResCount -= PriorityOne;
681           DEBUG(if (verbose) dbgs() << "D|");
682         }
683       }
684     }
685   }
686 
687   DEBUG(if (verbose) {
688     std::stringstream dbgstr;
689     dbgstr << "Total " << std::setw(4) << ResCount << ")";
690     dbgs() << dbgstr.str();
691   });
692 
693   return ResCount;
694 }
695 
696 /// Pick the best candidate from the top queue.
697 ///
698 /// TODO: getMaxPressureDelta results can be mostly cached for each SUnit during
699 /// DAG building. To adjust for the current scheduling location we need to
700 /// maintain the number of vreg uses remaining to be top-scheduled.
701 ConvergingVLIWScheduler::CandResult ConvergingVLIWScheduler::
702 pickNodeFromQueue(ReadyQueue &Q, const RegPressureTracker &RPTracker,
703                   SchedCandidate &Candidate) {
704   DEBUG(if (SchedDebugVerboseLevel > 1)
705         readyQueueVerboseDump(RPTracker, Candidate, Q);
706         else Q.dump(););
707 
708   // getMaxPressureDelta temporarily modifies the tracker.
709   RegPressureTracker &TempTracker = const_cast<RegPressureTracker&>(RPTracker);
710 
711   // BestSU remains NULL if no top candidates beat the best existing candidate.
712   CandResult FoundCandidate = NoCand;
713   for (ReadyQueue::iterator I = Q.begin(), E = Q.end(); I != E; ++I) {
714     RegPressureDelta RPDelta;
715     TempTracker.getMaxPressureDelta((*I)->getInstr(), RPDelta,
716                                     DAG->getRegionCriticalPSets(),
717                                     DAG->getRegPressure().MaxSetPressure);
718 
719     int CurrentCost = SchedulingCost(Q, *I, Candidate, RPDelta, false);
720 
721     // Initialize the candidate if needed.
722     if (!Candidate.SU) {
723       DEBUG(traceCandidate("DCAND", Q, *I, CurrentCost));
724       Candidate.SU = *I;
725       Candidate.RPDelta = RPDelta;
726       Candidate.SCost = CurrentCost;
727       FoundCandidate = NodeOrder;
728       continue;
729     }
730 
731     // Best cost.
732     if (CurrentCost > Candidate.SCost) {
733       DEBUG(traceCandidate("CCAND", Q, *I, CurrentCost));
734       Candidate.SU = *I;
735       Candidate.RPDelta = RPDelta;
736       Candidate.SCost = CurrentCost;
737       FoundCandidate = BestCost;
738       continue;
739     }
740 
741     // Tie breaker using Timing Class.
742     if (!DisableTCTie) {
743       auto &QST = DAG->MF.getSubtarget<HexagonSubtarget>();
744       auto &QII = *QST.getInstrInfo();
745 
746       const MachineInstr *MI = (*I)->getInstr();
747       const MachineInstr *CandI = Candidate.SU->getInstr();
748       const InstrItineraryData *InstrItins = QST.getInstrItineraryData();
749 
750       unsigned InstrLatency = QII.getInstrTimingClassLatency(InstrItins, *MI);
751       unsigned CandLatency = QII.getInstrTimingClassLatency(InstrItins, *CandI);
752       DEBUG(dbgs() << "TC Tie Breaker Cand: "
753                    << CandLatency << " Instr:" << InstrLatency << "\n"
754                    << *MI << *CandI << "\n");
755       if (Q.getID() == TopQID && CurrentCost == Candidate.SCost) {
756         if (InstrLatency < CandLatency && TopUseShorterTie) {
757           Candidate.SU = *I;
758           Candidate.RPDelta = RPDelta;
759           Candidate.SCost = CurrentCost;
760           FoundCandidate = BestCost;
761           DEBUG(dbgs() << "Used top shorter tie breaker\n");
762           continue;
763         } else if (InstrLatency > CandLatency && !TopUseShorterTie) {
764           Candidate.SU = *I;
765           Candidate.RPDelta = RPDelta;
766           Candidate.SCost = CurrentCost;
767           FoundCandidate = BestCost;
768           DEBUG(dbgs() << "Used top longer tie breaker\n");
769           continue;
770         }
771       } else if (Q.getID() == BotQID && CurrentCost == Candidate.SCost) {
772         if (InstrLatency < CandLatency && BotUseShorterTie) {
773           Candidate.SU = *I;
774           Candidate.RPDelta = RPDelta;
775           Candidate.SCost = CurrentCost;
776           FoundCandidate = BestCost;
777           DEBUG(dbgs() << "Used Bot shorter tie breaker\n");
778           continue;
779         } else if (InstrLatency > CandLatency && !BotUseShorterTie) {
780           Candidate.SU = *I;
781           Candidate.RPDelta = RPDelta;
782           Candidate.SCost = CurrentCost;
783           FoundCandidate = BestCost;
784           DEBUG(dbgs() << "Used Bot longer tie breaker\n");
785           continue;
786         }
787       }
788     }
789 
790     if (CurrentCost == Candidate.SCost) {
791       if ((Q.getID() == TopQID &&
792            (*I)->Succs.size() > Candidate.SU->Succs.size()) ||
793           (Q.getID() == BotQID &&
794            (*I)->Preds.size() < Candidate.SU->Preds.size())) {
795         DEBUG(traceCandidate("SPCAND", Q, *I, CurrentCost));
796         Candidate.SU = *I;
797         Candidate.RPDelta = RPDelta;
798         Candidate.SCost = CurrentCost;
799         FoundCandidate = BestCost;
800         continue;
801       }
802     }
803 
804     // Fall through to original instruction order.
805     // Only consider node order if Candidate was chosen from this Q.
806     if (FoundCandidate == NoCand)
807       continue;
808   }
809   return FoundCandidate;
810 }
811 
812 /// Pick the best candidate node from either the top or bottom queue.
813 SUnit *ConvergingVLIWScheduler::pickNodeBidrectional(bool &IsTopNode) {
814   // Schedule as far as possible in the direction of no choice. This is most
815   // efficient, but also provides the best heuristics for CriticalPSets.
816   if (SUnit *SU = Bot.pickOnlyChoice()) {
817     DEBUG(dbgs() << "Picked only Bottom\n");
818     IsTopNode = false;
819     return SU;
820   }
821   if (SUnit *SU = Top.pickOnlyChoice()) {
822     DEBUG(dbgs() << "Picked only Top\n");
823     IsTopNode = true;
824     return SU;
825   }
826   SchedCandidate BotCand;
827   // Prefer bottom scheduling when heuristics are silent.
828   CandResult BotResult = pickNodeFromQueue(Bot.Available,
829                                            DAG->getBotRPTracker(), BotCand);
830   assert(BotResult != NoCand && "failed to find the first candidate");
831 
832   // If either Q has a single candidate that provides the least increase in
833   // Excess pressure, we can immediately schedule from that Q.
834   //
835   // RegionCriticalPSets summarizes the pressure within the scheduled region and
836   // affects picking from either Q. If scheduling in one direction must
837   // increase pressure for one of the excess PSets, then schedule in that
838   // direction first to provide more freedom in the other direction.
839   if (BotResult == SingleExcess || BotResult == SingleCritical) {
840     DEBUG(dbgs() << "Prefered Bottom Node\n");
841     IsTopNode = false;
842     return BotCand.SU;
843   }
844   // Check if the top Q has a better candidate.
845   SchedCandidate TopCand;
846   CandResult TopResult = pickNodeFromQueue(Top.Available,
847                                            DAG->getTopRPTracker(), TopCand);
848   assert(TopResult != NoCand && "failed to find the first candidate");
849 
850   if (TopResult == SingleExcess || TopResult == SingleCritical) {
851     DEBUG(dbgs() << "Prefered Top Node\n");
852     IsTopNode = true;
853     return TopCand.SU;
854   }
855   // If either Q has a single candidate that minimizes pressure above the
856   // original region's pressure pick it.
857   if (BotResult == SingleMax) {
858     DEBUG(dbgs() << "Prefered Bottom Node SingleMax\n");
859     IsTopNode = false;
860     return BotCand.SU;
861   }
862   if (TopResult == SingleMax) {
863     DEBUG(dbgs() << "Prefered Top Node SingleMax\n");
864     IsTopNode = true;
865     return TopCand.SU;
866   }
867   if (TopCand.SCost > BotCand.SCost) {
868     DEBUG(dbgs() << "Prefered Top Node Cost\n");
869     IsTopNode = true;
870     return TopCand.SU;
871   }
872   // Otherwise prefer the bottom candidate in node order.
873   DEBUG(dbgs() << "Prefered Bottom in Node order\n");
874   IsTopNode = false;
875   return BotCand.SU;
876 }
877 
878 /// Pick the best node to balance the schedule. Implements MachineSchedStrategy.
879 SUnit *ConvergingVLIWScheduler::pickNode(bool &IsTopNode) {
880   if (DAG->top() == DAG->bottom()) {
881     assert(Top.Available.empty() && Top.Pending.empty() &&
882            Bot.Available.empty() && Bot.Pending.empty() && "ReadyQ garbage");
883     return nullptr;
884   }
885   SUnit *SU;
886   if (llvm::ForceTopDown) {
887     SU = Top.pickOnlyChoice();
888     if (!SU) {
889       SchedCandidate TopCand;
890       CandResult TopResult =
891         pickNodeFromQueue(Top.Available, DAG->getTopRPTracker(), TopCand);
892       assert(TopResult != NoCand && "failed to find the first candidate");
893       (void)TopResult;
894       SU = TopCand.SU;
895     }
896     IsTopNode = true;
897   } else if (llvm::ForceBottomUp) {
898     SU = Bot.pickOnlyChoice();
899     if (!SU) {
900       SchedCandidate BotCand;
901       CandResult BotResult =
902         pickNodeFromQueue(Bot.Available, DAG->getBotRPTracker(), BotCand);
903       assert(BotResult != NoCand && "failed to find the first candidate");
904       (void)BotResult;
905       SU = BotCand.SU;
906     }
907     IsTopNode = false;
908   } else {
909     SU = pickNodeBidrectional(IsTopNode);
910   }
911   if (SU->isTopReady())
912     Top.removeReady(SU);
913   if (SU->isBottomReady())
914     Bot.removeReady(SU);
915 
916   DEBUG(dbgs() << "*** " << (IsTopNode ? "Top" : "Bottom")
917         << " Scheduling Instruction in cycle "
918         << (IsTopNode ? Top.CurrCycle : Bot.CurrCycle) << '\n';
919         SU->dump(DAG));
920   return SU;
921 }
922 
923 /// Update the scheduler's state after scheduling a node. This is the same node
924 /// that was just returned by pickNode(). However, VLIWMachineScheduler needs
925 /// to update it's state based on the current cycle before MachineSchedStrategy
926 /// does.
927 void ConvergingVLIWScheduler::schedNode(SUnit *SU, bool IsTopNode) {
928   if (IsTopNode) {
929     SU->TopReadyCycle = Top.CurrCycle;
930     Top.bumpNode(SU);
931   } else {
932     SU->BotReadyCycle = Bot.CurrCycle;
933     Bot.bumpNode(SU);
934   }
935 }
936