Index: include/llvm/CodeGen/MachineScheduler.h =================================================================== --- include/llvm/CodeGen/MachineScheduler.h +++ include/llvm/CodeGen/MachineScheduler.h @@ -339,6 +339,12 @@ protected: // Top-Level entry points for the schedule() driver... + // Build the scheduling DAG. + virtual void buildDAG() { buildSchedGraph(AA); }; + + /// Move an instruction and update state. + virtual void scheduleMI(SUnit *SU, bool IsTopNode); + /// Apply each ScheduleDAGMutation step in order. This allows different /// instances of ScheduleDAGMI to perform custom DAG postprocessing. void postprocessDAG(); @@ -464,10 +470,6 @@ MachineBasicBlock::iterator end, unsigned regioninstrs) override; - /// Implement ScheduleDAGInstrs interface for scheduling a sequence of - /// reorderable instructions. - void schedule() override; - /// Compute the cyclic critical path through the DAG. unsigned computeCyclicCriticalPath(); @@ -478,14 +480,14 @@ /// enabled. This sets up three trackers. RPTracker will cover the entire DAG /// region, TopTracker and BottomTracker will be initialized to the top and /// bottom of the DAG region without covereing any unscheduled instruction. - void buildDAGWithRegPressure(); + void buildDAG() override; /// Release ExitSU predecessors and setup scheduler queues. Re-position /// the Top RP tracker in case the region beginning has changed. void initQueues(ArrayRef TopRoots, ArrayRef BotRoots); /// Move an instruction and update register pressure. - void scheduleMI(SUnit *SU, bool IsTopNode); + void scheduleMI(SUnit *SU, bool IsTopNode) override; // Lesser helpers... Index: lib/CodeGen/MachineScheduler.cpp =================================================================== --- lib/CodeGen/MachineScheduler.cpp +++ lib/CodeGen/MachineScheduler.cpp @@ -662,16 +662,43 @@ return true; } +void ScheduleDAGMI::scheduleMI(SUnit *SU, bool IsTopNode) { + MachineInstr *MI = SU->getInstr(); + if (IsTopNode) { + assert(SU->isTopReady() && "node still has unscheduled dependencies"); + if (&*CurrentTop == MI) + CurrentTop = nextIfDebug(++CurrentTop, CurrentBottom); + else + moveInstruction(MI, CurrentTop); + } else { + assert(SU->isBottomReady() && "node still has unscheduled dependencies"); + MachineBasicBlock::iterator priorII = + priorNonDebug(CurrentBottom, CurrentTop); + if (&*priorII == MI) + CurrentBottom = priorII; + else { + if (&*CurrentTop == MI) + CurrentTop = nextIfDebug(++CurrentTop, priorII); + moveInstruction(MI, CurrentBottom); + CurrentBottom = MI; + } + } +} + /// Per-region scheduling driver, called back from -/// MachineScheduler::runOnMachineFunction. This is a simplified driver that -/// does not consider liveness or register pressure. It is useful for PostRA -/// scheduling and potentially other custom schedulers. +/// MachineScheduler::runOnMachineFunction +/// This is a skeletal driver, with all the functionality pushed into helpers, +/// so that it can be easily extended by experimental schedulers. Generally, +/// implementing MachineSchedStrategy should be sufficient to implement a new +/// scheduling algorithm. However, if a scheduler further subclasses +/// ScheduleDAGMI then it will want to override this virtual method in order +/// to update any specialized state. void ScheduleDAGMI::schedule() { DEBUG(dbgs() << "ScheduleDAGMI::schedule starting\n"); DEBUG(SchedImpl->dumpPolicy()); // Build the DAG. - buildSchedGraph(AA); + buildDAG(); Topo.InitDAGTopologicalSorting(); @@ -687,8 +714,9 @@ DEBUG( if (EntrySU.getInstr() != nullptr) EntrySU.dumpAll(this); - for (unsigned su = 0, e = SUnits.size(); su != e; ++su) - SUnits[su].dumpAll(this); + for (const SUnit &SU : SUnits) { + SU.dumpAll(this); + } if (ExitSU.getInstr() != nullptr) ExitSU.dumpAll(this); ); @@ -707,26 +735,8 @@ if (!checkSchedLimit()) break; - MachineInstr *MI = SU->getInstr(); - if (IsTopNode) { - assert(SU->isTopReady() && "node still has unscheduled dependencies"); - if (&*CurrentTop == MI) - CurrentTop = nextIfDebug(++CurrentTop, CurrentBottom); - else - moveInstruction(MI, CurrentTop); - } else { - assert(SU->isBottomReady() && "node still has unscheduled dependencies"); - MachineBasicBlock::iterator priorII = - priorNonDebug(CurrentBottom, CurrentTop); - if (&*priorII == MI) - CurrentBottom = priorII; - else { - if (&*CurrentTop == MI) - CurrentTop = nextIfDebug(++CurrentTop, priorII); - moveInstruction(MI, CurrentBottom); - CurrentBottom = MI; - } - } + scheduleMI(SU, IsTopNode); + // Notify the scheduling strategy before updating the DAG. // This sets the scheduled node's ReadyCycle to CurrCycle. When updateQueues // runs, it can then use the accurate ReadyCycle time to determine whether @@ -1101,91 +1111,8 @@ } } -/// schedule - Called back from MachineScheduler::runOnMachineFunction -/// after setting up the current scheduling region. [RegionBegin, RegionEnd) -/// only includes instructions that have DAG nodes, not scheduling boundaries. -/// -/// This is a skeletal driver, with all the functionality pushed into helpers, -/// so that it can be easily extended by experimental schedulers. Generally, -/// implementing MachineSchedStrategy should be sufficient to implement a new -/// scheduling algorithm. However, if a scheduler further subclasses -/// ScheduleDAGMILive then it will want to override this virtual method in order -/// to update any specialized state. -void ScheduleDAGMILive::schedule() { - DEBUG(dbgs() << "ScheduleDAGMILive::schedule starting\n"); - DEBUG(SchedImpl->dumpPolicy()); - buildDAGWithRegPressure(); - - Topo.InitDAGTopologicalSorting(); - - postprocessDAG(); - - SmallVector TopRoots, BotRoots; - findRootsAndBiasEdges(TopRoots, BotRoots); - - // Initialize the strategy before modifying the DAG. - // This may initialize a DFSResult to be used for queue priority. - SchedImpl->initialize(this); - - DEBUG( - if (EntrySU.getInstr() != nullptr) - EntrySU.dumpAll(this); - for (const SUnit &SU : SUnits) { - SU.dumpAll(this); - if (ShouldTrackPressure) { - dbgs() << " Pressure Diff : "; - getPressureDiff(&SU).dump(*TRI); - } - dbgs() << '\n'; - } - if (ExitSU.getInstr() != nullptr) - ExitSU.dumpAll(this); - ); - if (ViewMISchedDAGs) viewGraph(); - - // Initialize ready queues now that the DAG and priority data are finalized. - initQueues(TopRoots, BotRoots); - - bool IsTopNode = false; - while (true) { - DEBUG(dbgs() << "** ScheduleDAGMILive::schedule picking next node\n"); - SUnit *SU = SchedImpl->pickNode(IsTopNode); - if (!SU) break; - - assert(!SU->isScheduled && "Node already scheduled"); - if (!checkSchedLimit()) - break; - - scheduleMI(SU, IsTopNode); - - if (DFSResult) { - unsigned SubtreeID = DFSResult->getSubtreeID(SU); - if (!ScheduledTrees.test(SubtreeID)) { - ScheduledTrees.set(SubtreeID); - DFSResult->scheduleTree(SubtreeID); - SchedImpl->scheduleTree(SubtreeID); - } - } - - // Notify the scheduling strategy after updating the DAG. - SchedImpl->schedNode(SU, IsTopNode); - - updateQueues(SU, IsTopNode); - } - assert(CurrentTop == CurrentBottom && "Nonempty unscheduled zone."); - - placeDebugValues(); - - DEBUG({ - unsigned BBNum = begin()->getParent()->getNumber(); - dbgs() << "*** Final schedule for BB#" << BBNum << " ***\n"; - dumpSchedule(); - dbgs() << '\n'; - }); -} - /// Build the DAG and setup three register pressure trackers. -void ScheduleDAGMILive::buildDAGWithRegPressure() { +void ScheduleDAGMILive::buildDAG() { if (!ShouldTrackPressure) { RPTracker.reset(); RegionCriticalPSets.clear(); @@ -1206,6 +1133,15 @@ // Initialize top/bottom trackers after computing region pressure. initRegPressure(); + + DEBUG( + for (const SUnit &SU : SUnits) { + SU.dumpAll(this); + dbgs() << " Pressure Diff : "; + getPressureDiff(&SU).dump(*TRI); + } + dbgs() << '\n'; + ); } void ScheduleDAGMILive::computeDFSResult() { @@ -1389,6 +1325,15 @@ updatePressureDiffs(LiveUses); } } + + if (DFSResult) { + unsigned SubtreeID = DFSResult->getSubtreeID(SU); + if (!ScheduledTrees.test(SubtreeID)) { + ScheduledTrees.set(SubtreeID); + DFSResult->scheduleTree(SubtreeID); + SchedImpl->scheduleTree(SubtreeID); + } + } } //===----------------------------------------------------------------------===// Index: lib/Target/AMDGPU/SIMachineScheduler.cpp =================================================================== --- lib/Target/AMDGPU/SIMachineScheduler.cpp +++ lib/Target/AMDGPU/SIMachineScheduler.cpp @@ -1792,7 +1792,7 @@ SIScheduleBlockResult Best, Temp; DEBUG(dbgs() << "Preparing Scheduling\n"); - buildDAGWithRegPressure(); + buildDAG(); DEBUG( for(SUnit& SU : SUnits) SU.dumpAll(this) Index: lib/Target/Hexagon/HexagonMachineScheduler.cpp =================================================================== --- lib/Target/Hexagon/HexagonMachineScheduler.cpp +++ lib/Target/Hexagon/HexagonMachineScheduler.cpp @@ -259,7 +259,7 @@ << " at loop depth " << MLI->getLoopDepth(BB) << " \n"); - buildDAGWithRegPressure(); + buildDAG(); SmallVector TopRoots, BotRoots; findRootsAndBiasEdges(TopRoots, BotRoots);