LCOV - code coverage report
Current view: top level - include/llvm/CodeGen - MachineScheduler.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 95 121 78.5 %
Date: 2018-10-20 13:21:21 Functions: 26 51 51.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : // scheduler, 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 ScheduleDAGMILive(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"
      84             : #include "llvm/Analysis/AliasAnalysis.h"
      85             : #include "llvm/CodeGen/MachineBasicBlock.h"
      86             : #include "llvm/CodeGen/MachinePassRegistry.h"
      87             : #include "llvm/CodeGen/RegisterPressure.h"
      88             : #include "llvm/CodeGen/ScheduleDAG.h"
      89             : #include "llvm/CodeGen/ScheduleDAGInstrs.h"
      90             : #include "llvm/CodeGen/ScheduleDAGMutation.h"
      91             : #include "llvm/CodeGen/TargetSchedule.h"
      92             : #include "llvm/Support/CommandLine.h"
      93             : #include "llvm/Support/ErrorHandling.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 MachineFunction;
     108             : class MachineInstr;
     109             : class MachineLoopInfo;
     110             : class RegisterClassInfo;
     111             : class SchedDFSResult;
     112             : class ScheduleHazardRecognizer;
     113             : class TargetInstrInfo;
     114             : class TargetPassConfig;
     115             : class TargetRegisterInfo;
     116             : 
     117             : /// MachineSchedContext provides enough context from the MachineScheduler pass
     118             : /// for the target to instantiate a scheduler.
     119             : struct MachineSchedContext {
     120             :   MachineFunction *MF = nullptr;
     121             :   const MachineLoopInfo *MLI = nullptr;
     122             :   const MachineDominatorTree *MDT = nullptr;
     123             :   const TargetPassConfig *PassConfig = nullptr;
     124             :   AliasAnalysis *AA = nullptr;
     125             :   LiveIntervals *LIS = nullptr;
     126             : 
     127             :   RegisterClassInfo *RegClassInfo;
     128             : 
     129             :   MachineSchedContext();
     130             :   virtual ~MachineSchedContext();
     131             : };
     132             : 
     133             : /// MachineSchedRegistry provides a selection of available machine instruction
     134             : /// schedulers.
     135             : class MachineSchedRegistry : public MachinePassRegistryNode {
     136             : public:
     137             :   using ScheduleDAGCtor = ScheduleDAGInstrs *(*)(MachineSchedContext *);
     138             : 
     139             :   // RegisterPassParser requires a (misnamed) FunctionPassCtor type.
     140             :   using FunctionPassCtor = ScheduleDAGCtor;
     141             : 
     142             :   static MachinePassRegistry Registry;
     143             : 
     144             :   MachineSchedRegistry(const char *N, const char *D, ScheduleDAGCtor C)
     145             :     : MachinePassRegistryNode(N, D, (MachinePassCtor)C) {
     146             :     Registry.Add(this);
     147             :   }
     148             : 
     149     1253296 :   ~MachineSchedRegistry() { Registry.Remove(this); }
     150             : 
     151             :   // Accessors.
     152             :   //
     153             :   MachineSchedRegistry *getNext() const {
     154           0 :     return (MachineSchedRegistry *)MachinePassRegistryNode::getNext();
     155             :   }
     156             : 
     157             :   static MachineSchedRegistry *getList() {
     158      113936 :     return (MachineSchedRegistry *)Registry.getList();
     159             :   }
     160             : 
     161             :   static void setListener(MachinePassRegistryListener *L) {
     162             :     Registry.setListener(L);
     163             :   }
     164             : };
     165             : 
     166             : class ScheduleDAGMI;
     167             : 
     168             : /// Define a generic scheduling policy for targets that don't provide their own
     169             : /// MachineSchedStrategy. This can be overriden for each scheduling region
     170             : /// before building the DAG.
     171             : struct MachineSchedPolicy {
     172             :   // Allow the scheduler to disable register pressure tracking.
     173             :   bool ShouldTrackPressure = false;
     174             :   /// Track LaneMasks to allow reordering of independent subregister writes
     175             :   /// of the same vreg. \sa MachineSchedStrategy::shouldTrackLaneMasks()
     176             :   bool ShouldTrackLaneMasks = false;
     177             : 
     178             :   // Allow the scheduler to force top-down or bottom-up scheduling. If neither
     179             :   // is true, the scheduler runs in both directions and converges.
     180             :   bool OnlyTopDown = false;
     181             :   bool OnlyBottomUp = false;
     182             : 
     183             :   // Disable heuristic that tries to fetch nodes from long dependency chains
     184             :   // first.
     185             :   bool DisableLatencyHeuristic = false;
     186             : 
     187      161522 :   MachineSchedPolicy() = default;
     188             : };
     189             : 
     190             : /// MachineSchedStrategy - Interface to the scheduling algorithm used by
     191             : /// ScheduleDAGMI.
     192             : ///
     193             : /// Initialization sequence:
     194             : ///   initPolicy -> shouldTrackPressure -> initialize(DAG) -> registerRoots
     195             : class MachineSchedStrategy {
     196             :   virtual void anchor();
     197             : 
     198             : public:
     199           0 :   virtual ~MachineSchedStrategy() = default;
     200             : 
     201             :   /// Optionally override the per-region scheduling policy.
     202        9442 :   virtual void initPolicy(MachineBasicBlock::iterator Begin,
     203             :                           MachineBasicBlock::iterator End,
     204        9442 :                           unsigned NumRegionInstrs) {}
     205             : 
     206           0 :   virtual void dumpPolicy() const {}
     207             : 
     208             :   /// Check if pressure tracking is needed before building the DAG and
     209             :   /// initializing this strategy. Called after initPolicy.
     210        9426 :   virtual bool shouldTrackPressure() const { return true; }
     211             : 
     212             :   /// Returns true if lanemasks should be tracked. LaneMask tracking is
     213             :   /// necessary to reorder independent subregister defs for the same vreg.
     214             :   /// This has to be enabled in combination with shouldTrackPressure().
     215        9426 :   virtual bool shouldTrackLaneMasks() const { return false; }
     216             : 
     217             :   // If this method returns true, handling of the scheduling regions
     218             :   // themselves (in case of a scheduling boundary in MBB) will be done
     219             :   // beginning with the topmost region of MBB.
     220      448283 :   virtual bool doMBBSchedRegionsTopDown() const { return false; }
     221             : 
     222             :   /// Initialize the strategy after building the DAG for a new region.
     223             :   virtual void initialize(ScheduleDAGMI *DAG) = 0;
     224             : 
     225             :   /// Tell the strategy that MBB is about to be processed.
     226      469017 :   virtual void enterMBB(MachineBasicBlock *MBB) {};
     227             : 
     228             :   /// Tell the strategy that current MBB is done.
     229      469709 :   virtual void leaveMBB() {};
     230             : 
     231             :   /// Notify this strategy that all roots have been released (including those
     232             :   /// that depend on EntrySU or ExitSU).
     233        8975 :   virtual void registerRoots() {}
     234             : 
     235             :   /// Pick the next node to schedule, or return NULL. Set IsTopNode to true to
     236             :   /// schedule the node at the top of the unscheduled region. Otherwise it will
     237             :   /// be scheduled at the bottom.
     238             :   virtual SUnit *pickNode(bool &IsTopNode) = 0;
     239             : 
     240             :   /// Scheduler callback to notify that a new subtree is scheduled.
     241           0 :   virtual void scheduleTree(unsigned SubtreeID) {}
     242             : 
     243             :   /// Notify MachineSchedStrategy that ScheduleDAGMI has scheduled an
     244             :   /// instruction and updated scheduled/remaining flags in the DAG nodes.
     245             :   virtual void schedNode(SUnit *SU, bool IsTopNode) = 0;
     246             : 
     247             :   /// When all predecessor dependencies have been resolved, free this node for
     248             :   /// top-down scheduling.
     249             :   virtual void releaseTopNode(SUnit *SU) = 0;
     250             : 
     251             :   /// When all successor dependencies have been resolved, free this node for
     252             :   /// bottom-up scheduling.
     253             :   virtual void releaseBottomNode(SUnit *SU) = 0;
     254             : };
     255             : 
     256             : /// ScheduleDAGMI is an implementation of ScheduleDAGInstrs that simply
     257             : /// schedules machine instructions according to the given MachineSchedStrategy
     258             : /// without much extra book-keeping. This is the common functionality between
     259             : /// PreRA and PostRA MachineScheduler.
     260      401476 : class ScheduleDAGMI : public ScheduleDAGInstrs {
     261             : protected:
     262             :   AliasAnalysis *AA;
     263             :   LiveIntervals *LIS;
     264             :   std::unique_ptr<MachineSchedStrategy> SchedImpl;
     265             : 
     266             :   /// Topo - A topological ordering for SUnits which permits fast IsReachable
     267             :   /// and similar queries.
     268             :   ScheduleDAGTopologicalSort Topo;
     269             : 
     270             :   /// Ordered list of DAG postprocessing steps.
     271             :   std::vector<std::unique_ptr<ScheduleDAGMutation>> Mutations;
     272             : 
     273             :   /// The top of the unscheduled zone.
     274             :   MachineBasicBlock::iterator CurrentTop;
     275             : 
     276             :   /// The bottom of the unscheduled zone.
     277             :   MachineBasicBlock::iterator CurrentBottom;
     278             : 
     279             :   /// Record the next node in a scheduled cluster.
     280             :   const SUnit *NextClusterPred = nullptr;
     281             :   const SUnit *NextClusterSucc = nullptr;
     282             : 
     283             : #ifndef NDEBUG
     284             :   /// The number of instructions scheduled so far. Used to cut off the
     285             :   /// scheduler at the point determined by misched-cutoff.
     286             :   unsigned NumInstrsScheduled = 0;
     287             : #endif
     288             : 
     289             : public:
     290      189529 :   ScheduleDAGMI(MachineSchedContext *C, std::unique_ptr<MachineSchedStrategy> S,
     291             :                 bool RemoveKillFlags)
     292      568587 :       : ScheduleDAGInstrs(*C->MF, C->MLI, RemoveKillFlags), AA(C->AA),
     293      189529 :         LIS(C->LIS), SchedImpl(std::move(S)), Topo(SUnits, &ExitSU) {}
     294             : 
     295             :   // Provide a vtable anchor
     296             :   ~ScheduleDAGMI() override;
     297             : 
     298             :   /// If this method returns true, handling of the scheduling regions
     299             :   /// themselves (in case of a scheduling boundary in MBB) will be done
     300             :   /// beginning with the topmost region of MBB.
     301      451711 :   bool doMBBSchedRegionsTopDown() const override {
     302      451711 :     return SchedImpl->doMBBSchedRegionsTopDown();
     303             :   }
     304             : 
     305             :   // Returns LiveIntervals instance for use in DAG mutators and such.
     306           0 :   LiveIntervals *getLIS() const { return LIS; }
     307             : 
     308             :   /// Return true if this DAG supports VReg liveness and RegPressure.
     309           0 :   virtual bool hasVRegLiveness() const { return false; }
     310             : 
     311             :   /// Add a postprocessing step to the DAG builder.
     312             :   /// Mutations are applied in the order that they are added after normal DAG
     313             :   /// building and before MachineSchedStrategy initialization.
     314             :   ///
     315             :   /// ScheduleDAGMI takes ownership of the Mutation object.
     316             :   void addMutation(std::unique_ptr<ScheduleDAGMutation> Mutation) {
     317      366517 :     if (Mutation)
     318      376354 :       Mutations.push_back(std::move(Mutation));
     319             :   }
     320             : 
     321             :   /// True if an edge can be added from PredSU to SuccSU without creating
     322             :   /// a cycle.
     323             :   bool canAddEdge(SUnit *SuccSU, SUnit *PredSU);
     324             : 
     325             :   /// Add a DAG edge to the given SU with the given predecessor
     326             :   /// dependence data.
     327             :   ///
     328             :   /// \returns true if the edge may be added without creating a cycle OR if an
     329             :   /// equivalent edge already existed (false indicates failure).
     330             :   bool addEdge(SUnit *SuccSU, const SDep &PredDep);
     331             : 
     332           0 :   MachineBasicBlock::iterator top() const { return CurrentTop; }
     333           0 :   MachineBasicBlock::iterator bottom() const { return CurrentBottom; }
     334             : 
     335             :   /// Implement the ScheduleDAGInstrs interface for handling the next scheduling
     336             :   /// region. This covers all instructions in a block, while schedule() may only
     337             :   /// cover a subset.
     338             :   void enterRegion(MachineBasicBlock *bb,
     339             :                    MachineBasicBlock::iterator begin,
     340             :                    MachineBasicBlock::iterator end,
     341             :                    unsigned regioninstrs) override;
     342             : 
     343             :   /// Implement ScheduleDAGInstrs interface for scheduling a sequence of
     344             :   /// reorderable instructions.
     345             :   void schedule() override;
     346             : 
     347             :   void startBlock(MachineBasicBlock *bb) override;
     348             :   void finishBlock() override;
     349             : 
     350             :   /// Change the position of an instruction within the basic block and update
     351             :   /// live ranges and region boundary iterators.
     352             :   void moveInstruction(MachineInstr *MI, MachineBasicBlock::iterator InsertPos);
     353             : 
     354           0 :   const SUnit *getNextClusterPred() const { return NextClusterPred; }
     355             : 
     356           0 :   const SUnit *getNextClusterSucc() const { return NextClusterSucc; }
     357             : 
     358             :   void viewGraph(const Twine &Name, const Twine &Title) override;
     359             :   void viewGraph() override;
     360             : 
     361             : protected:
     362             :   // Top-Level entry points for the schedule() driver...
     363             : 
     364             :   /// Apply each ScheduleDAGMutation step in order. This allows different
     365             :   /// instances of ScheduleDAGMI to perform custom DAG postprocessing.
     366             :   void postprocessDAG();
     367             : 
     368             :   /// Release ExitSU predecessors and setup scheduler queues.
     369             :   void initQueues(ArrayRef<SUnit*> TopRoots, ArrayRef<SUnit*> BotRoots);
     370             : 
     371             :   /// Update scheduler DAG and queues after scheduling an instruction.
     372             :   void updateQueues(SUnit *SU, bool IsTopNode);
     373             : 
     374             :   /// Reinsert debug_values recorded in ScheduleDAGInstrs::DbgValues.
     375             :   void placeDebugValues();
     376             : 
     377             :   /// dump the scheduled Sequence.
     378             :   void dumpSchedule() const;
     379             : 
     380             :   // Lesser helpers...
     381             :   bool checkSchedLimit();
     382             : 
     383             :   void findRootsAndBiasEdges(SmallVectorImpl<SUnit*> &TopRoots,
     384             :                              SmallVectorImpl<SUnit*> &BotRoots);
     385             : 
     386             :   void releaseSucc(SUnit *SU, SDep *SuccEdge);
     387             :   void releaseSuccessors(SUnit *SU);
     388             :   void releasePred(SUnit *SU, SDep *PredEdge);
     389             :   void releasePredecessors(SUnit *SU);
     390             : };
     391             : 
     392             : /// ScheduleDAGMILive is an implementation of ScheduleDAGInstrs that schedules
     393             : /// machine instructions while updating LiveIntervals and tracking regpressure.
     394             : class ScheduleDAGMILive : public ScheduleDAGMI {
     395             : protected:
     396             :   RegisterClassInfo *RegClassInfo;
     397             : 
     398             :   /// Information about DAG subtrees. If DFSResult is NULL, then SchedulerTrees
     399             :   /// will be empty.
     400             :   SchedDFSResult *DFSResult = nullptr;
     401             :   BitVector ScheduledTrees;
     402             : 
     403             :   MachineBasicBlock::iterator LiveRegionEnd;
     404             : 
     405             :   /// Maps vregs to the SUnits of their uses in the current scheduling region.
     406             :   VReg2SUnitMultiMap VRegUses;
     407             : 
     408             :   // Map each SU to its summary of pressure changes. This array is updated for
     409             :   // liveness during bottom-up scheduling. Top-down scheduling may proceed but
     410             :   // has no affect on the pressure diffs.
     411             :   PressureDiffs SUPressureDiffs;
     412             : 
     413             :   /// Register pressure in this region computed by initRegPressure.
     414             :   bool ShouldTrackPressure = false;
     415             :   bool ShouldTrackLaneMasks = false;
     416             :   IntervalPressure RegPressure;
     417             :   RegPressureTracker RPTracker;
     418             : 
     419             :   /// List of pressure sets that exceed the target's pressure limit before
     420             :   /// scheduling, listed in increasing set ID order. Each pressure set is paired
     421             :   /// with its max pressure in the currently scheduled regions.
     422             :   std::vector<PressureChange> RegionCriticalPSets;
     423             : 
     424             :   /// The top of the unscheduled zone.
     425             :   IntervalPressure TopPressure;
     426             :   RegPressureTracker TopRPTracker;
     427             : 
     428             :   /// The bottom of the unscheduled zone.
     429             :   IntervalPressure BotPressure;
     430             :   RegPressureTracker BotRPTracker;
     431             : 
     432             :   /// True if disconnected subregister components are already renamed.
     433             :   /// The renaming is only done on demand if lane masks are tracked.
     434             :   bool DisconnectedComponentsRenamed = false;
     435             : 
     436             : public:
     437      167111 :   ScheduleDAGMILive(MachineSchedContext *C,
     438             :                     std::unique_ptr<MachineSchedStrategy> S)
     439      167111 :       : ScheduleDAGMI(C, std::move(S), /*RemoveKillFlags=*/false),
     440      167111 :         RegClassInfo(C->RegClassInfo), RPTracker(RegPressure),
     441      334222 :         TopRPTracker(TopPressure), BotRPTracker(BotPressure) {}
     442             : 
     443             :   ~ScheduleDAGMILive() override;
     444             : 
     445             :   /// Return true if this DAG supports VReg liveness and RegPressure.
     446           0 :   bool hasVRegLiveness() const override { return true; }
     447             : 
     448             :   /// Return true if register pressure tracking is enabled.
     449           0 :   bool isTrackingPressure() const { return ShouldTrackPressure; }
     450             : 
     451             :   /// Get current register pressure for the top scheduled instructions.
     452             :   const IntervalPressure &getTopPressure() const { return TopPressure; }
     453      138672 :   const RegPressureTracker &getTopRPTracker() const { return TopRPTracker; }
     454             : 
     455             :   /// Get current register pressure for the bottom scheduled instructions.
     456             :   const IntervalPressure &getBotPressure() const { return BotPressure; }
     457     1366198 :   const RegPressureTracker &getBotRPTracker() const { return BotRPTracker; }
     458             : 
     459             :   /// Get register pressure for the entire scheduling region before scheduling.
     460             :   const IntervalPressure &getRegPressure() const { return RegPressure; }
     461             : 
     462             :   const std::vector<PressureChange> &getRegionCriticalPSets() const {
     463             :     return RegionCriticalPSets;
     464             :   }
     465             : 
     466           0 :   PressureDiff &getPressureDiff(const SUnit *SU) {
     467    12447090 :     return SUPressureDiffs[SU->NodeNum];
     468             :   }
     469             :   const PressureDiff &getPressureDiff(const SUnit *SU) const {
     470             :     return SUPressureDiffs[SU->NodeNum];
     471             :   }
     472             : 
     473             :   /// Compute a DFSResult after DAG building is complete, and before any
     474             :   /// queue comparisons.
     475             :   void computeDFSResult();
     476             : 
     477             :   /// Return a non-null DFS result if the scheduling strategy initialized it.
     478           0 :   const SchedDFSResult *getDFSResult() const { return DFSResult; }
     479             : 
     480          10 :   BitVector &getScheduledTrees() { return ScheduledTrees; }
     481             : 
     482             :   /// Implement the ScheduleDAGInstrs interface for handling the next scheduling
     483             :   /// region. This covers all instructions in a block, while schedule() may only
     484             :   /// cover a subset.
     485             :   void enterRegion(MachineBasicBlock *bb,
     486             :                    MachineBasicBlock::iterator begin,
     487             :                    MachineBasicBlock::iterator end,
     488             :                    unsigned regioninstrs) override;
     489             : 
     490             :   /// Implement ScheduleDAGInstrs interface for scheduling a sequence of
     491             :   /// reorderable instructions.
     492             :   void schedule() override;
     493             : 
     494             :   /// Compute the cyclic critical path through the DAG.
     495             :   unsigned computeCyclicCriticalPath();
     496             : 
     497             :   void dump() const override;
     498             : 
     499             : protected:
     500             :   // Top-Level entry points for the schedule() driver...
     501             : 
     502             :   /// Call ScheduleDAGInstrs::buildSchedGraph with register pressure tracking
     503             :   /// enabled. This sets up three trackers. RPTracker will cover the entire DAG
     504             :   /// region, TopTracker and BottomTracker will be initialized to the top and
     505             :   /// bottom of the DAG region without covereing any unscheduled instruction.
     506             :   void buildDAGWithRegPressure();
     507             : 
     508             :   /// Release ExitSU predecessors and setup scheduler queues. Re-position
     509             :   /// the Top RP tracker in case the region beginning has changed.
     510             :   void initQueues(ArrayRef<SUnit*> TopRoots, ArrayRef<SUnit*> BotRoots);
     511             : 
     512             :   /// Move an instruction and update register pressure.
     513             :   void scheduleMI(SUnit *SU, bool IsTopNode);
     514             : 
     515             :   // Lesser helpers...
     516             : 
     517             :   void initRegPressure();
     518             : 
     519             :   void updatePressureDiffs(ArrayRef<RegisterMaskPair> LiveUses);
     520             : 
     521             :   void updateScheduledPressure(const SUnit *SU,
     522             :                                const std::vector<unsigned> &NewMaxPressure);
     523             : 
     524             :   void collectVRegUses(SUnit &SU);
     525             : };
     526             : 
     527             : //===----------------------------------------------------------------------===//
     528             : ///
     529             : /// Helpers for implementing custom MachineSchedStrategy classes. These take
     530             : /// care of the book-keeping associated with list scheduling heuristics.
     531             : ///
     532             : //===----------------------------------------------------------------------===//
     533             : 
     534             : /// ReadyQueue encapsulates vector of "ready" SUnits with basic convenience
     535             : /// methods for pushing and removing nodes. ReadyQueue's are uniquely identified
     536             : /// by an ID. SUnit::NodeQueueId is a mask of the ReadyQueues the SUnit is in.
     537             : ///
     538             : /// This is a convenience class that may be used by implementations of
     539             : /// MachineSchedStrategy.
     540             : class ReadyQueue {
     541             :   unsigned ID;
     542             :   std::string Name;
     543             :   std::vector<SUnit*> Queue;
     544             : 
     545             : public:
     546      355616 :   ReadyQueue(unsigned id, const Twine &name): ID(id), Name(name.str()) {}
     547             : 
     548           0 :   unsigned getID() const { return ID; }
     549             : 
     550             :   StringRef getName() const { return Name; }
     551             : 
     552             :   // SU is in this queue if it's NodeQueueID is a superset of this ID.
     553     3775130 :   bool isInQueue(SUnit *SU) const { return (SU->NodeQueueId & ID); }
     554             : 
     555             :   bool empty() const { return Queue.empty(); }
     556             : 
     557             :   void clear() { Queue.clear(); }
     558             : 
     559    12220197 :   unsigned size() const { return Queue.size(); }
     560             : 
     561             :   using iterator = std::vector<SUnit*>::iterator;
     562             : 
     563             :   iterator begin() { return Queue.begin(); }
     564             : 
     565             :   iterator end() { return Queue.end(); }
     566             : 
     567             :   ArrayRef<SUnit*> elements() { return Queue; }
     568             : 
     569             :   iterator find(SUnit *SU) { return llvm::find(Queue, SU); }
     570             : 
     571             :   void push(SUnit *SU) {
     572     4117648 :     Queue.push_back(SU);
     573     4117648 :     SU->NodeQueueId |= ID;
     574             :   }
     575             : 
     576             :   iterator remove(iterator I) {
     577     4117638 :     (*I)->NodeQueueId &= ~ID;
     578     4117638 :     *I = Queue.back();
     579             :     unsigned idx = I - Queue.begin();
     580             :     Queue.pop_back();
     581             :     return Queue.begin() + idx;
     582             :   }
     583             : 
     584             :   void dump() const;
     585             : };
     586             : 
     587             : /// Summarize the unscheduled region.
     588             : struct SchedRemainder {
     589             :   // Critical path through the DAG in expected latency.
     590             :   unsigned CriticalPath;
     591             :   unsigned CyclicCritPath;
     592             : 
     593             :   // Scaled count of micro-ops left to schedule.
     594             :   unsigned RemIssueCount;
     595             : 
     596             :   bool IsAcyclicLatencyLimited;
     597             : 
     598             :   // Unscheduled resources
     599             :   SmallVector<unsigned, 16> RemainingCounts;
     600             : 
     601      180978 :   SchedRemainder() { reset(); }
     602             : 
     603             :   void reset() {
     604      624055 :     CriticalPath = 0;
     605      624055 :     CyclicCritPath = 0;
     606      624055 :     RemIssueCount = 0;
     607      462596 :     IsAcyclicLatencyLimited = false;
     608             :     RemainingCounts.clear();
     609             :   }
     610             : 
     611             :   void init(ScheduleDAGMI *DAG, const TargetSchedModel *SchedModel);
     612             : };
     613             : 
     614             : /// Each Scheduling boundary is associated with ready queues. It tracks the
     615             : /// current cycle in the direction of movement, and maintains the state
     616             : /// of "hazards" and other interlocks at the current cycle.
     617             : class SchedBoundary {
     618             : public:
     619             :   /// SUnit::NodeQueueId: 0 (none), 1 (top), 2 (bot), 3 (both)
     620             :   enum {
     621             :     TopQID = 1,
     622             :     BotQID = 2,
     623             :     LogMaxQID = 2
     624             :   };
     625             : 
     626             :   ScheduleDAGMI *DAG = nullptr;
     627             :   const TargetSchedModel *SchedModel = nullptr;
     628             :   SchedRemainder *Rem = nullptr;
     629             : 
     630             :   ReadyQueue Available;
     631             :   ReadyQueue Pending;
     632             : 
     633             :   ScheduleHazardRecognizer *HazardRec = nullptr;
     634             : 
     635             : private:
     636             :   /// True if the pending Q should be checked/updated before scheduling another
     637             :   /// instruction.
     638             :   bool CheckPending;
     639             : 
     640             :   /// Number of cycles it takes to issue the instructions scheduled in this
     641             :   /// zone. It is defined as: scheduled-micro-ops / issue-width + stalls.
     642             :   /// See getStalls().
     643             :   unsigned CurrCycle;
     644             : 
     645             :   /// Micro-ops issued in the current cycle
     646             :   unsigned CurrMOps;
     647             : 
     648             :   /// MinReadyCycle - Cycle of the soonest available instruction.
     649             :   unsigned MinReadyCycle;
     650             : 
     651             :   // The expected latency of the critical path in this scheduled zone.
     652             :   unsigned ExpectedLatency;
     653             : 
     654             :   // The latency of dependence chains leading into this zone.
     655             :   // For each node scheduled bottom-up: DLat = max DLat, N.Depth.
     656             :   // For each cycle scheduled: DLat -= 1.
     657             :   unsigned DependentLatency;
     658             : 
     659             :   /// Count the scheduled (issued) micro-ops that can be retired by
     660             :   /// time=CurrCycle assuming the first scheduled instr is retired at time=0.
     661             :   unsigned RetiredMOps;
     662             : 
     663             :   // Count scheduled resources that have been executed. Resources are
     664             :   // considered executed if they become ready in the time that it takes to
     665             :   // saturate any resource including the one in question. Counts are scaled
     666             :   // for direct comparison with other resources. Counts can be compared with
     667             :   // MOps * getMicroOpFactor and Latency * getLatencyFactor.
     668             :   SmallVector<unsigned, 16> ExecutedResCounts;
     669             : 
     670             :   /// Cache the max count for a single resource.
     671             :   unsigned MaxExecutedResCount;
     672             : 
     673             :   // Cache the critical resources ID in this scheduled zone.
     674             :   unsigned ZoneCritResIdx;
     675             : 
     676             :   // Is the scheduled region resource limited vs. latency limited.
     677             :   bool IsResourceLimited;
     678             : 
     679             :   // Record the highest cycle at which each resource has been reserved by a
     680             :   // scheduled instruction.
     681             :   SmallVector<unsigned, 16> ReservedCycles;
     682             : 
     683             : #ifndef NDEBUG
     684             :   // Remember the greatest possible stall as an upper bound on the number of
     685             :   // times we should retry the pending queue because of a hazard.
     686             :   unsigned MaxObservedStall;
     687             : #endif
     688             : 
     689             : public:
     690             :   /// Pending queues extend the ready queues with the same ID and the
     691             :   /// PendingFlag set.
     692      342500 :   SchedBoundary(unsigned ID, const Twine &Name):
     693      685000 :     Available(ID, Name+".A"), Pending(ID << LogMaxQID, Name+".P") {
     694      342500 :     reset();
     695      342500 :   }
     696             : 
     697             :   ~SchedBoundary();
     698             : 
     699             :   void reset();
     700             : 
     701             :   void init(ScheduleDAGMI *dag, const TargetSchedModel *smodel,
     702             :             SchedRemainder *rem);
     703             : 
     704             :   bool isTop() const {
     705    34754964 :     return Available.getID() == TopQID;
     706             :   }
     707             : 
     708             :   /// Number of cycles to issue the instructions scheduled in this zone.
     709           0 :   unsigned getCurrCycle() const { return CurrCycle; }
     710             : 
     711             :   /// Micro-ops issued in the current cycle
     712           0 :   unsigned getCurrMOps() const { return CurrMOps; }
     713             : 
     714             :   // The latency of dependence chains leading into this zone.
     715           0 :   unsigned getDependentLatency() const { return DependentLatency; }
     716             : 
     717             :   /// Get the number of latency cycles "covered" by the scheduled
     718             :   /// instructions. This is the larger of the critical path within the zone
     719             :   /// and the number of cycles required to issue the instructions.
     720             :   unsigned getScheduledLatency() const {
     721     5400546 :     return std::max(ExpectedLatency, CurrCycle);
     722             :   }
     723             : 
     724     4859960 :   unsigned getUnscheduledLatency(SUnit *SU) const {
     725     4859960 :     return isTop() ? SU->getHeight() : SU->getDepth();
     726             :   }
     727             : 
     728             :   unsigned getResourceCount(unsigned ResIdx) const {
     729    11214170 :     return ExecutedResCounts[ResIdx];
     730             :   }
     731             : 
     732             :   /// Get the scaled count of scheduled micro-ops and resources, including
     733             :   /// executed resources.
     734             :   unsigned getCriticalCount() const {
     735     5386322 :     if (!ZoneCritResIdx)
     736     3133751 :       return RetiredMOps * SchedModel->getMicroOpFactor();
     737             :     return getResourceCount(ZoneCritResIdx);
     738             :   }
     739             : 
     740             :   /// Get a scaled count for the minimum execution time of the scheduled
     741             :   /// micro-ops that are ready to execute by getExecutedCount. Notice the
     742             :   /// feedback loop.
     743             :   unsigned getExecutedCount() const {
     744             :     return std::max(CurrCycle * SchedModel->getLatencyFactor(),
     745             :                     MaxExecutedResCount);
     746             :   }
     747             : 
     748           0 :   unsigned getZoneCritResIdx() const { return ZoneCritResIdx; }
     749             : 
     750             :   // Is the scheduled region resource limited vs. latency limited.
     751           0 :   bool isResourceLimited() const { return IsResourceLimited; }
     752             : 
     753             :   /// Get the difference between the given SUnit's ready time and the current
     754             :   /// cycle.
     755             :   unsigned getLatencyStallCycles(SUnit *SU);
     756             : 
     757             :   unsigned getNextResourceCycle(unsigned PIdx, unsigned Cycles);
     758             : 
     759             :   bool checkHazard(SUnit *SU);
     760             : 
     761             :   unsigned findMaxLatency(ArrayRef<SUnit*> ReadySUs);
     762             : 
     763             :   unsigned getOtherResourceCount(unsigned &OtherCritIdx);
     764             : 
     765             :   void releaseNode(SUnit *SU, unsigned ReadyCycle);
     766             : 
     767             :   void bumpCycle(unsigned NextCycle);
     768             : 
     769             :   void incExecutedResources(unsigned PIdx, unsigned Count);
     770             : 
     771             :   unsigned countResource(unsigned PIdx, unsigned Cycles, unsigned ReadyCycle);
     772             : 
     773             :   void bumpNode(SUnit *SU);
     774             : 
     775             :   void releasePending();
     776             : 
     777             :   void removeReady(SUnit *SU);
     778             : 
     779             :   /// Call this before applying any other heuristics to the Available queue.
     780             :   /// Updates the Available/Pending Q's if necessary and returns the single
     781             :   /// available instruction, or NULL if there are multiple candidates.
     782             :   SUnit *pickOnlyChoice();
     783             : 
     784             :   void dumpScheduledState() const;
     785             : };
     786             : 
     787             : /// Base class for GenericScheduler. This class maintains information about
     788             : /// scheduling candidates based on TargetSchedModel making it easy to implement
     789             : /// heuristics for either preRA or postRA scheduling.
     790       19456 : class GenericSchedulerBase : public MachineSchedStrategy {
     791             : public:
     792             :   /// Represent the type of SchedCandidate found within a single queue.
     793             :   /// pickNodeBidirectional depends on these listed by decreasing priority.
     794             :   enum CandReason : uint8_t {
     795             :     NoCand, Only1, PhysRegCopy, RegExcess, RegCritical, Stall, Cluster, Weak,
     796             :     RegMax, ResourceReduce, ResourceDemand, BotHeightReduce, BotPathReduce,
     797             :     TopDepthReduce, TopPathReduce, NextDefUse, NodeOrder};
     798             : 
     799             : #ifndef NDEBUG
     800             :   static const char *getReasonStr(GenericSchedulerBase::CandReason Reason);
     801             : #endif
     802             : 
     803             :   /// Policy for scheduling the next instruction in the candidate's zone.
     804             :   struct CandPolicy {
     805             :     bool ReduceLatency = false;
     806             :     unsigned ReduceResIdx = 0;
     807             :     unsigned DemandResIdx = 0;
     808             : 
     809       26961 :     CandPolicy() = default;
     810             : 
     811             :     bool operator==(const CandPolicy &RHS) const {
     812      533441 :       return ReduceLatency == RHS.ReduceLatency &&
     813      276556 :              ReduceResIdx == RHS.ReduceResIdx &&
     814      256463 :              DemandResIdx == RHS.DemandResIdx;
     815             :     }
     816             :     bool operator!=(const CandPolicy &RHS) const {
     817             :       return !(*this == RHS);
     818             :     }
     819             :   };
     820             : 
     821             :   /// Status of an instruction's critical resource consumption.
     822             :   struct SchedResourceDelta {
     823             :     // Count critical resources in the scheduled region required by SU.
     824             :     unsigned CritResources = 0;
     825             : 
     826             :     // Count critical resources from another region consumed by SU.
     827             :     unsigned DemandedResources = 0;
     828             : 
     829             :     SchedResourceDelta() = default;
     830             : 
     831           0 :     bool operator==(const SchedResourceDelta &RHS) const {
     832           0 :       return CritResources == RHS.CritResources
     833     4396945 :         && DemandedResources == RHS.DemandedResources;
     834             :     }
     835             :     bool operator!=(const SchedResourceDelta &RHS) const {
     836             :       return !operator==(RHS);
     837             :     }
     838             :   };
     839             : 
     840             :   /// Store the state used by GenericScheduler heuristics, required for the
     841             :   /// lifetime of one invocation of pickNode().
     842             :   struct SchedCandidate {
     843             :     CandPolicy Policy;
     844             : 
     845             :     // The best SUnit candidate.
     846             :     SUnit *SU;
     847             : 
     848             :     // The reason for this candidate.
     849             :     CandReason Reason;
     850             : 
     851             :     // Whether this candidate should be scheduled at top/bottom.
     852             :     bool AtTop;
     853             : 
     854             :     // Register pressure values for the best candidate.
     855             :     RegPressureDelta RPDelta;
     856             : 
     857             :     // Critical resource consumption of the best candidate.
     858             :     SchedResourceDelta ResDelta;
     859             : 
     860      593411 :     SchedCandidate() { reset(CandPolicy()); }
     861    13849859 :     SchedCandidate(const CandPolicy &Policy) { reset(Policy); }
     862             : 
     863             :     void reset(const CandPolicy &NewPolicy) {
     864    15926336 :       Policy = NewPolicy;
     865    15806280 :       SU = nullptr;
     866    15926336 :       Reason = NoCand;
     867    15806280 :       AtTop = false;
     868    15926336 :       RPDelta = RegPressureDelta();
     869    15506905 :       ResDelta = SchedResourceDelta();
     870             :     }
     871             : 
     872           0 :     bool isValid() const { return SU; }
     873             : 
     874             :     // Copy the status of another candidate without changing policy.
     875             :     void setBest(SchedCandidate &Best) {
     876             :       assert(Best.Reason != NoCand && "uninitialized Sched candidate");
     877     4497458 :       SU = Best.SU;
     878     4456821 :       Reason = Best.Reason;
     879       40637 :       AtTop = Best.AtTop;
     880     4456821 :       RPDelta = Best.RPDelta;
     881     4456821 :       ResDelta = Best.ResDelta;
     882             :     }
     883             : 
     884             :     void initResourceDelta(const ScheduleDAGMI *DAG,
     885             :                            const TargetSchedModel *SchedModel);
     886             :   };
     887             : 
     888             : protected:
     889             :   const MachineSchedContext *Context;
     890             :   const TargetSchedModel *SchedModel = nullptr;
     891             :   const TargetRegisterInfo *TRI = nullptr;
     892             : 
     893             :   SchedRemainder Rem;
     894             : 
     895      180978 :   GenericSchedulerBase(const MachineSchedContext *C) : Context(C) {}
     896             : 
     897             :   void setPolicy(CandPolicy &Policy, bool IsPostRA, SchedBoundary &CurrZone,
     898             :                  SchedBoundary *OtherZone);
     899             : 
     900             : #ifndef NDEBUG
     901             :   void traceCandidate(const SchedCandidate &Cand);
     902             : #endif
     903             : 
     904             : private:
     905             :   bool shouldReduceLatency(const CandPolicy &Policy, SchedBoundary &CurrZone,
     906             :                            bool ComputeRemLatency, unsigned &RemLatency) const;
     907             : };
     908             : 
     909             : // Utility functions used by heuristics in tryCandidate().
     910             : bool tryLess(int TryVal, int CandVal,
     911             :              GenericSchedulerBase::SchedCandidate &TryCand,
     912             :              GenericSchedulerBase::SchedCandidate &Cand,
     913             :              GenericSchedulerBase::CandReason Reason);
     914             : bool tryGreater(int TryVal, int CandVal,
     915             :                 GenericSchedulerBase::SchedCandidate &TryCand,
     916             :                 GenericSchedulerBase::SchedCandidate &Cand,
     917             :                 GenericSchedulerBase::CandReason Reason);
     918             : bool tryLatency(GenericSchedulerBase::SchedCandidate &TryCand,
     919             :                 GenericSchedulerBase::SchedCandidate &Cand,
     920             :                 SchedBoundary &Zone);
     921             : bool tryPressure(const PressureChange &TryP,
     922             :                  const PressureChange &CandP,
     923             :                  GenericSchedulerBase::SchedCandidate &TryCand,
     924             :                  GenericSchedulerBase::SchedCandidate &Cand,
     925             :                  GenericSchedulerBase::CandReason Reason,
     926             :                  const TargetRegisterInfo *TRI,
     927             :                  const MachineFunction &MF);
     928             : unsigned getWeakLeft(const SUnit *SU, bool isTop);
     929             : int biasPhysRegCopy(const SUnit *SU, bool isTop);
     930             : 
     931             : /// GenericScheduler shrinks the unscheduled zone using heuristics to balance
     932             : /// the schedule.
     933             : class GenericScheduler : public GenericSchedulerBase {
     934             : public:
     935      161522 :   GenericScheduler(const MachineSchedContext *C):
     936             :     GenericSchedulerBase(C), Top(SchedBoundary::TopQID, "TopQ"),
     937      323044 :     Bot(SchedBoundary::BotQID, "BotQ") {}
     938             : 
     939             :   void initPolicy(MachineBasicBlock::iterator Begin,
     940             :                   MachineBasicBlock::iterator End,
     941             :                   unsigned NumRegionInstrs) override;
     942             : 
     943             :   void dumpPolicy() const override;
     944             : 
     945      970270 :   bool shouldTrackPressure() const override {
     946      970270 :     return RegionPolicy.ShouldTrackPressure;
     947             :   }
     948             : 
     949      970270 :   bool shouldTrackLaneMasks() const override {
     950      970270 :     return RegionPolicy.ShouldTrackLaneMasks;
     951             :   }
     952             : 
     953             :   void initialize(ScheduleDAGMI *dag) override;
     954             : 
     955             :   SUnit *pickNode(bool &IsTopNode) override;
     956             : 
     957             :   void schedNode(SUnit *SU, bool IsTopNode) override;
     958             : 
     959     1205657 :   void releaseTopNode(SUnit *SU) override {
     960     1205657 :     if (SU->isScheduled)
     961             :       return;
     962             : 
     963     1200146 :     Top.releaseNode(SU, SU->TopReadyCycle);
     964     1200146 :     TopCand.SU = nullptr;
     965             :   }
     966             : 
     967     2479065 :   void releaseBottomNode(SUnit *SU) override {
     968     2479065 :     if (SU->isScheduled)
     969             :       return;
     970             : 
     971     2447510 :     Bot.releaseNode(SU, SU->BotReadyCycle);
     972     2447510 :     BotCand.SU = nullptr;
     973             :   }
     974             : 
     975             :   void registerRoots() override;
     976             : 
     977             : protected:
     978             :   ScheduleDAGMILive *DAG = nullptr;
     979             : 
     980             :   MachineSchedPolicy RegionPolicy;
     981             : 
     982             :   // State of the top and bottom scheduled instruction boundaries.
     983             :   SchedBoundary Top;
     984             :   SchedBoundary Bot;
     985             : 
     986             :   /// Candidate last picked from Top boundary.
     987             :   SchedCandidate TopCand;
     988             :   /// Candidate last picked from Bot boundary.
     989             :   SchedCandidate BotCand;
     990             : 
     991             :   void checkAcyclicLatency();
     992             : 
     993             :   void initCandidate(SchedCandidate &Cand, SUnit *SU, bool AtTop,
     994             :                      const RegPressureTracker &RPTracker,
     995             :                      RegPressureTracker &TempTracker);
     996             : 
     997             :   virtual void tryCandidate(SchedCandidate &Cand, SchedCandidate &TryCand,
     998             :                             SchedBoundary *Zone) const;
     999             : 
    1000             :   SUnit *pickNodeBidirectional(bool &IsTopNode);
    1001             : 
    1002             :   void pickNodeFromQueue(SchedBoundary &Zone,
    1003             :                          const CandPolicy &ZonePolicy,
    1004             :                          const RegPressureTracker &RPTracker,
    1005             :                          SchedCandidate &Candidate);
    1006             : 
    1007             :   void reschedulePhysRegCopies(SUnit *SU, bool isTop);
    1008             : };
    1009             : 
    1010             : /// PostGenericScheduler - Interface to the scheduling algorithm used by
    1011             : /// ScheduleDAGMI.
    1012             : ///
    1013             : /// Callbacks from ScheduleDAGMI:
    1014             : ///   initPolicy -> initialize(DAG) -> registerRoots -> pickNode ...
    1015             : class PostGenericScheduler : public GenericSchedulerBase {
    1016             :   ScheduleDAGMI *DAG;
    1017             :   SchedBoundary Top;
    1018             :   SmallVector<SUnit*, 8> BotRoots;
    1019             : 
    1020             : public:
    1021       19456 :   PostGenericScheduler(const MachineSchedContext *C):
    1022       38912 :     GenericSchedulerBase(C), Top(SchedBoundary::TopQID, "TopQ") {}
    1023             : 
    1024       39049 :   ~PostGenericScheduler() override = default;
    1025             : 
    1026       37221 :   void initPolicy(MachineBasicBlock::iterator Begin,
    1027             :                   MachineBasicBlock::iterator End,
    1028             :                   unsigned NumRegionInstrs) override {
    1029             :     /* no configurable policy */
    1030       37221 :   }
    1031             : 
    1032             :   /// PostRA scheduling does not track pressure.
    1033           0 :   bool shouldTrackPressure() const override { return false; }
    1034             : 
    1035             :   void initialize(ScheduleDAGMI *Dag) override;
    1036             : 
    1037             :   void registerRoots() override;
    1038             : 
    1039             :   SUnit *pickNode(bool &IsTopNode) override;
    1040             : 
    1041           0 :   void scheduleTree(unsigned SubtreeID) override {
    1042           0 :     llvm_unreachable("PostRA scheduler does not support subtree analysis.");
    1043             :   }
    1044             : 
    1045             :   void schedNode(SUnit *SU, bool IsTopNode) override;
    1046             : 
    1047       85346 :   void releaseTopNode(SUnit *SU) override {
    1048       85346 :     if (SU->isScheduled)
    1049             :       return;
    1050       85346 :     Top.releaseNode(SU, SU->TopReadyCycle);
    1051             :   }
    1052             : 
    1053             :   // Only called for roots.
    1054       26374 :   void releaseBottomNode(SUnit *SU) override {
    1055       26374 :     BotRoots.push_back(SU);
    1056       26374 :   }
    1057             : 
    1058             : protected:
    1059             :   void tryCandidate(SchedCandidate &Cand, SchedCandidate &TryCand);
    1060             : 
    1061             :   void pickNodeFromQueue(SchedCandidate &Cand);
    1062             : };
    1063             : 
    1064             : /// Create the standard converging machine scheduler. This will be used as the
    1065             : /// default scheduler if the target does not set a default.
    1066             : /// Adds default DAG mutations.
    1067             : ScheduleDAGMILive *createGenericSchedLive(MachineSchedContext *C);
    1068             : 
    1069             : /// Create a generic scheduler with no vreg liveness or DAG mutation passes.
    1070             : ScheduleDAGMI *createGenericSchedPostRA(MachineSchedContext *C);
    1071             : 
    1072             : std::unique_ptr<ScheduleDAGMutation>
    1073             : createLoadClusterDAGMutation(const TargetInstrInfo *TII,
    1074             :                              const TargetRegisterInfo *TRI);
    1075             : 
    1076             : std::unique_ptr<ScheduleDAGMutation>
    1077             : createStoreClusterDAGMutation(const TargetInstrInfo *TII,
    1078             :                               const TargetRegisterInfo *TRI);
    1079             : 
    1080             : std::unique_ptr<ScheduleDAGMutation>
    1081             : createCopyConstrainDAGMutation(const TargetInstrInfo *TII,
    1082             :                                const TargetRegisterInfo *TRI);
    1083             : 
    1084             : } // end namespace llvm
    1085             : 
    1086             : #endif // LLVM_CODEGEN_MACHINESCHEDULER_H

Generated by: LCOV version 1.13