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