LLVM  3.7.0
MachineScheduler.h
Go to the documentation of this file.
1 //==- MachineScheduler.h - MachineInstr Scheduling Pass ----------*- C++ -*-==//
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 // This file provides an interface for customizing the standard MachineScheduler
11 // pass. Note that the entire pass may be replaced as follows:
12 //
13 // <Target>TargetMachine::createPassConfig(PassManagerBase &PM) {
14 // PM.substitutePass(&MachineSchedulerID, &CustomSchedulerPassID);
15 // ...}
16 //
17 // The MachineScheduler pass is only responsible for choosing the regions to be
18 // scheduled. Targets can override the DAG builder and scheduler without
19 // replacing the pass as follows:
20 //
21 // ScheduleDAGInstrs *<Target>PassConfig::
22 // createMachineScheduler(MachineSchedContext *C) {
23 // return new CustomMachineScheduler(C);
24 // }
25 //
26 // The default scheduler, ScheduleDAGMILive, builds the DAG and drives list
27 // scheduling while updating the instruction stream, register pressure, and live
28 // intervals. Most targets don't need to override the DAG builder and list
29 // schedulier, but subtargets that require custom scheduling heuristics may
30 // plugin an alternate MachineSchedStrategy. The strategy is responsible for
31 // selecting the highest priority node from the list:
32 //
33 // ScheduleDAGInstrs *<Target>PassConfig::
34 // createMachineScheduler(MachineSchedContext *C) {
35 // return new ScheduleDAGMI(C, CustomStrategy(C));
36 // }
37 //
38 // The DAG builder can also be customized in a sense by adding DAG mutations
39 // that will run after DAG building and before list scheduling. DAG mutations
40 // can adjust dependencies based on target-specific knowledge or add weak edges
41 // to aid heuristics:
42 //
43 // ScheduleDAGInstrs *<Target>PassConfig::
44 // createMachineScheduler(MachineSchedContext *C) {
45 // ScheduleDAGMI *DAG = new ScheduleDAGMI(C, CustomStrategy(C));
46 // DAG->addMutation(new CustomDependencies(DAG->TII, DAG->TRI));
47 // return DAG;
48 // }
49 //
50 // A target that supports alternative schedulers can use the
51 // MachineSchedRegistry to allow command line selection. This can be done by
52 // implementing the following boilerplate:
53 //
54 // static ScheduleDAGInstrs *createCustomMachineSched(MachineSchedContext *C) {
55 // return new CustomMachineScheduler(C);
56 // }
57 // static MachineSchedRegistry
58 // SchedCustomRegistry("custom", "Run my target's custom scheduler",
59 // createCustomMachineSched);
60 //
61 //
62 // Finally, subtargets that don't need to implement custom heuristics but would
63 // like to configure the GenericScheduler's policy for a given scheduler region,
64 // including scheduling direction and register pressure tracking policy, can do
65 // this:
66 //
67 // void <SubTarget>Subtarget::
68 // overrideSchedPolicy(MachineSchedPolicy &Policy,
69 // MachineInstr *begin,
70 // MachineInstr *end,
71 // unsigned NumRegionInstrs) const {
72 // Policy.<Flag> = true;
73 // }
74 //
75 //===----------------------------------------------------------------------===//
76 
77 #ifndef LLVM_CODEGEN_MACHINESCHEDULER_H
78 #define LLVM_CODEGEN_MACHINESCHEDULER_H
79 
83 #include <memory>
84 
85 namespace llvm {
86 
87 extern cl::opt<bool> ForceTopDown;
88 extern cl::opt<bool> ForceBottomUp;
89 
90 class AliasAnalysis;
91 class LiveIntervals;
92 class MachineDominatorTree;
93 class MachineLoopInfo;
94 class RegisterClassInfo;
95 class ScheduleDAGInstrs;
96 class SchedDFSResult;
97 class ScheduleHazardRecognizer;
98 
99 /// MachineSchedContext provides enough context from the MachineScheduler pass
100 /// for the target to instantiate a scheduler.
108 
110 
112  virtual ~MachineSchedContext();
113 };
114 
115 /// MachineSchedRegistry provides a selection of available machine instruction
116 /// schedulers.
118 public:
119  typedef ScheduleDAGInstrs *(*ScheduleDAGCtor)(MachineSchedContext *);
120 
121  // RegisterPassParser requires a (misnamed) FunctionPassCtor type.
123 
125 
126  MachineSchedRegistry(const char *N, const char *D, ScheduleDAGCtor C)
128  Registry.Add(this);
129  }
130  ~MachineSchedRegistry() { Registry.Remove(this); }
131 
132  // Accessors.
133  //
136  }
138  return (MachineSchedRegistry *)Registry.getList();
139  }
141  Registry.setListener(L);
142  }
143 };
144 
145 class ScheduleDAGMI;
146 
147 /// Define a generic scheduling policy for targets that don't provide their own
148 /// MachineSchedStrategy. This can be overriden for each scheduling region
149 /// before building the DAG.
151  // Allow the scheduler to disable register pressure tracking.
153 
154  // Allow the scheduler to force top-down or bottom-up scheduling. If neither
155  // is true, the scheduler runs in both directions and converges.
158 
160  OnlyBottomUp(false) {}
161 };
162 
163 /// MachineSchedStrategy - Interface to the scheduling algorithm used by
164 /// ScheduleDAGMI.
165 ///
166 /// Initialization sequence:
167 /// initPolicy -> shouldTrackPressure -> initialize(DAG) -> registerRoots
169  virtual void anchor();
170 public:
172 
173  /// Optionally override the per-region scheduling policy.
176  unsigned NumRegionInstrs) {}
177 
178  /// Check if pressure tracking is needed before building the DAG and
179  /// initializing this strategy. Called after initPolicy.
180  virtual bool shouldTrackPressure() const { return true; }
181 
182  /// Initialize the strategy after building the DAG for a new region.
183  virtual void initialize(ScheduleDAGMI *DAG) = 0;
184 
185  /// Notify this strategy that all roots have been released (including those
186  /// that depend on EntrySU or ExitSU).
187  virtual void registerRoots() {}
188 
189  /// Pick the next node to schedule, or return NULL. Set IsTopNode to true to
190  /// schedule the node at the top of the unscheduled region. Otherwise it will
191  /// be scheduled at the bottom.
192  virtual SUnit *pickNode(bool &IsTopNode) = 0;
193 
194  /// \brief Scheduler callback to notify that a new subtree is scheduled.
195  virtual void scheduleTree(unsigned SubtreeID) {}
196 
197  /// Notify MachineSchedStrategy that ScheduleDAGMI has scheduled an
198  /// instruction and updated scheduled/remaining flags in the DAG nodes.
199  virtual void schedNode(SUnit *SU, bool IsTopNode) = 0;
200 
201  /// When all predecessor dependencies have been resolved, free this node for
202  /// top-down scheduling.
203  virtual void releaseTopNode(SUnit *SU) = 0;
204  /// When all successor dependencies have been resolved, free this node for
205  /// bottom-up scheduling.
206  virtual void releaseBottomNode(SUnit *SU) = 0;
207 };
208 
209 /// Mutate the DAG as a postpass after normal DAG building.
211  virtual void anchor();
212 public:
213  virtual ~ScheduleDAGMutation() {}
214 
215  virtual void apply(ScheduleDAGMI *DAG) = 0;
216 };
217 
218 /// ScheduleDAGMI is an implementation of ScheduleDAGInstrs that simply
219 /// schedules machine instructions according to the given MachineSchedStrategy
220 /// without much extra book-keeping. This is the common functionality between
221 /// PreRA and PostRA MachineScheduler.
223 protected:
225  std::unique_ptr<MachineSchedStrategy> SchedImpl;
226 
227  /// Topo - A topological ordering for SUnits which permits fast IsReachable
228  /// and similar queries.
230 
231  /// Ordered list of DAG postprocessing steps.
232  std::vector<std::unique_ptr<ScheduleDAGMutation>> Mutations;
233 
234  /// The top of the unscheduled zone.
236 
237  /// The bottom of the unscheduled zone.
239 
240  /// Record the next node in a scheduled cluster.
243 
244 #ifndef NDEBUG
245  /// The number of instructions scheduled so far. Used to cut off the
246  /// scheduler at the point determined by misched-cutoff.
248 #endif
249 public:
250  ScheduleDAGMI(MachineSchedContext *C, std::unique_ptr<MachineSchedStrategy> S,
251  bool IsPostRA)
252  : ScheduleDAGInstrs(*C->MF, C->MLI, IsPostRA,
253  /*RemoveKillFlags=*/IsPostRA, C->LIS),
254  AA(C->AA), SchedImpl(std::move(S)), Topo(SUnits, &ExitSU), CurrentTop(),
255  CurrentBottom(), NextClusterPred(nullptr), NextClusterSucc(nullptr) {
256 #ifndef NDEBUG
257  NumInstrsScheduled = 0;
258 #endif
259  }
260 
261  // Provide a vtable anchor
262  ~ScheduleDAGMI() override;
263 
264  /// Return true if this DAG supports VReg liveness and RegPressure.
265  virtual bool hasVRegLiveness() const { return false; }
266 
267  /// Add a postprocessing step to the DAG builder.
268  /// Mutations are applied in the order that they are added after normal DAG
269  /// building and before MachineSchedStrategy initialization.
270  ///
271  /// ScheduleDAGMI takes ownership of the Mutation object.
272  void addMutation(std::unique_ptr<ScheduleDAGMutation> Mutation) {
273  Mutations.push_back(std::move(Mutation));
274  }
275 
276  /// \brief True if an edge can be added from PredSU to SuccSU without creating
277  /// a cycle.
278  bool canAddEdge(SUnit *SuccSU, SUnit *PredSU);
279 
280  /// \brief Add a DAG edge to the given SU with the given predecessor
281  /// dependence data.
282  ///
283  /// \returns true if the edge may be added without creating a cycle OR if an
284  /// equivalent edge already existed (false indicates failure).
285  bool addEdge(SUnit *SuccSU, const SDep &PredDep);
286 
289 
290  /// Implement the ScheduleDAGInstrs interface for handling the next scheduling
291  /// region. This covers all instructions in a block, while schedule() may only
292  /// cover a subset.
296  unsigned regioninstrs) override;
297 
298  /// Implement ScheduleDAGInstrs interface for scheduling a sequence of
299  /// reorderable instructions.
300  void schedule() override;
301 
302  /// Change the position of an instruction within the basic block and update
303  /// live ranges and region boundary iterators.
305 
306  const SUnit *getNextClusterPred() const { return NextClusterPred; }
307 
308  const SUnit *getNextClusterSucc() const { return NextClusterSucc; }
309 
310  void viewGraph(const Twine &Name, const Twine &Title) override;
311  void viewGraph() override;
312 
313 protected:
314  // Top-Level entry points for the schedule() driver...
315 
316  /// Apply each ScheduleDAGMutation step in order. This allows different
317  /// instances of ScheduleDAGMI to perform custom DAG postprocessing.
318  void postprocessDAG();
319 
320  /// Release ExitSU predecessors and setup scheduler queues.
321  void initQueues(ArrayRef<SUnit*> TopRoots, ArrayRef<SUnit*> BotRoots);
322 
323  /// Update scheduler DAG and queues after scheduling an instruction.
324  void updateQueues(SUnit *SU, bool IsTopNode);
325 
326  /// Reinsert debug_values recorded in ScheduleDAGInstrs::DbgValues.
327  void placeDebugValues();
328 
329  /// \brief dump the scheduled Sequence.
330  void dumpSchedule() const;
331 
332  // Lesser helpers...
333  bool checkSchedLimit();
334 
336  SmallVectorImpl<SUnit*> &BotRoots);
337 
338  void releaseSucc(SUnit *SU, SDep *SuccEdge);
339  void releaseSuccessors(SUnit *SU);
340  void releasePred(SUnit *SU, SDep *PredEdge);
341  void releasePredecessors(SUnit *SU);
342 };
343 
344 /// ScheduleDAGMILive is an implementation of ScheduleDAGInstrs that schedules
345 /// machine instructions while updating LiveIntervals and tracking regpressure.
347 protected:
349 
350  /// Information about DAG subtrees. If DFSResult is NULL, then SchedulerTrees
351  /// will be empty.
354 
356 
357  // Map each SU to its summary of pressure changes. This array is updated for
358  // liveness during bottom-up scheduling. Top-down scheduling may proceed but
359  // has no affect on the pressure diffs.
361 
362  /// Register pressure in this region computed by initRegPressure.
366 
367  /// List of pressure sets that exceed the target's pressure limit before
368  /// scheduling, listed in increasing set ID order. Each pressure set is paired
369  /// with its max pressure in the currently scheduled regions.
370  std::vector<PressureChange> RegionCriticalPSets;
371 
372  /// The top of the unscheduled zone.
375 
376  /// The bottom of the unscheduled zone.
379 
380 public:
382  std::unique_ptr<MachineSchedStrategy> S)
383  : ScheduleDAGMI(C, std::move(S), /*IsPostRA=*/false),
384  RegClassInfo(C->RegClassInfo), DFSResult(nullptr),
387 
388  ~ScheduleDAGMILive() override;
389 
390  /// Return true if this DAG supports VReg liveness and RegPressure.
391  bool hasVRegLiveness() const override { return true; }
392 
393  /// \brief Return true if register pressure tracking is enabled.
394  bool isTrackingPressure() const { return ShouldTrackPressure; }
395 
396  /// Get current register pressure for the top scheduled instructions.
397  const IntervalPressure &getTopPressure() const { return TopPressure; }
399 
400  /// Get current register pressure for the bottom scheduled instructions.
401  const IntervalPressure &getBotPressure() const { return BotPressure; }
403 
404  /// Get register pressure for the entire scheduling region before scheduling.
405  const IntervalPressure &getRegPressure() const { return RegPressure; }
406 
407  const std::vector<PressureChange> &getRegionCriticalPSets() const {
408  return RegionCriticalPSets;
409  }
410 
412  return SUPressureDiffs[SU->NodeNum];
413  }
414 
415  /// Compute a DFSResult after DAG building is complete, and before any
416  /// queue comparisons.
417  void computeDFSResult();
418 
419  /// Return a non-null DFS result if the scheduling strategy initialized it.
420  const SchedDFSResult *getDFSResult() const { return DFSResult; }
421 
423 
424  /// Implement the ScheduleDAGInstrs interface for handling the next scheduling
425  /// region. This covers all instructions in a block, while schedule() may only
426  /// cover a subset.
430  unsigned regioninstrs) override;
431 
432  /// Implement ScheduleDAGInstrs interface for scheduling a sequence of
433  /// reorderable instructions.
434  void schedule() override;
435 
436  /// Compute the cyclic critical path through the DAG.
437  unsigned computeCyclicCriticalPath();
438 
439 protected:
440  // Top-Level entry points for the schedule() driver...
441 
442  /// Call ScheduleDAGInstrs::buildSchedGraph with register pressure tracking
443  /// enabled. This sets up three trackers. RPTracker will cover the entire DAG
444  /// region, TopTracker and BottomTracker will be initialized to the top and
445  /// bottom of the DAG region without covereing any unscheduled instruction.
447 
448  /// Move an instruction and update register pressure.
449  void scheduleMI(SUnit *SU, bool IsTopNode);
450 
451  // Lesser helpers...
452 
453  void initRegPressure();
454 
456 
457  void updateScheduledPressure(const SUnit *SU,
458  const std::vector<unsigned> &NewMaxPressure);
459 };
460 
461 //===----------------------------------------------------------------------===//
462 ///
463 /// Helpers for implementing custom MachineSchedStrategy classes. These take
464 /// care of the book-keeping associated with list scheduling heuristics.
465 ///
466 //===----------------------------------------------------------------------===//
467 
468 /// ReadyQueue encapsulates vector of "ready" SUnits with basic convenience
469 /// methods for pushing and removing nodes. ReadyQueue's are uniquely identified
470 /// by an ID. SUnit::NodeQueueId is a mask of the ReadyQueues the SUnit is in.
471 ///
472 /// This is a convenience class that may be used by implementations of
473 /// MachineSchedStrategy.
474 class ReadyQueue {
475  unsigned ID;
476  std::string Name;
477  std::vector<SUnit*> Queue;
478 
479 public:
480  ReadyQueue(unsigned id, const Twine &name): ID(id), Name(name.str()) {}
481 
482  unsigned getID() const { return ID; }
483 
484  StringRef getName() const { return Name; }
485 
486  // SU is in this queue if it's NodeQueueID is a superset of this ID.
487  bool isInQueue(SUnit *SU) const { return (SU->NodeQueueId & ID); }
488 
489  bool empty() const { return Queue.empty(); }
490 
491  void clear() { Queue.clear(); }
492 
493  unsigned size() const { return Queue.size(); }
494 
495  typedef std::vector<SUnit*>::iterator iterator;
496 
497  iterator begin() { return Queue.begin(); }
498 
499  iterator end() { return Queue.end(); }
500 
501  ArrayRef<SUnit*> elements() { return Queue; }
502 
504  return std::find(Queue.begin(), Queue.end(), SU);
505  }
506 
507  void push(SUnit *SU) {
508  Queue.push_back(SU);
509  SU->NodeQueueId |= ID;
510  }
511 
512  iterator remove(iterator I) {
513  (*I)->NodeQueueId &= ~ID;
514  *I = Queue.back();
515  unsigned idx = I - Queue.begin();
516  Queue.pop_back();
517  return Queue.begin() + idx;
518  }
519 
520  void dump();
521 };
522 
523 /// Summarize the unscheduled region.
525  // Critical path through the DAG in expected latency.
526  unsigned CriticalPath;
527  unsigned CyclicCritPath;
528 
529  // Scaled count of micro-ops left to schedule.
530  unsigned RemIssueCount;
531 
533 
534  // Unscheduled resources
536 
537  void reset() {
538  CriticalPath = 0;
539  CyclicCritPath = 0;
540  RemIssueCount = 0;
541  IsAcyclicLatencyLimited = false;
543  }
544 
546 
547  void init(ScheduleDAGMI *DAG, const TargetSchedModel *SchedModel);
548 };
549 
550 /// Each Scheduling boundary is associated with ready queues. It tracks the
551 /// current cycle in the direction of movement, and maintains the state
552 /// of "hazards" and other interlocks at the current cycle.
554 public:
555  /// SUnit::NodeQueueId: 0 (none), 1 (top), 2 (bot), 3 (both)
556  enum {
557  TopQID = 1,
558  BotQID = 2,
560  };
561 
565 
568 
570 
571 private:
572  /// True if the pending Q should be checked/updated before scheduling another
573  /// instruction.
574  bool CheckPending;
575 
576  // For heuristics, keep a list of the nodes that immediately depend on the
577  // most recently scheduled node.
579 
580  /// Number of cycles it takes to issue the instructions scheduled in this
581  /// zone. It is defined as: scheduled-micro-ops / issue-width + stalls.
582  /// See getStalls().
583  unsigned CurrCycle;
584 
585  /// Micro-ops issued in the current cycle
586  unsigned CurrMOps;
587 
588  /// MinReadyCycle - Cycle of the soonest available instruction.
589  unsigned MinReadyCycle;
590 
591  // The expected latency of the critical path in this scheduled zone.
592  unsigned ExpectedLatency;
593 
594  // The latency of dependence chains leading into this zone.
595  // For each node scheduled bottom-up: DLat = max DLat, N.Depth.
596  // For each cycle scheduled: DLat -= 1.
597  unsigned DependentLatency;
598 
599  /// Count the scheduled (issued) micro-ops that can be retired by
600  /// time=CurrCycle assuming the first scheduled instr is retired at time=0.
601  unsigned RetiredMOps;
602 
603  // Count scheduled resources that have been executed. Resources are
604  // considered executed if they become ready in the time that it takes to
605  // saturate any resource including the one in question. Counts are scaled
606  // for direct comparison with other resources. Counts can be compared with
607  // MOps * getMicroOpFactor and Latency * getLatencyFactor.
608  SmallVector<unsigned, 16> ExecutedResCounts;
609 
610  /// Cache the max count for a single resource.
611  unsigned MaxExecutedResCount;
612 
613  // Cache the critical resources ID in this scheduled zone.
614  unsigned ZoneCritResIdx;
615 
616  // Is the scheduled region resource limited vs. latency limited.
617  bool IsResourceLimited;
618 
619  // Record the highest cycle at which each resource has been reserved by a
620  // scheduled instruction.
621  SmallVector<unsigned, 16> ReservedCycles;
622 
623 #ifndef NDEBUG
624  // Remember the greatest possible stall as an upper bound on the number of
625  // times we should retry the pending queue because of a hazard.
626  unsigned MaxObservedStall;
627 #endif
628 
629 public:
630  /// Pending queues extend the ready queues with the same ID and the
631  /// PendingFlag set.
632  SchedBoundary(unsigned ID, const Twine &Name):
633  DAG(nullptr), SchedModel(nullptr), Rem(nullptr), Available(ID, Name+".A"),
634  Pending(ID << LogMaxQID, Name+".P"),
635  HazardRec(nullptr) {
636  reset();
637  }
638 
639  ~SchedBoundary();
640 
641  void reset();
642 
643  void init(ScheduleDAGMI *dag, const TargetSchedModel *smodel,
644  SchedRemainder *rem);
645 
646  bool isTop() const {
647  return Available.getID() == TopQID;
648  }
649 
650  /// Number of cycles to issue the instructions scheduled in this zone.
651  unsigned getCurrCycle() const { return CurrCycle; }
652 
653  /// Micro-ops issued in the current cycle
654  unsigned getCurrMOps() const { return CurrMOps; }
655 
656  /// Return true if the given SU is used by the most recently scheduled
657  /// instruction.
658  bool isNextSU(const SUnit *SU) const { return NextSUs.count(SU); }
659 
660  // The latency of dependence chains leading into this zone.
661  unsigned getDependentLatency() const { return DependentLatency; }
662 
663  /// Get the number of latency cycles "covered" by the scheduled
664  /// instructions. This is the larger of the critical path within the zone
665  /// and the number of cycles required to issue the instructions.
666  unsigned getScheduledLatency() const {
667  return std::max(ExpectedLatency, CurrCycle);
668  }
669 
670  unsigned getUnscheduledLatency(SUnit *SU) const {
671  return isTop() ? SU->getHeight() : SU->getDepth();
672  }
673 
674  unsigned getResourceCount(unsigned ResIdx) const {
675  return ExecutedResCounts[ResIdx];
676  }
677 
678  /// Get the scaled count of scheduled micro-ops and resources, including
679  /// executed resources.
680  unsigned getCriticalCount() const {
681  if (!ZoneCritResIdx)
682  return RetiredMOps * SchedModel->getMicroOpFactor();
683  return getResourceCount(ZoneCritResIdx);
684  }
685 
686  /// Get a scaled count for the minimum execution time of the scheduled
687  /// micro-ops that are ready to execute by getExecutedCount. Notice the
688  /// feedback loop.
689  unsigned getExecutedCount() const {
690  return std::max(CurrCycle * SchedModel->getLatencyFactor(),
691  MaxExecutedResCount);
692  }
693 
694  unsigned getZoneCritResIdx() const { return ZoneCritResIdx; }
695 
696  // Is the scheduled region resource limited vs. latency limited.
697  bool isResourceLimited() const { return IsResourceLimited; }
698 
699  /// Get the difference between the given SUnit's ready time and the current
700  /// cycle.
701  unsigned getLatencyStallCycles(SUnit *SU);
702 
703  unsigned getNextResourceCycle(unsigned PIdx, unsigned Cycles);
704 
705  bool checkHazard(SUnit *SU);
706 
707  unsigned findMaxLatency(ArrayRef<SUnit*> ReadySUs);
708 
709  unsigned getOtherResourceCount(unsigned &OtherCritIdx);
710 
711  void releaseNode(SUnit *SU, unsigned ReadyCycle);
712 
713  void releaseTopNode(SUnit *SU);
714 
715  void releaseBottomNode(SUnit *SU);
716 
717  void bumpCycle(unsigned NextCycle);
718 
719  void incExecutedResources(unsigned PIdx, unsigned Count);
720 
721  unsigned countResource(unsigned PIdx, unsigned Cycles, unsigned ReadyCycle);
722 
723  void bumpNode(SUnit *SU);
724 
725  void releasePending();
726 
727  void removeReady(SUnit *SU);
728 
729  /// Call this before applying any other heuristics to the Available queue.
730  /// Updates the Available/Pending Q's if necessary and returns the single
731  /// available instruction, or NULL if there are multiple candidates.
733 
734 #ifndef NDEBUG
735  void dumpScheduledState();
736 #endif
737 };
738 
739 /// Base class for GenericScheduler. This class maintains information about
740 /// scheduling candidates based on TargetSchedModel making it easy to implement
741 /// heuristics for either preRA or postRA scheduling.
743 public:
744  /// Represent the type of SchedCandidate found within a single queue.
745  /// pickNodeBidirectional depends on these listed by decreasing priority.
746  enum CandReason {
750 
751 #ifndef NDEBUG
752  static const char *getReasonStr(GenericSchedulerBase::CandReason Reason);
753 #endif
754 
755  /// Policy for scheduling the next instruction in the candidate's zone.
756  struct CandPolicy {
758  unsigned ReduceResIdx;
759  unsigned DemandResIdx;
760 
762  };
763 
764  /// Status of an instruction's critical resource consumption.
766  // Count critical resources in the scheduled region required by SU.
767  unsigned CritResources;
768 
769  // Count critical resources from another region consumed by SU.
771 
773 
774  bool operator==(const SchedResourceDelta &RHS) const {
775  return CritResources == RHS.CritResources
777  }
778  bool operator!=(const SchedResourceDelta &RHS) const {
779  return !operator==(RHS);
780  }
781  };
782 
783  /// Store the state used by GenericScheduler heuristics, required for the
784  /// lifetime of one invocation of pickNode().
785  struct SchedCandidate {
787 
788  // The best SUnit candidate.
790 
791  // The reason for this candidate.
793 
794  // Set of reasons that apply to multiple candidates.
795  uint32_t RepeatReasonSet;
796 
797  // Register pressure values for the best candidate.
799 
800  // Critical resource consumption of the best candidate.
802 
803  SchedCandidate(const CandPolicy &policy)
804  : Policy(policy), SU(nullptr), Reason(NoCand), RepeatReasonSet(0) {}
805 
806  bool isValid() const { return SU; }
807 
808  // Copy the status of another candidate without changing policy.
809  void setBest(SchedCandidate &Best) {
810  assert(Best.Reason != NoCand && "uninitialized Sched candidate");
811  SU = Best.SU;
812  Reason = Best.Reason;
813  RPDelta = Best.RPDelta;
814  ResDelta = Best.ResDelta;
815  }
816 
817  bool isRepeat(CandReason R) { return RepeatReasonSet & (1 << R); }
818  void setRepeat(CandReason R) { RepeatReasonSet |= (1 << R); }
819 
820  void initResourceDelta(const ScheduleDAGMI *DAG,
822  };
823 
824 protected:
828 
830 protected:
832  Context(C), SchedModel(nullptr), TRI(nullptr) {}
833 
834  void setPolicy(CandPolicy &Policy, bool IsPostRA, SchedBoundary &CurrZone,
835  SchedBoundary *OtherZone);
836 
837 #ifndef NDEBUG
838  void traceCandidate(const SchedCandidate &Cand);
839 #endif
840 };
841 
842 /// GenericScheduler shrinks the unscheduled zone using heuristics to balance
843 /// the schedule.
845  ScheduleDAGMILive *DAG;
846 
847  // State of the top and bottom scheduled instruction boundaries.
848  SchedBoundary Top;
849  SchedBoundary Bot;
850 
851  MachineSchedPolicy RegionPolicy;
852 public:
854  GenericSchedulerBase(C), DAG(nullptr), Top(SchedBoundary::TopQID, "TopQ"),
855  Bot(SchedBoundary::BotQID, "BotQ") {}
856 
859  unsigned NumRegionInstrs) override;
860 
861  bool shouldTrackPressure() const override {
862  return RegionPolicy.ShouldTrackPressure;
863  }
864 
865  void initialize(ScheduleDAGMI *dag) override;
866 
867  SUnit *pickNode(bool &IsTopNode) override;
868 
869  void schedNode(SUnit *SU, bool IsTopNode) override;
870 
871  void releaseTopNode(SUnit *SU) override {
872  Top.releaseTopNode(SU);
873  }
874 
875  void releaseBottomNode(SUnit *SU) override {
876  Bot.releaseBottomNode(SU);
877  }
878 
879  void registerRoots() override;
880 
881 protected:
882  void checkAcyclicLatency();
883 
884  void tryCandidate(SchedCandidate &Cand,
885  SchedCandidate &TryCand,
886  SchedBoundary &Zone,
887  const RegPressureTracker &RPTracker,
888  RegPressureTracker &TempTracker);
889 
890  SUnit *pickNodeBidirectional(bool &IsTopNode);
891 
892  void pickNodeFromQueue(SchedBoundary &Zone,
893  const RegPressureTracker &RPTracker,
894  SchedCandidate &Candidate);
895 
896  void reschedulePhysRegCopies(SUnit *SU, bool isTop);
897 };
898 
899 /// PostGenericScheduler - Interface to the scheduling algorithm used by
900 /// ScheduleDAGMI.
901 ///
902 /// Callbacks from ScheduleDAGMI:
903 /// initPolicy -> initialize(DAG) -> registerRoots -> pickNode ...
905  ScheduleDAGMI *DAG;
906  SchedBoundary Top;
907  SmallVector<SUnit*, 8> BotRoots;
908 public:
910  GenericSchedulerBase(C), Top(SchedBoundary::TopQID, "TopQ") {}
911 
912  ~PostGenericScheduler() override {}
913 
916  unsigned NumRegionInstrs) override {
917  /* no configurable policy */
918  };
919 
920  /// PostRA scheduling does not track pressure.
921  bool shouldTrackPressure() const override { return false; }
922 
923  void initialize(ScheduleDAGMI *Dag) override;
924 
925  void registerRoots() override;
926 
927  SUnit *pickNode(bool &IsTopNode) override;
928 
929  void scheduleTree(unsigned SubtreeID) override {
930  llvm_unreachable("PostRA scheduler does not support subtree analysis.");
931  }
932 
933  void schedNode(SUnit *SU, bool IsTopNode) override;
934 
935  void releaseTopNode(SUnit *SU) override {
936  Top.releaseTopNode(SU);
937  }
938 
939  // Only called for roots.
940  void releaseBottomNode(SUnit *SU) override {
941  BotRoots.push_back(SU);
942  }
943 
944 protected:
945  void tryCandidate(SchedCandidate &Cand, SchedCandidate &TryCand);
946 
947  void pickNodeFromQueue(SchedCandidate &Cand);
948 };
949 
950 } // namespace llvm
951 
952 #endif
void computeDFSResult()
Compute a DFSResult after DAG building is complete, and before any queue comparisons.
void releaseSucc(SUnit *SU, SDep *SuccEdge)
ReleaseSucc - Decrement the NumPredsLeft count of a successor.
void initPolicy(MachineBasicBlock::iterator Begin, MachineBasicBlock::iterator End, unsigned NumRegionInstrs) override
Optionally override the per-region scheduling policy.
void schedNode(SUnit *SU, bool IsTopNode) override
Called after ScheduleDAGMI has scheduled an instruction and updated scheduled/remaining flags in the ...
virtual void initialize(ScheduleDAGMI *DAG)=0
Initialize the strategy after building the DAG for a new region.
void pickNodeFromQueue(SchedBoundary &Zone, const RegPressureTracker &RPTracker, SchedCandidate &Candidate)
Pick the best candidate from the queue.
Base class for GenericScheduler.
Each Scheduling boundary is associated with ready queues.
PostGenericScheduler - Interface to the scheduling algorithm used by ScheduleDAGMI.
GenericSchedulerBase(const MachineSchedContext *C)
void releaseTopNode(SUnit *SU)
const MachineSchedContext * Context
SUnit * pickNodeBidirectional(bool &IsTopNode)
Pick the best candidate node from either the top or bottom queue.
virtual void releaseTopNode(SUnit *SU)=0
When all predecessor dependencies have been resolved, free this node for top-down scheduling...
void schedule() override
Implement ScheduleDAGInstrs interface for scheduling a sequence of reorderable instructions.
void init(ScheduleDAGMI *DAG, const TargetSchedModel *SchedModel)
bool isInQueue(SUnit *SU) const
unsigned getCurrCycle() const
Number of cycles to issue the instructions scheduled in this zone.
ScheduleDAGTopologicalSort Topo
Topo - A topological ordering for SUnits which permits fast IsReachable and similar queries...
MachineBasicBlock::iterator CurrentTop
The top of the unscheduled zone.
const MachineLoopInfo * MLI
bool isTrackingPressure() const
Return true if register pressure tracking is enabled.
void releaseTopNode(SUnit *SU) override
When all predecessor dependencies have been resolved, free this node for top-down scheduling...
unsigned computeCyclicCriticalPath()
Compute the cyclic critical path through the DAG.
A global registry used in conjunction with static constructors to make pluggable components (like tar...
Definition: Registry.h:61
void traceCandidate(const SchedCandidate &Cand)
bool ShouldTrackPressure
Register pressure in this region computed by initRegPressure.
void *(* MachinePassCtor)()
MachineBasicBlock::iterator begin() const
begin - Return an iterator to the top of the current scheduling region.
MachineSchedRegistry(const char *N, const char *D, ScheduleDAGCtor C)
Mutate the DAG as a postpass after normal DAG building.
Summarize the unscheduled region.
unsigned getID() const
static void setListener(MachinePassRegistryListener *L)
ScheduleDAGMI * DAG
virtual bool shouldTrackPressure() const
Check if pressure tracking is needed before building the DAG and initializing this strategy...
MachineSchedRegistry provides a selection of available machine instruction schedulers.
RegisterClassInfo * RegClassInfo
MachineBasicBlock::iterator top() const
const IntervalPressure & getTopPressure() const
Get current register pressure for the top scheduled instructions.
const RegPressureTracker & getTopRPTracker() const
ScheduleDAGMI is an implementation of ScheduleDAGInstrs that simply schedules machine instructions ac...
std::unique_ptr< MachineSchedStrategy > SchedImpl
const RegPressureTracker & getBotRPTracker() const
MachineSchedRegistry * getNext() const
void updateQueues(SUnit *SU, bool IsTopNode)
Update scheduler DAG and queues after scheduling an instruction.
virtual void schedNode(SUnit *SU, bool IsTopNode)=0
Notify MachineSchedStrategy that ScheduleDAGMI has scheduled an instruction and updated scheduled/rem...
ScheduleDAGMILive is an implementation of ScheduleDAGInstrs that schedules machine instructions while...
unsigned getDependentLatency() const
MachineFunction & MF
Definition: ScheduleDAG.h:563
unsigned NumInstrsScheduled
The number of instructions scheduled so far.
unsigned getHeight() const
getHeight - Return the height of this node, which is the length of the maximum path down to any node ...
Definition: ScheduleDAG.h:431
ArrayRef< SUnit * > elements()
void releaseBottomNode(SUnit *SU)
BitVector & getScheduledTrees()
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:79
Provide an instruction scheduling machine model to CodeGen passes.
const TargetPassConfig * PassConfig
const IntervalPressure & getBotPressure() const
Get current register pressure for the bottom scheduled instructions.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:98
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APInt.h:33
void scheduleTree(unsigned SubtreeID) override
Scheduler callback to notify that a new subtree is scheduled.
PressureDiff & getPressureDiff(const SUnit *SU)
std::vector< std::unique_ptr< ScheduleDAGMutation > > Mutations
Ordered list of DAG postprocessing steps.
#define false
Definition: ConvertUTF.c:65
Target-Independent Code Generator Pass Configuration Options.
ScheduleDAGCtor FunctionPassCtor
void initPolicy(MachineBasicBlock::iterator Begin, MachineBasicBlock::iterator End, unsigned NumRegionInstrs) override
Initialize the per-region scheduling policy.
static MachineSchedRegistry * getList()
Compute the values of each DAG node for various metrics during DFS.
Definition: ScheduleDFS.h:66
void enterRegion(MachineBasicBlock *bb, MachineBasicBlock::iterator begin, MachineBasicBlock::iterator end, unsigned regioninstrs) override
Implement the ScheduleDAGInstrs interface for handling the next scheduling region.
PowerPC VSX FMA Mutation
MachineBasicBlock::iterator LiveRegionEnd
unsigned getCriticalCount() const
Get the scaled count of scheduled micro-ops and resources, including executed resources.
void bumpCycle(unsigned NextCycle)
Move the boundary of scheduled code by one cycle.
unsigned countResource(unsigned PIdx, unsigned Cycles, unsigned ReadyCycle)
Add the given processor resource to this scheduled zone.
iterator find(SUnit *SU)
void scheduleMI(SUnit *SU, bool IsTopNode)
Move an instruction and update register pressure.
void tryCandidate(SchedCandidate &Cand, SchedCandidate &TryCand, SchedBoundary &Zone, const RegPressureTracker &RPTracker, RegPressureTracker &TempTracker)
Apply a set of heursitics to a new candidate.
RegPressureTracker BotRPTracker
bool operator!=(const SchedResourceDelta &RHS) const
const SchedDFSResult * getDFSResult() const
Return a non-null DFS result if the scheduling strategy initialized it.
void buildDAGWithRegPressure()
Call ScheduleDAGInstrs::buildSchedGraph with register pressure tracking enabled.
std::vector< PressureChange > RegionCriticalPSets
List of pressure sets that exceed the target's pressure limit before scheduling, listed in increasing...
static const char * getReasonStr(GenericSchedulerBase::CandReason Reason)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: ArrayRef.h:31
SchedRemainder * Rem
bool IsPostRA
isPostRA flag indicates vregs cannot be present.
void releasePending()
Release pending ready nodes in to the available queue.
virtual void initPolicy(MachineBasicBlock::iterator Begin, MachineBasicBlock::iterator End, unsigned NumRegionInstrs)
Optionally override the per-region scheduling policy.
MachinePassRegistry - Track the registration of machine passes.
void bumpNode(SUnit *SU)
Move the boundary of scheduled code by one SUnit.
SUnit * pickNode(bool &IsTopNode) override
Pick the next node to schedule.
CandReason
Represent the type of SchedCandidate found within a single queue.
void checkAcyclicLatency()
Set IsAcyclicLatencyLimited if the acyclic path is longer than the cyclic critical path by more cycle...
void incExecutedResources(unsigned PIdx, unsigned Count)
virtual void registerRoots()
Notify this strategy that all roots have been released (including those that depend on EntrySU or Exi...
std::vector< SUnit * >::iterator iterator
SDep - Scheduling dependency.
Definition: ScheduleDAG.h:45
RegisterClassInfo * RegClassInfo
bundle_iterator< MachineInstr, instr_iterator > iterator
ScheduleHazardRecognizer * HazardRec
unsigned getNextResourceCycle(unsigned PIdx, unsigned Cycles)
Compute the next cycle at which the given processor resource can be scheduled.
Helpers for implementing custom MachineSchedStrategy classes.
Array of PressureDiffs.
RegisterPressure computed within a region of instructions delimited by TopIdx and BottomIdx...
bool operator==(const SchedResourceDelta &RHS) const
HazardRecognizer - This determines whether or not an instruction can be issued this cycle...
unsigned getScheduledLatency() const
Get the number of latency cycles "covered" by the scheduled instructions.
void dumpSchedule() const
dump the scheduled Sequence.
void removeReady(SUnit *SU)
Remove SU from the ready set for this boundary.
unsigned getZoneCritResIdx() const
bundle_iterator - MachineBasicBlock iterator that automatically skips over MIs that are inside bundle...
unsigned getLatencyFactor() const
Multiply cycle count by this factor to normalize it relative to other resources.
MachinePassRegistryNode * getNext() const
bool addEdge(SUnit *SuccSU, const SDep &PredDep)
Add a DAG edge to the given SU with the given predecessor dependence data.
static MachinePassRegistry Registry
bool empty() const
Store the state used by GenericScheduler heuristics, required for the lifetime of one invocation of p...
bool checkHazard(SUnit *SU)
Does this SU have a hazard within the current instruction group.
void releasePred(SUnit *SU, SDep *PredEdge)
ReleasePred - Decrement the NumSuccsLeft count of a predecessor.
Track the current register pressure at some position in the instruction stream, and remember the high...
virtual void releaseBottomNode(SUnit *SU)=0
When all successor dependencies have been resolved, free this node for bottom-up scheduling.
void findRootsAndBiasEdges(SmallVectorImpl< SUnit * > &TopRoots, SmallVectorImpl< SUnit * > &BotRoots)
Policy for scheduling the next instruction in the candidate's zone.
const TargetSchedModel * SchedModel
List of PressureChanges in order of increasing, unique PSetID.
const TargetRegisterInfo * TRI
SchedDFSResult * DFSResult
Information about DAG subtrees.
const IntervalPressure & getRegPressure() const
Get register pressure for the entire scheduling region before scheduling.
bool isNextSU(const SUnit *SU) const
Return true if the given SU is used by the most recently scheduled instruction.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
void releaseSuccessors(SUnit *SU)
releaseSuccessors - Call releaseSucc on each of SU's successors.
const SUnit * NextClusterSucc
void viewGraph() override
Out-of-line implementation with no arguments is handy for gdb.
void setPolicy(CandPolicy &Policy, bool IsPostRA, SchedBoundary &CurrZone, SchedBoundary *OtherZone)
Set the CandPolicy given a scheduling zone given the current resources and latencies inside and outsi...
SchedBoundary(unsigned ID, const Twine &Name)
Pending queues extend the ready queues with the same ID and the PendingFlag set.
void init(ScheduleDAGMI *dag, const TargetSchedModel *smodel, SchedRemainder *rem)
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
Definition: SmallPtrSet.h:299
const SUnit * NextClusterPred
Record the next node in a scheduled cluster.
void registerRoots() override
Notify this strategy that all roots have been released (including those that depend on EntrySU or Exi...
void reschedulePhysRegCopies(SUnit *SU, bool isTop)
GenericScheduler shrinks the unscheduled zone using heuristics to balance the schedule.
unsigned getExecutedCount() const
Get a scaled count for the minimum execution time of the scheduled micro-ops that are ready to execut...
ScheduleDAGInstrs *(* ScheduleDAGCtor)(MachineSchedContext *)
bool shouldTrackPressure() const override
Check if pressure tracking is needed before building the DAG and initializing this strategy...
const MachineLoopInfo * MLI
void enterRegion(MachineBasicBlock *bb, MachineBasicBlock::iterator begin, MachineBasicBlock::iterator end, unsigned regioninstrs) override
Implement the ScheduleDAGInstrs interface for handling the next scheduling region.
void releaseNode(SUnit *SU, unsigned ReadyCycle)
bool hasVRegLiveness() const override
Return true if this DAG supports VReg liveness and RegPressure.
void updateScheduledPressure(const SUnit *SU, const std::vector< unsigned > &NewMaxPressure)
void initResourceDelta(const ScheduleDAGMI *DAG, const TargetSchedModel *SchedModel)
unsigned getOtherResourceCount(unsigned &OtherCritIdx)
PostGenericScheduler(const MachineSchedContext *C)
void tryCandidate(SchedCandidate &Cand, SchedCandidate &TryCand)
Apply a set of heursitics to a new candidate for PostRA scheduling.
ReadyQueue(unsigned id, const Twine &name)
MachinePassRegistryListener - Listener to adds and removals of nodes in registration list...
MachineBasicBlock::iterator bottom() const
void moveInstruction(MachineInstr *MI, MachineBasicBlock::iterator InsertPos)
Change the position of an instruction within the basic block and update live ranges and region bounda...
ScheduleDAGMILive(MachineSchedContext *C, std::unique_ptr< MachineSchedStrategy > S)
MachineBasicBlock::iterator end() const
end - Return an iterator to the bottom of the current scheduling region.
virtual bool hasVRegLiveness() const
Return true if this DAG supports VReg liveness and RegPressure.
unsigned getDepth() const
getDepth - Return the depth of this node, which is the length of the maximum path up to any node whic...
Definition: ScheduleDAG.h:423
void updatePressureDiffs(ArrayRef< unsigned > LiveUses)
Update the PressureDiff array for liveness after scheduling this instruction.
void schedNode(SUnit *SU, bool IsTopNode) override
Update the scheduler's state after scheduling a node.
const SUnit * getNextClusterSucc() const
virtual void scheduleTree(unsigned SubtreeID)
Scheduler callback to notify that a new subtree is scheduled.
void releasePredecessors(SUnit *SU)
releasePredecessors - Call releasePred on each of SU's predecessors.
unsigned getUnscheduledLatency(SUnit *SU) const
void initialize(ScheduleDAGMI *dag) override
Initialize the strategy after building the DAG for a new region.
unsigned NodeQueueId
Definition: ScheduleDAG.h:284
virtual SUnit * pickNode(bool &IsTopNode)=0
Pick the next node to schedule, or return NULL.
ScheduleDAGInstrs - A ScheduleDAG subclass for scheduling lists of MachineInstrs. ...
Define a generic scheduling policy for targets that don't provide their own MachineSchedStrategy.
Representation of each machine instruction.
Definition: MachineInstr.h:51
const MachineDominatorTree * MDT
void initialize(ScheduleDAGMI *Dag) override
Initialize the strategy after building the DAG for a new region.
SUnit * pickOnlyChoice()
Call this before applying any other heuristics to the Available queue.
Status of an instruction's critical resource consumption.
GenericScheduler(const MachineSchedContext *C)
bool shouldTrackPressure() const override
PostRA scheduling does not track pressure.
cl::opt< bool > ForceBottomUp
unsigned findMaxLatency(ArrayRef< SUnit * > ReadySUs)
MachineSchedContext provides enough context from the MachineScheduler pass for the target to instanti...
MachineSchedStrategy - Interface to the scheduling algorithm used by ScheduleDAGMI.
#define I(x, y, z)
Definition: MD5.cpp:54
#define N
MachinePassRegistryNode - Machine pass node stored in registration list.
SmallVector< unsigned, 16 > RemainingCounts
void placeDebugValues()
Reinsert debug_values recorded in ScheduleDAGInstrs::DbgValues.
unsigned getLatencyStallCycles(SUnit *SU)
Get the difference between the given SUnit's ready time and the current cycle.
void schedule() override
Implement ScheduleDAGInstrs interface for scheduling a sequence of reorderable instructions.
SUnit * pickNode(bool &IsTopNode) override
Pick the best node to balance the schedule. Implements MachineSchedStrategy.
const std::vector< PressureChange > & getRegionCriticalPSets() const
IntervalPressure TopPressure
The top of the unscheduled zone.
void releaseTopNode(SUnit *SU) override
When all predecessor dependencies have been resolved, free this node for top-down scheduling...
unsigned NodeNum
Definition: ScheduleDAG.h:283
void registerRoots() override
Notify this strategy that all roots have been released (including those that depend on EntrySU or Exi...
MachineBasicBlock::iterator CurrentBottom
The bottom of the unscheduled zone.
Store the effects of a change in pressure on things that MI scheduler cares about.
void initQueues(ArrayRef< SUnit * > TopRoots, ArrayRef< SUnit * > BotRoots)
Release ExitSU predecessors and setup scheduler queues.
unsigned getMicroOpFactor() const
Multiply number of micro-ops by this factor to normalize it relative to other resources.
void postprocessDAG()
Apply each ScheduleDAGMutation step in order.
static const char * name
ScheduleDAGMI(MachineSchedContext *C, std::unique_ptr< MachineSchedStrategy > S, bool IsPostRA)
const SUnit * getNextClusterPred() const
StringRef getName() const
unsigned size() const
IntervalPressure RegPressure
void push(SUnit *SU)
unsigned getCurrMOps() const
Micro-ops issued in the current cycle.
bool canAddEdge(SUnit *SuccSU, SUnit *PredSU)
True if an edge can be added from PredSU to SuccSU without creating a cycle.
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:40
const TargetSchedModel * SchedModel
IntervalPressure BotPressure
The bottom of the unscheduled zone.
std::vector< SUnit > SUnits
Definition: ScheduleDAG.h:565
ScheduleDAGTopologicalSort is a class that computes a topological ordering for SUnits and provides me...
Definition: ScheduleDAG.h:691
void releaseBottomNode(SUnit *SU) override
When all successor dependencies have been resolved, free this node for bottom-up scheduling.
AliasAnalysis * AA
RegPressureTracker TopRPTracker
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
RegPressureTracker RPTracker
virtual void apply(ScheduleDAGMI *DAG)=0
LiveIntervals * LIS
Live Intervals provides reaching defs in preRA scheduling.
void pickNodeFromQueue(SchedCandidate &Cand)
unsigned getResourceCount(unsigned ResIdx) const
SUnit - Scheduling unit. This is a node in the scheduling DAG.
Definition: ScheduleDAG.h:261
void addMutation(std::unique_ptr< ScheduleDAGMutation > Mutation)
Add a postprocessing step to the DAG builder.
cl::opt< bool > ForceTopDown
void releaseBottomNode(SUnit *SU) override
When all successor dependencies have been resolved, free this node for bottom-up scheduling.
bool isResourceLimited() const