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