LLVM  4.0.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 = createGenericSchedLive(C);
46 // DAG->addMutation(new CustomDAGMutation(...));
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 // unsigned NumRegionInstrs) const {
70 // Policy.<Flag> = true;
71 // }
72 //
73 //===----------------------------------------------------------------------===//
74 
75 #ifndef LLVM_CODEGEN_MACHINESCHEDULER_H
76 #define LLVM_CODEGEN_MACHINESCHEDULER_H
77 
78 #include "llvm/ADT/ArrayRef.h"
79 #include "llvm/ADT/BitVector.h"
80 #include "llvm/ADT/STLExtras.h"
81 #include "llvm/ADT/SmallVector.h"
82 #include "llvm/ADT/StringRef.h"
83 #include "llvm/ADT/Twine.h"
94 #include <algorithm>
95 #include <cassert>
96 #include <memory>
97 #include <string>
98 #include <vector>
99 
100 namespace llvm {
101 
102 extern cl::opt<bool> ForceTopDown;
103 extern cl::opt<bool> ForceBottomUp;
104 
105 class LiveIntervals;
106 class MachineDominatorTree;
107 class MachineLoopInfo;
108 class RegisterClassInfo;
109 class SchedDFSResult;
110 class ScheduleHazardRecognizer;
111 
112 /// MachineSchedContext provides enough context from the MachineScheduler pass
113 /// for the target to instantiate a scheduler.
121 
123 
125  virtual ~MachineSchedContext();
126 };
127 
128 /// MachineSchedRegistry provides a selection of available machine instruction
129 /// schedulers.
131 public:
132  typedef ScheduleDAGInstrs *(*ScheduleDAGCtor)(MachineSchedContext *);
133 
134  // RegisterPassParser requires a (misnamed) FunctionPassCtor type.
136 
138 
139  MachineSchedRegistry(const char *N, const char *D, ScheduleDAGCtor C)
141  Registry.Add(this);
142  }
143 
144  ~MachineSchedRegistry() { Registry.Remove(this); }
145 
146  // Accessors.
147  //
150  }
151 
153  return (MachineSchedRegistry *)Registry.getList();
154  }
155 
157  Registry.setListener(L);
158  }
159 };
160 
161 class ScheduleDAGMI;
162 
163 /// Define a generic scheduling policy for targets that don't provide their own
164 /// MachineSchedStrategy. This can be overriden for each scheduling region
165 /// before building the DAG.
167  // Allow the scheduler to disable register pressure tracking.
169  /// Track LaneMasks to allow reordering of independent subregister writes
170  /// of the same vreg. \sa MachineSchedStrategy::shouldTrackLaneMasks()
172 
173  // Allow the scheduler to force top-down or bottom-up scheduling. If neither
174  // is true, the scheduler runs in both directions and converges.
177 
178  // Disable heuristic that tries to fetch nodes from long dependency chains
179  // first.
181 
184 };
185 
186 /// MachineSchedStrategy - Interface to the scheduling algorithm used by
187 /// ScheduleDAGMI.
188 ///
189 /// Initialization sequence:
190 /// initPolicy -> shouldTrackPressure -> initialize(DAG) -> registerRoots
192  virtual void anchor();
193 
194 public:
195  virtual ~MachineSchedStrategy() = default;
196 
197  /// Optionally override the per-region scheduling policy.
200  unsigned NumRegionInstrs) {}
201 
202  virtual void dumpPolicy() {}
203 
204  /// Check if pressure tracking is needed before building the DAG and
205  /// initializing this strategy. Called after initPolicy.
206  virtual bool shouldTrackPressure() const { return true; }
207 
208  /// Returns true if lanemasks should be tracked. LaneMask tracking is
209  /// necessary to reorder independent subregister defs for the same vreg.
210  /// This has to be enabled in combination with shouldTrackPressure().
211  virtual bool shouldTrackLaneMasks() const { return false; }
212 
213  /// Initialize the strategy after building the DAG for a new region.
214  virtual void initialize(ScheduleDAGMI *DAG) = 0;
215 
216  /// Notify this strategy that all roots have been released (including those
217  /// that depend on EntrySU or ExitSU).
218  virtual void registerRoots() {}
219 
220  /// Pick the next node to schedule, or return NULL. Set IsTopNode to true to
221  /// schedule the node at the top of the unscheduled region. Otherwise it will
222  /// be scheduled at the bottom.
223  virtual SUnit *pickNode(bool &IsTopNode) = 0;
224 
225  /// \brief Scheduler callback to notify that a new subtree is scheduled.
226  virtual void scheduleTree(unsigned SubtreeID) {}
227 
228  /// Notify MachineSchedStrategy that ScheduleDAGMI has scheduled an
229  /// instruction and updated scheduled/remaining flags in the DAG nodes.
230  virtual void schedNode(SUnit *SU, bool IsTopNode) = 0;
231 
232  /// When all predecessor dependencies have been resolved, free this node for
233  /// top-down scheduling.
234  virtual void releaseTopNode(SUnit *SU) = 0;
235  /// When all successor dependencies have been resolved, free this node for
236  /// bottom-up scheduling.
237  virtual void releaseBottomNode(SUnit *SU) = 0;
238 };
239 
240 /// ScheduleDAGMI is an implementation of ScheduleDAGInstrs that simply
241 /// schedules machine instructions according to the given MachineSchedStrategy
242 /// without much extra book-keeping. This is the common functionality between
243 /// PreRA and PostRA MachineScheduler.
245 protected:
248  std::unique_ptr<MachineSchedStrategy> SchedImpl;
249 
250  /// Topo - A topological ordering for SUnits which permits fast IsReachable
251  /// and similar queries.
253 
254  /// Ordered list of DAG postprocessing steps.
255  std::vector<std::unique_ptr<ScheduleDAGMutation>> Mutations;
256 
257  /// The top of the unscheduled zone.
259 
260  /// The bottom of the unscheduled zone.
262 
263  /// Record the next node in a scheduled cluster.
266 
267 #ifndef NDEBUG
268  /// The number of instructions scheduled so far. Used to cut off the
269  /// scheduler at the point determined by misched-cutoff.
271 #endif
272 public:
273  ScheduleDAGMI(MachineSchedContext *C, std::unique_ptr<MachineSchedStrategy> S,
274  bool RemoveKillFlags)
275  : ScheduleDAGInstrs(*C->MF, C->MLI, RemoveKillFlags), AA(C->AA),
276  LIS(C->LIS), SchedImpl(std::move(S)), Topo(SUnits, &ExitSU),
277  NextClusterPred(nullptr), NextClusterSucc(nullptr) {
278 #ifndef NDEBUG
279  NumInstrsScheduled = 0;
280 #endif
281  }
282 
283  // Provide a vtable anchor
284  ~ScheduleDAGMI() override;
285 
286  // Returns LiveIntervals instance for use in DAG mutators and such.
287  LiveIntervals *getLIS() const { return LIS; }
288 
289  /// Return true if this DAG supports VReg liveness and RegPressure.
290  virtual bool hasVRegLiveness() const { return false; }
291 
292  /// Add a postprocessing step to the DAG builder.
293  /// Mutations are applied in the order that they are added after normal DAG
294  /// building and before MachineSchedStrategy initialization.
295  ///
296  /// ScheduleDAGMI takes ownership of the Mutation object.
297  void addMutation(std::unique_ptr<ScheduleDAGMutation> Mutation) {
298  if (Mutation)
299  Mutations.push_back(std::move(Mutation));
300  }
301 
302  /// \brief True if an edge can be added from PredSU to SuccSU without creating
303  /// a cycle.
304  bool canAddEdge(SUnit *SuccSU, SUnit *PredSU);
305 
306  /// \brief Add a DAG edge to the given SU with the given predecessor
307  /// dependence data.
308  ///
309  /// \returns true if the edge may be added without creating a cycle OR if an
310  /// equivalent edge already existed (false indicates failure).
311  bool addEdge(SUnit *SuccSU, const SDep &PredDep);
312 
315 
316  /// Implement the ScheduleDAGInstrs interface for handling the next scheduling
317  /// region. This covers all instructions in a block, while schedule() may only
318  /// cover a subset.
322  unsigned regioninstrs) override;
323 
324  /// Implement ScheduleDAGInstrs interface for scheduling a sequence of
325  /// reorderable instructions.
326  void schedule() override;
327 
328  /// Change the position of an instruction within the basic block and update
329  /// live ranges and region boundary iterators.
331 
332  const SUnit *getNextClusterPred() const { return NextClusterPred; }
333 
334  const SUnit *getNextClusterSucc() const { return NextClusterSucc; }
335 
336  void viewGraph(const Twine &Name, const Twine &Title) override;
337  void viewGraph() override;
338 
339 protected:
340  // Top-Level entry points for the schedule() driver...
341 
342  /// Apply each ScheduleDAGMutation step in order. This allows different
343  /// instances of ScheduleDAGMI to perform custom DAG postprocessing.
344  void postprocessDAG();
345 
346  /// Release ExitSU predecessors and setup scheduler queues.
347  void initQueues(ArrayRef<SUnit*> TopRoots, ArrayRef<SUnit*> BotRoots);
348 
349  /// Update scheduler DAG and queues after scheduling an instruction.
350  void updateQueues(SUnit *SU, bool IsTopNode);
351 
352  /// Reinsert debug_values recorded in ScheduleDAGInstrs::DbgValues.
353  void placeDebugValues();
354 
355  /// \brief dump the scheduled Sequence.
356  void dumpSchedule() const;
357 
358  // Lesser helpers...
359  bool checkSchedLimit();
360 
362  SmallVectorImpl<SUnit*> &BotRoots);
363 
364  void releaseSucc(SUnit *SU, SDep *SuccEdge);
365  void releaseSuccessors(SUnit *SU);
366  void releasePred(SUnit *SU, SDep *PredEdge);
367  void releasePredecessors(SUnit *SU);
368 };
369 
370 /// ScheduleDAGMILive is an implementation of ScheduleDAGInstrs that schedules
371 /// machine instructions while updating LiveIntervals and tracking regpressure.
373 protected:
375 
376  /// Information about DAG subtrees. If DFSResult is NULL, then SchedulerTrees
377  /// will be empty.
380 
382 
383  /// Maps vregs to the SUnits of their uses in the current scheduling region.
385 
386  // Map each SU to its summary of pressure changes. This array is updated for
387  // liveness during bottom-up scheduling. Top-down scheduling may proceed but
388  // has no affect on the pressure diffs.
390 
391  /// Register pressure in this region computed by initRegPressure.
396 
397  /// List of pressure sets that exceed the target's pressure limit before
398  /// scheduling, listed in increasing set ID order. Each pressure set is paired
399  /// with its max pressure in the currently scheduled regions.
400  std::vector<PressureChange> RegionCriticalPSets;
401 
402  /// The top of the unscheduled zone.
405 
406  /// The bottom of the unscheduled zone.
409 
410  /// True if disconnected subregister components are already renamed.
411  /// The renaming is only done on demand if lane masks are tracked.
413 
414 public:
416  std::unique_ptr<MachineSchedStrategy> S)
417  : ScheduleDAGMI(C, std::move(S), /*RemoveKillFlags=*/false),
418  RegClassInfo(C->RegClassInfo), DFSResult(nullptr),
422 
423  ~ScheduleDAGMILive() override;
424 
425  /// Return true if this DAG supports VReg liveness and RegPressure.
426  bool hasVRegLiveness() const override { return true; }
427 
428  /// \brief Return true if register pressure tracking is enabled.
429  bool isTrackingPressure() const { return ShouldTrackPressure; }
430 
431  /// Get current register pressure for the top scheduled instructions.
432  const IntervalPressure &getTopPressure() const { return TopPressure; }
434 
435  /// Get current register pressure for the bottom scheduled instructions.
436  const IntervalPressure &getBotPressure() const { return BotPressure; }
438 
439  /// Get register pressure for the entire scheduling region before scheduling.
440  const IntervalPressure &getRegPressure() const { return RegPressure; }
441 
442  const std::vector<PressureChange> &getRegionCriticalPSets() const {
443  return RegionCriticalPSets;
444  }
445 
447  return SUPressureDiffs[SU->NodeNum];
448  }
449 
450  /// Compute a DFSResult after DAG building is complete, and before any
451  /// queue comparisons.
452  void computeDFSResult();
453 
454  /// Return a non-null DFS result if the scheduling strategy initialized it.
455  const SchedDFSResult *getDFSResult() const { return DFSResult; }
456 
458 
459  /// Implement the ScheduleDAGInstrs interface for handling the next scheduling
460  /// region. This covers all instructions in a block, while schedule() may only
461  /// cover a subset.
465  unsigned regioninstrs) override;
466 
467  /// Implement ScheduleDAGInstrs interface for scheduling a sequence of
468  /// reorderable instructions.
469  void schedule() override;
470 
471  /// Compute the cyclic critical path through the DAG.
472  unsigned computeCyclicCriticalPath();
473 
474 protected:
475  // Top-Level entry points for the schedule() driver...
476 
477  /// Call ScheduleDAGInstrs::buildSchedGraph with register pressure tracking
478  /// enabled. This sets up three trackers. RPTracker will cover the entire DAG
479  /// region, TopTracker and BottomTracker will be initialized to the top and
480  /// bottom of the DAG region without covereing any unscheduled instruction.
482 
483  /// Release ExitSU predecessors and setup scheduler queues. Re-position
484  /// the Top RP tracker in case the region beginning has changed.
485  void initQueues(ArrayRef<SUnit*> TopRoots, ArrayRef<SUnit*> BotRoots);
486 
487  /// Move an instruction and update register pressure.
488  void scheduleMI(SUnit *SU, bool IsTopNode);
489 
490  // Lesser helpers...
491 
492  void initRegPressure();
493 
495 
496  void updateScheduledPressure(const SUnit *SU,
497  const std::vector<unsigned> &NewMaxPressure);
498 
499  void collectVRegUses(SUnit &SU);
500 };
501 
502 //===----------------------------------------------------------------------===//
503 ///
504 /// Helpers for implementing custom MachineSchedStrategy classes. These take
505 /// care of the book-keeping associated with list scheduling heuristics.
506 ///
507 //===----------------------------------------------------------------------===//
508 
509 /// ReadyQueue encapsulates vector of "ready" SUnits with basic convenience
510 /// methods for pushing and removing nodes. ReadyQueue's are uniquely identified
511 /// by an ID. SUnit::NodeQueueId is a mask of the ReadyQueues the SUnit is in.
512 ///
513 /// This is a convenience class that may be used by implementations of
514 /// MachineSchedStrategy.
515 class ReadyQueue {
516  unsigned ID;
517  std::string Name;
518  std::vector<SUnit*> Queue;
519 
520 public:
521  ReadyQueue(unsigned id, const Twine &name): ID(id), Name(name.str()) {}
522 
523  unsigned getID() const { return ID; }
524 
525  StringRef getName() const { return Name; }
526 
527  // SU is in this queue if it's NodeQueueID is a superset of this ID.
528  bool isInQueue(SUnit *SU) const { return (SU->NodeQueueId & ID); }
529 
530  bool empty() const { return Queue.empty(); }
531 
532  void clear() { Queue.clear(); }
533 
534  unsigned size() const { return Queue.size(); }
535 
536  typedef std::vector<SUnit*>::iterator iterator;
537 
538  iterator begin() { return Queue.begin(); }
539 
540  iterator end() { return Queue.end(); }
541 
542  ArrayRef<SUnit*> elements() { return Queue; }
543 
544  iterator find(SUnit *SU) { return llvm::find(Queue, SU); }
545 
546  void push(SUnit *SU) {
547  Queue.push_back(SU);
548  SU->NodeQueueId |= ID;
549  }
550 
551  iterator remove(iterator I) {
552  (*I)->NodeQueueId &= ~ID;
553  *I = Queue.back();
554  unsigned idx = I - Queue.begin();
555  Queue.pop_back();
556  return Queue.begin() + idx;
557  }
558 
559  void dump();
560 };
561 
562 /// Summarize the unscheduled region.
564  // Critical path through the DAG in expected latency.
565  unsigned CriticalPath;
566  unsigned CyclicCritPath;
567 
568  // Scaled count of micro-ops left to schedule.
569  unsigned RemIssueCount;
570 
572 
573  // Unscheduled resources
575 
576  void reset() {
577  CriticalPath = 0;
578  CyclicCritPath = 0;
579  RemIssueCount = 0;
580  IsAcyclicLatencyLimited = false;
582  }
583 
585 
586  void init(ScheduleDAGMI *DAG, const TargetSchedModel *SchedModel);
587 };
588 
589 /// Each Scheduling boundary is associated with ready queues. It tracks the
590 /// current cycle in the direction of movement, and maintains the state
591 /// of "hazards" and other interlocks at the current cycle.
593 public:
594  /// SUnit::NodeQueueId: 0 (none), 1 (top), 2 (bot), 3 (both)
595  enum {
596  TopQID = 1,
597  BotQID = 2,
599  };
600 
604 
607 
609 
610 private:
611  /// True if the pending Q should be checked/updated before scheduling another
612  /// instruction.
613  bool CheckPending;
614 
615  /// Number of cycles it takes to issue the instructions scheduled in this
616  /// zone. It is defined as: scheduled-micro-ops / issue-width + stalls.
617  /// See getStalls().
618  unsigned CurrCycle;
619 
620  /// Micro-ops issued in the current cycle
621  unsigned CurrMOps;
622 
623  /// MinReadyCycle - Cycle of the soonest available instruction.
624  unsigned MinReadyCycle;
625 
626  // The expected latency of the critical path in this scheduled zone.
627  unsigned ExpectedLatency;
628 
629  // The latency of dependence chains leading into this zone.
630  // For each node scheduled bottom-up: DLat = max DLat, N.Depth.
631  // For each cycle scheduled: DLat -= 1.
632  unsigned DependentLatency;
633 
634  /// Count the scheduled (issued) micro-ops that can be retired by
635  /// time=CurrCycle assuming the first scheduled instr is retired at time=0.
636  unsigned RetiredMOps;
637 
638  // Count scheduled resources that have been executed. Resources are
639  // considered executed if they become ready in the time that it takes to
640  // saturate any resource including the one in question. Counts are scaled
641  // for direct comparison with other resources. Counts can be compared with
642  // MOps * getMicroOpFactor and Latency * getLatencyFactor.
643  SmallVector<unsigned, 16> ExecutedResCounts;
644 
645  /// Cache the max count for a single resource.
646  unsigned MaxExecutedResCount;
647 
648  // Cache the critical resources ID in this scheduled zone.
649  unsigned ZoneCritResIdx;
650 
651  // Is the scheduled region resource limited vs. latency limited.
652  bool IsResourceLimited;
653 
654  // Record the highest cycle at which each resource has been reserved by a
655  // scheduled instruction.
656  SmallVector<unsigned, 16> ReservedCycles;
657 
658 #ifndef NDEBUG
659  // Remember the greatest possible stall as an upper bound on the number of
660  // times we should retry the pending queue because of a hazard.
661  unsigned MaxObservedStall;
662 #endif
663 
664 public:
665  /// Pending queues extend the ready queues with the same ID and the
666  /// PendingFlag set.
667  SchedBoundary(unsigned ID, const Twine &Name):
668  DAG(nullptr), SchedModel(nullptr), Rem(nullptr), Available(ID, Name+".A"),
669  Pending(ID << LogMaxQID, Name+".P"),
670  HazardRec(nullptr) {
671  reset();
672  }
673 
674  ~SchedBoundary();
675 
676  void reset();
677 
678  void init(ScheduleDAGMI *dag, const TargetSchedModel *smodel,
679  SchedRemainder *rem);
680 
681  bool isTop() const {
682  return Available.getID() == TopQID;
683  }
684 
685  /// Number of cycles to issue the instructions scheduled in this zone.
686  unsigned getCurrCycle() const { return CurrCycle; }
687 
688  /// Micro-ops issued in the current cycle
689  unsigned getCurrMOps() const { return CurrMOps; }
690 
691  // The latency of dependence chains leading into this zone.
692  unsigned getDependentLatency() const { return DependentLatency; }
693 
694  /// Get the number of latency cycles "covered" by the scheduled
695  /// instructions. This is the larger of the critical path within the zone
696  /// and the number of cycles required to issue the instructions.
697  unsigned getScheduledLatency() const {
698  return std::max(ExpectedLatency, CurrCycle);
699  }
700 
701  unsigned getUnscheduledLatency(SUnit *SU) const {
702  return isTop() ? SU->getHeight() : SU->getDepth();
703  }
704 
705  unsigned getResourceCount(unsigned ResIdx) const {
706  return ExecutedResCounts[ResIdx];
707  }
708 
709  /// Get the scaled count of scheduled micro-ops and resources, including
710  /// executed resources.
711  unsigned getCriticalCount() const {
712  if (!ZoneCritResIdx)
713  return RetiredMOps * SchedModel->getMicroOpFactor();
714  return getResourceCount(ZoneCritResIdx);
715  }
716 
717  /// Get a scaled count for the minimum execution time of the scheduled
718  /// micro-ops that are ready to execute by getExecutedCount. Notice the
719  /// feedback loop.
720  unsigned getExecutedCount() const {
721  return std::max(CurrCycle * SchedModel->getLatencyFactor(),
722  MaxExecutedResCount);
723  }
724 
725  unsigned getZoneCritResIdx() const { return ZoneCritResIdx; }
726 
727  // Is the scheduled region resource limited vs. latency limited.
728  bool isResourceLimited() const { return IsResourceLimited; }
729 
730  /// Get the difference between the given SUnit's ready time and the current
731  /// cycle.
732  unsigned getLatencyStallCycles(SUnit *SU);
733 
734  unsigned getNextResourceCycle(unsigned PIdx, unsigned Cycles);
735 
736  bool checkHazard(SUnit *SU);
737 
738  unsigned findMaxLatency(ArrayRef<SUnit*> ReadySUs);
739 
740  unsigned getOtherResourceCount(unsigned &OtherCritIdx);
741 
742  void releaseNode(SUnit *SU, unsigned ReadyCycle);
743 
744  void bumpCycle(unsigned NextCycle);
745 
746  void incExecutedResources(unsigned PIdx, unsigned Count);
747 
748  unsigned countResource(unsigned PIdx, unsigned Cycles, unsigned ReadyCycle);
749 
750  void bumpNode(SUnit *SU);
751 
752  void releasePending();
753 
754  void removeReady(SUnit *SU);
755 
756  /// Call this before applying any other heuristics to the Available queue.
757  /// Updates the Available/Pending Q's if necessary and returns the single
758  /// available instruction, or NULL if there are multiple candidates.
760 
761 #ifndef NDEBUG
762  void dumpScheduledState();
763 #endif
764 };
765 
766 /// Base class for GenericScheduler. This class maintains information about
767 /// scheduling candidates based on TargetSchedModel making it easy to implement
768 /// heuristics for either preRA or postRA scheduling.
770 public:
771  /// Represent the type of SchedCandidate found within a single queue.
772  /// pickNodeBidirectional depends on these listed by decreasing priority.
773  enum CandReason : uint8_t {
777 
778 #ifndef NDEBUG
779  static const char *getReasonStr(GenericSchedulerBase::CandReason Reason);
780 #endif
781 
782  /// Policy for scheduling the next instruction in the candidate's zone.
783  struct CandPolicy {
785  unsigned ReduceResIdx;
786  unsigned DemandResIdx;
787 
789 
790  bool operator==(const CandPolicy &RHS) const {
791  return ReduceLatency == RHS.ReduceLatency &&
792  ReduceResIdx == RHS.ReduceResIdx &&
793  DemandResIdx == RHS.DemandResIdx;
794  }
795  bool operator!=(const CandPolicy &RHS) const {
796  return !(*this == RHS);
797  }
798  };
799 
800  /// Status of an instruction's critical resource consumption.
802  // Count critical resources in the scheduled region required by SU.
803  unsigned CritResources;
804 
805  // Count critical resources from another region consumed by SU.
807 
809 
810  bool operator==(const SchedResourceDelta &RHS) const {
811  return CritResources == RHS.CritResources
813  }
814  bool operator!=(const SchedResourceDelta &RHS) const {
815  return !operator==(RHS);
816  }
817  };
818 
819  /// Store the state used by GenericScheduler heuristics, required for the
820  /// lifetime of one invocation of pickNode().
821  struct SchedCandidate {
823 
824  // The best SUnit candidate.
826 
827  // The reason for this candidate.
829 
830  // Whether this candidate should be scheduled at top/bottom.
831  bool AtTop;
832 
833  // Register pressure values for the best candidate.
835 
836  // Critical resource consumption of the best candidate.
838 
840  SchedCandidate(const CandPolicy &Policy) { reset(Policy); }
841 
842  void reset(const CandPolicy &NewPolicy) {
843  Policy = NewPolicy;
844  SU = nullptr;
845  Reason = NoCand;
846  AtTop = false;
849  }
850 
851  bool isValid() const { return SU; }
852 
853  // Copy the status of another candidate without changing policy.
854  void setBest(SchedCandidate &Best) {
855  assert(Best.Reason != NoCand && "uninitialized Sched candidate");
856  SU = Best.SU;
857  Reason = Best.Reason;
858  AtTop = Best.AtTop;
859  RPDelta = Best.RPDelta;
860  ResDelta = Best.ResDelta;
861  }
862 
863  void initResourceDelta(const ScheduleDAGMI *DAG,
865  };
866 
867 protected:
871 
873 
875  Context(C), SchedModel(nullptr), TRI(nullptr) {}
876 
877  void setPolicy(CandPolicy &Policy, bool IsPostRA, SchedBoundary &CurrZone,
878  SchedBoundary *OtherZone);
879 
880 #ifndef NDEBUG
881  void traceCandidate(const SchedCandidate &Cand);
882 #endif
883 };
884 
885 /// GenericScheduler shrinks the unscheduled zone using heuristics to balance
886 /// the schedule.
888 public:
890  GenericSchedulerBase(C), DAG(nullptr), Top(SchedBoundary::TopQID, "TopQ"),
891  Bot(SchedBoundary::BotQID, "BotQ") {}
892 
895  unsigned NumRegionInstrs) override;
896 
897  void dumpPolicy() override;
898 
899  bool shouldTrackPressure() const override {
901  }
902 
903  bool shouldTrackLaneMasks() const override {
905  }
906 
907  void initialize(ScheduleDAGMI *dag) override;
908 
909  SUnit *pickNode(bool &IsTopNode) override;
910 
911  void schedNode(SUnit *SU, bool IsTopNode) override;
912 
913  void releaseTopNode(SUnit *SU) override {
914  if (SU->isScheduled)
915  return;
916 
917  Top.releaseNode(SU, SU->TopReadyCycle);
918  TopCand.SU = nullptr;
919  }
920 
921  void releaseBottomNode(SUnit *SU) override {
922  if (SU->isScheduled)
923  return;
924 
925  Bot.releaseNode(SU, SU->BotReadyCycle);
926  BotCand.SU = nullptr;
927  }
928 
929  void registerRoots() override;
930 
931 protected:
933 
935 
936  // State of the top and bottom scheduled instruction boundaries.
939 
940  /// Candidate last picked from Top boundary.
941  SchedCandidate TopCand;
942  /// Candidate last picked from Bot boundary.
943  SchedCandidate BotCand;
944 
945  void checkAcyclicLatency();
946 
947  void initCandidate(SchedCandidate &Cand, SUnit *SU, bool AtTop,
948  const RegPressureTracker &RPTracker,
949  RegPressureTracker &TempTracker);
950 
951  void tryCandidate(SchedCandidate &Cand,
952  SchedCandidate &TryCand,
953  SchedBoundary *Zone);
954 
955  SUnit *pickNodeBidirectional(bool &IsTopNode);
956 
957  void pickNodeFromQueue(SchedBoundary &Zone,
958  const CandPolicy &ZonePolicy,
959  const RegPressureTracker &RPTracker,
960  SchedCandidate &Candidate);
961 
962  void reschedulePhysRegCopies(SUnit *SU, bool isTop);
963 };
964 
965 /// PostGenericScheduler - Interface to the scheduling algorithm used by
966 /// ScheduleDAGMI.
967 ///
968 /// Callbacks from ScheduleDAGMI:
969 /// initPolicy -> initialize(DAG) -> registerRoots -> pickNode ...
971  ScheduleDAGMI *DAG;
972  SchedBoundary Top;
973  SmallVector<SUnit*, 8> BotRoots;
974 
975 public:
977  GenericSchedulerBase(C), Top(SchedBoundary::TopQID, "TopQ") {}
978 
979  ~PostGenericScheduler() override = default;
980 
983  unsigned NumRegionInstrs) override {
984  /* no configurable policy */
985  }
986 
987  /// PostRA scheduling does not track pressure.
988  bool shouldTrackPressure() const override { return false; }
989 
990  void initialize(ScheduleDAGMI *Dag) override;
991 
992  void registerRoots() override;
993 
994  SUnit *pickNode(bool &IsTopNode) override;
995 
996  void scheduleTree(unsigned SubtreeID) override {
997  llvm_unreachable("PostRA scheduler does not support subtree analysis.");
998  }
999 
1000  void schedNode(SUnit *SU, bool IsTopNode) override;
1001 
1002  void releaseTopNode(SUnit *SU) override {
1003  if (SU->isScheduled)
1004  return;
1005  Top.releaseNode(SU, SU->TopReadyCycle);
1006  }
1007 
1008  // Only called for roots.
1009  void releaseBottomNode(SUnit *SU) override {
1010  BotRoots.push_back(SU);
1011  }
1012 
1013 protected:
1014  void tryCandidate(SchedCandidate &Cand, SchedCandidate &TryCand);
1015 
1016  void pickNodeFromQueue(SchedCandidate &Cand);
1017 };
1018 
1019 /// Create the standard converging machine scheduler. This will be used as the
1020 /// default scheduler if the target does not set a default.
1021 /// Adds default DAG mutations.
1022 ScheduleDAGMILive *createGenericSchedLive(MachineSchedContext *C);
1023 
1024 /// Create a generic scheduler with no vreg liveness or DAG mutation passes.
1025 ScheduleDAGMI *createGenericSchedPostRA(MachineSchedContext *C);
1026 
1027 std::unique_ptr<ScheduleDAGMutation>
1028 createLoadClusterDAGMutation(const TargetInstrInfo *TII,
1029  const TargetRegisterInfo *TRI);
1030 
1031 std::unique_ptr<ScheduleDAGMutation>
1032 createStoreClusterDAGMutation(const TargetInstrInfo *TII,
1033  const TargetRegisterInfo *TRI);
1034 
1035 std::unique_ptr<ScheduleDAGMutation>
1036 createMacroFusionDAGMutation(const TargetInstrInfo *TII);
1037 
1038 std::unique_ptr<ScheduleDAGMutation>
1039 createCopyConstrainDAGMutation(const TargetInstrInfo *TII,
1040  const TargetRegisterInfo *TRI);
1041 
1042 } // end namespace llvm
1043 
1044 #endif // LLVM_CODEGEN_MACHINESCHEDULER_H
MachineLoop * L
VReg2SUnitMultiMap VRegUses
Maps vregs to the SUnits of their uses in the current scheduling region.
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.
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)
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...
ScheduleDAGMI(MachineSchedContext *C, std::unique_ptr< MachineSchedStrategy > S, bool RemoveKillFlags)
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:45
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.
ScheduleDAGMI * createGenericSchedPostRA(MachineSchedContext *C)
Create a generic scheduler with no vreg liveness or DAG mutation passes.
MachineSchedRegistry(const char *N, const char *D, ScheduleDAGCtor C)
Summarize the unscheduled region.
void reset(const CandPolicy &NewPolicy)
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
unsigned BotReadyCycle
Definition: ScheduleDAG.h:301
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:581
unsigned NumInstrsScheduled
The number of instructions scheduled so far.
bool isScheduled
Definition: ScheduleDAG.h:286
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:425
ArrayRef< SUnit * > elements()
BitVector & getScheduledTrees()
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
Provide an instruction scheduling machine model to CodeGen passes.
const HexagonInstrInfo * TII
const TargetPassConfig * PassConfig
const IntervalPressure & getBotPressure() const
Get current register pressure for the bottom scheduled instructions.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:32
static GCRegistry::Add< StatepointGC > D("statepoint-example","an example strategy for statepoint")
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.
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.
bool shouldTrackLaneMasks() const override
Returns true if lanemasks should be tracked.
static MachineSchedRegistry * getList()
Compute the values of each DAG node for various metrics during DFS.
Definition: ScheduleDFS.h:66
unsigned TopReadyCycle
Definition: ScheduleDAG.h:300
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.
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.
bool DisconnectedComponentsRenamed
True if disconnected subregister components are already renamed.
Function Alias Analysis false
MachineSchedPolicy RegionPolicy
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: APInt.h:33
SchedRemainder * Rem
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.
ScheduleDAGMILive * createGenericSchedLive(MachineSchedContext *C)
Create the standard converging machine scheduler.
MachinePassRegistry - Track the registration of machine passes.
std::unique_ptr< ScheduleDAGMutation > createMacroFusionDAGMutation(const TargetInstrInfo *TII)
void collectVRegUses(SUnit &SU)
void bumpNode(SUnit *SU)
Move the boundary of scheduled code by one SUnit.
SUnit * pickNode(bool &IsTopNode) override
Pick the next node to schedule.
void initCandidate(SchedCandidate &Cand, SUnit *SU, bool AtTop, const RegPressureTracker &RPTracker, RegPressureTracker &TempTracker)
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
ScheduleHazardRecognizer * HazardRec
unsigned getNextResourceCycle(unsigned PIdx, unsigned Cycles)
Compute the next cycle at which the given processor resource can be scheduled.
void initQueues(ArrayRef< SUnit * > TopRoots, ArrayRef< SUnit * > BotRoots)
Release ExitSU predecessors and setup scheduler queues.
CandReason
Represent the type of SchedCandidate found within a single queue.
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.
bool RemoveKillFlags
True if the DAG builder should remove kill flags (in preparation for rescheduling).
bool operator==(const CandPolicy &RHS) const
void removeReady(SUnit *SU)
Remove SU from the ready set for this boundary.
unsigned getZoneCritResIdx() const
void updatePressureDiffs(ArrayRef< RegisterMaskPair > LiveUses)
Update the PressureDiff array for liveness after scheduling this instruction.
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.
bool ShouldTrackLaneMasks
Track LaneMasks to allow reordering of independent subregister writes of the same vreg...
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 tryCandidate(SchedCandidate &Cand, SchedCandidate &TryCand, SchedBoundary *Zone)
Apply a set of heursitics to a new candidate.
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...
static const unsigned End
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
std::unique_ptr< ScheduleDAGMutation > createStoreClusterDAGMutation(const TargetInstrInfo *TII, const TargetRegisterInfo *TRI)
SchedDFSResult * DFSResult
Information about DAG subtrees.
const IntervalPressure & getRegPressure() const
Get register pressure for the entire scheduling region before scheduling.
LiveIntervals * getLIS() const
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
ScheduleDAGMILive * DAG
void releaseSuccessors(SUnit *SU)
releaseSuccessors - Call releaseSucc on each of SU's successors.
const SUnit * NextClusterSucc
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
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)
virtual bool shouldTrackLaneMasks() const
Returns true if lanemasks should be tracked.
std::unique_ptr< ScheduleDAGMutation > createLoadClusterDAGMutation(const TargetInstrInfo *TII, const TargetRegisterInfo *TRI)
const SUnit * NextClusterPred
Record the next node in a scheduled cluster.
auto find(R &&Range, const T &Val) -> decltype(std::begin(Range))
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:757
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)
std::unique_ptr< ScheduleDAGMutation > createCopyConstrainDAGMutation(const TargetInstrInfo *TII, const TargetRegisterInfo *TRI)
void initResourceDelta(const ScheduleDAGMI *DAG, const TargetSchedModel *SchedModel)
static GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
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:417
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:267
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:52
LiveIntervals * LIS
const MachineDominatorTree * MDT
void initialize(ScheduleDAGMI *Dag) override
Initialize the strategy after building the DAG for a new region.
bool operator!=(const CandPolicy &RHS) const
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.
SchedCandidate BotCand
Candidate last picked from Bot boundary.
cl::opt< bool > ForceBottomUp
unsigned findMaxLatency(ArrayRef< SUnit * > ReadySUs)
MachineSchedContext provides enough context from the MachineScheduler pass for the target to instanti...
~PostGenericScheduler() override=default
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.
virtual ~MachineSchedStrategy()=default
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.
void pickNodeFromQueue(SchedBoundary &Zone, const CandPolicy &ZonePolicy, const RegPressureTracker &RPTracker, SchedCandidate &Candidate)
Pick the best candidate from the queue.
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:266
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.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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
SchedCandidate TopCand
Candidate last picked from Top boundary.
const SUnit * getNextClusterPred() const
StringRef getName() const
unsigned size() const
IntervalPressure RegPressure
void push(SUnit *SU)
IRTranslator LLVM IR MI
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:47
const TargetSchedModel * SchedModel
IntervalPressure BotPressure
The bottom of the unscheduled zone.
std::vector< SUnit > SUnits
Definition: ScheduleDAG.h:583
ScheduleDAGTopologicalSort is a class that computes a topological ordering for SUnits and provides me...
Definition: ScheduleDAG.h:709
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
void pickNodeFromQueue(SchedCandidate &Cand)
unsigned getResourceCount(unsigned ResIdx) const
SUnit - Scheduling unit. This is a node in the scheduling DAG.
Definition: ScheduleDAG.h:244
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