Home | History | Annotate | Download | only in CodeGen
      1 //===- MachineScheduler.cpp - Machine Instruction Scheduler ---------------===//
      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 // MachineScheduler schedules machine instructions after phi elimination. It
     11 // preserves LiveIntervals so it can be invoked before register allocation.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #define DEBUG_TYPE "misched"
     16 
     17 #include "llvm/CodeGen/LiveIntervalAnalysis.h"
     18 #include "llvm/CodeGen/MachineScheduler.h"
     19 #include "llvm/CodeGen/Passes.h"
     20 #include "llvm/CodeGen/ScheduleDAGInstrs.h"
     21 #include "llvm/Analysis/AliasAnalysis.h"
     22 #include "llvm/Target/TargetInstrInfo.h"
     23 #include "llvm/Support/CommandLine.h"
     24 #include "llvm/Support/Debug.h"
     25 #include "llvm/Support/ErrorHandling.h"
     26 #include "llvm/Support/raw_ostream.h"
     27 #include "llvm/ADT/OwningPtr.h"
     28 #include "llvm/ADT/PriorityQueue.h"
     29 
     30 #include <queue>
     31 
     32 using namespace llvm;
     33 
     34 static cl::opt<bool> ForceTopDown("misched-topdown", cl::Hidden,
     35                                   cl::desc("Force top-down list scheduling"));
     36 static cl::opt<bool> ForceBottomUp("misched-bottomup", cl::Hidden,
     37                                   cl::desc("Force bottom-up list scheduling"));
     38 
     39 #ifndef NDEBUG
     40 static cl::opt<bool> ViewMISchedDAGs("view-misched-dags", cl::Hidden,
     41   cl::desc("Pop up a window to show MISched dags after they are processed"));
     42 
     43 static cl::opt<unsigned> MISchedCutoff("misched-cutoff", cl::Hidden,
     44   cl::desc("Stop scheduling after N instructions"), cl::init(~0U));
     45 #else
     46 static bool ViewMISchedDAGs = false;
     47 #endif // NDEBUG
     48 
     49 //===----------------------------------------------------------------------===//
     50 // Machine Instruction Scheduling Pass and Registry
     51 //===----------------------------------------------------------------------===//
     52 
     53 namespace {
     54 /// MachineScheduler runs after coalescing and before register allocation.
     55 class MachineScheduler : public MachineSchedContext,
     56                          public MachineFunctionPass {
     57 public:
     58   MachineScheduler();
     59 
     60   virtual void getAnalysisUsage(AnalysisUsage &AU) const;
     61 
     62   virtual void releaseMemory() {}
     63 
     64   virtual bool runOnMachineFunction(MachineFunction&);
     65 
     66   virtual void print(raw_ostream &O, const Module* = 0) const;
     67 
     68   static char ID; // Class identification, replacement for typeinfo
     69 };
     70 } // namespace
     71 
     72 char MachineScheduler::ID = 0;
     73 
     74 char &llvm::MachineSchedulerID = MachineScheduler::ID;
     75 
     76 INITIALIZE_PASS_BEGIN(MachineScheduler, "misched",
     77                       "Machine Instruction Scheduler", false, false)
     78 INITIALIZE_AG_DEPENDENCY(AliasAnalysis)
     79 INITIALIZE_PASS_DEPENDENCY(SlotIndexes)
     80 INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
     81 INITIALIZE_PASS_END(MachineScheduler, "misched",
     82                     "Machine Instruction Scheduler", false, false)
     83 
     84 MachineScheduler::MachineScheduler()
     85 : MachineFunctionPass(ID) {
     86   initializeMachineSchedulerPass(*PassRegistry::getPassRegistry());
     87 }
     88 
     89 void MachineScheduler::getAnalysisUsage(AnalysisUsage &AU) const {
     90   AU.setPreservesCFG();
     91   AU.addRequiredID(MachineDominatorsID);
     92   AU.addRequired<MachineLoopInfo>();
     93   AU.addRequired<AliasAnalysis>();
     94   AU.addRequired<TargetPassConfig>();
     95   AU.addRequired<SlotIndexes>();
     96   AU.addPreserved<SlotIndexes>();
     97   AU.addRequired<LiveIntervals>();
     98   AU.addPreserved<LiveIntervals>();
     99   MachineFunctionPass::getAnalysisUsage(AU);
    100 }
    101 
    102 MachinePassRegistry MachineSchedRegistry::Registry;
    103 
    104 /// A dummy default scheduler factory indicates whether the scheduler
    105 /// is overridden on the command line.
    106 static ScheduleDAGInstrs *useDefaultMachineSched(MachineSchedContext *C) {
    107   return 0;
    108 }
    109 
    110 /// MachineSchedOpt allows command line selection of the scheduler.
    111 static cl::opt<MachineSchedRegistry::ScheduleDAGCtor, false,
    112                RegisterPassParser<MachineSchedRegistry> >
    113 MachineSchedOpt("misched",
    114                 cl::init(&useDefaultMachineSched), cl::Hidden,
    115                 cl::desc("Machine instruction scheduler to use"));
    116 
    117 static MachineSchedRegistry
    118 DefaultSchedRegistry("default", "Use the target's default scheduler choice.",
    119                      useDefaultMachineSched);
    120 
    121 /// Forward declare the standard machine scheduler. This will be used as the
    122 /// default scheduler if the target does not set a default.
    123 static ScheduleDAGInstrs *createConvergingSched(MachineSchedContext *C);
    124 
    125 /// Top-level MachineScheduler pass driver.
    126 ///
    127 /// Visit blocks in function order. Divide each block into scheduling regions
    128 /// and visit them bottom-up. Visiting regions bottom-up is not required, but is
    129 /// consistent with the DAG builder, which traverses the interior of the
    130 /// scheduling regions bottom-up.
    131 ///
    132 /// This design avoids exposing scheduling boundaries to the DAG builder,
    133 /// simplifying the DAG builder's support for "special" target instructions.
    134 /// At the same time the design allows target schedulers to operate across
    135 /// scheduling boundaries, for example to bundle the boudary instructions
    136 /// without reordering them. This creates complexity, because the target
    137 /// scheduler must update the RegionBegin and RegionEnd positions cached by
    138 /// ScheduleDAGInstrs whenever adding or removing instructions. A much simpler
    139 /// design would be to split blocks at scheduling boundaries, but LLVM has a
    140 /// general bias against block splitting purely for implementation simplicity.
    141 bool MachineScheduler::runOnMachineFunction(MachineFunction &mf) {
    142   // Initialize the context of the pass.
    143   MF = &mf;
    144   MLI = &getAnalysis<MachineLoopInfo>();
    145   MDT = &getAnalysis<MachineDominatorTree>();
    146   PassConfig = &getAnalysis<TargetPassConfig>();
    147   AA = &getAnalysis<AliasAnalysis>();
    148 
    149   LIS = &getAnalysis<LiveIntervals>();
    150   const TargetInstrInfo *TII = MF->getTarget().getInstrInfo();
    151 
    152   // Select the scheduler, or set the default.
    153   MachineSchedRegistry::ScheduleDAGCtor Ctor = MachineSchedOpt;
    154   if (Ctor == useDefaultMachineSched) {
    155     // Get the default scheduler set by the target.
    156     Ctor = MachineSchedRegistry::getDefault();
    157     if (!Ctor) {
    158       Ctor = createConvergingSched;
    159       MachineSchedRegistry::setDefault(Ctor);
    160     }
    161   }
    162   // Instantiate the selected scheduler.
    163   OwningPtr<ScheduleDAGInstrs> Scheduler(Ctor(this));
    164 
    165   // Visit all machine basic blocks.
    166   for (MachineFunction::iterator MBB = MF->begin(), MBBEnd = MF->end();
    167        MBB != MBBEnd; ++MBB) {
    168 
    169     Scheduler->startBlock(MBB);
    170 
    171     // Break the block into scheduling regions [I, RegionEnd), and schedule each
    172     // region as soon as it is discovered. RegionEnd points the the scheduling
    173     // boundary at the bottom of the region. The DAG does not include RegionEnd,
    174     // but the region does (i.e. the next RegionEnd is above the previous
    175     // RegionBegin). If the current block has no terminator then RegionEnd ==
    176     // MBB->end() for the bottom region.
    177     //
    178     // The Scheduler may insert instructions during either schedule() or
    179     // exitRegion(), even for empty regions. So the local iterators 'I' and
    180     // 'RegionEnd' are invalid across these calls.
    181     unsigned RemainingCount = MBB->size();
    182     for(MachineBasicBlock::iterator RegionEnd = MBB->end();
    183         RegionEnd != MBB->begin(); RegionEnd = Scheduler->begin()) {
    184       // Avoid decrementing RegionEnd for blocks with no terminator.
    185       if (RegionEnd != MBB->end()
    186           || TII->isSchedulingBoundary(llvm::prior(RegionEnd), MBB, *MF)) {
    187         --RegionEnd;
    188         // Count the boundary instruction.
    189         --RemainingCount;
    190       }
    191 
    192       // The next region starts above the previous region. Look backward in the
    193       // instruction stream until we find the nearest boundary.
    194       MachineBasicBlock::iterator I = RegionEnd;
    195       for(;I != MBB->begin(); --I, --RemainingCount) {
    196         if (TII->isSchedulingBoundary(llvm::prior(I), MBB, *MF))
    197           break;
    198       }
    199       // Notify the scheduler of the region, even if we may skip scheduling
    200       // it. Perhaps it still needs to be bundled.
    201       Scheduler->enterRegion(MBB, I, RegionEnd, RemainingCount);
    202 
    203       // Skip empty scheduling regions (0 or 1 schedulable instructions).
    204       if (I == RegionEnd || I == llvm::prior(RegionEnd)) {
    205         // Close the current region. Bundle the terminator if needed.
    206         // This invalidates 'RegionEnd' and 'I'.
    207         Scheduler->exitRegion();
    208         continue;
    209       }
    210       DEBUG(dbgs() << "MachineScheduling " << MF->getFunction()->getName()
    211             << ":BB#" << MBB->getNumber() << "\n  From: " << *I << "    To: ";
    212             if (RegionEnd != MBB->end()) dbgs() << *RegionEnd;
    213             else dbgs() << "End";
    214             dbgs() << " Remaining: " << RemainingCount << "\n");
    215 
    216       // Schedule a region: possibly reorder instructions.
    217       // This invalidates 'RegionEnd' and 'I'.
    218       Scheduler->schedule();
    219 
    220       // Close the current region.
    221       Scheduler->exitRegion();
    222 
    223       // Scheduling has invalidated the current iterator 'I'. Ask the
    224       // scheduler for the top of it's scheduled region.
    225       RegionEnd = Scheduler->begin();
    226     }
    227     assert(RemainingCount == 0 && "Instruction count mismatch!");
    228     Scheduler->finishBlock();
    229   }
    230   Scheduler->finalizeSchedule();
    231   DEBUG(LIS->print(dbgs()));
    232   return true;
    233 }
    234 
    235 void MachineScheduler::print(raw_ostream &O, const Module* m) const {
    236   // unimplemented
    237 }
    238 
    239 //===----------------------------------------------------------------------===//
    240 // MachineSchedStrategy - Interface to a machine scheduling algorithm.
    241 //===----------------------------------------------------------------------===//
    242 
    243 namespace {
    244 class ScheduleDAGMI;
    245 
    246 /// MachineSchedStrategy - Interface used by ScheduleDAGMI to drive the selected
    247 /// scheduling algorithm.
    248 ///
    249 /// If this works well and targets wish to reuse ScheduleDAGMI, we may expose it
    250 /// in ScheduleDAGInstrs.h
    251 class MachineSchedStrategy {
    252 public:
    253   virtual ~MachineSchedStrategy() {}
    254 
    255   /// Initialize the strategy after building the DAG for a new region.
    256   virtual void initialize(ScheduleDAGMI *DAG) = 0;
    257 
    258   /// Pick the next node to schedule, or return NULL. Set IsTopNode to true to
    259   /// schedule the node at the top of the unscheduled region. Otherwise it will
    260   /// be scheduled at the bottom.
    261   virtual SUnit *pickNode(bool &IsTopNode) = 0;
    262 
    263   /// When all predecessor dependencies have been resolved, free this node for
    264   /// top-down scheduling.
    265   virtual void releaseTopNode(SUnit *SU) = 0;
    266   /// When all successor dependencies have been resolved, free this node for
    267   /// bottom-up scheduling.
    268   virtual void releaseBottomNode(SUnit *SU) = 0;
    269 };
    270 } // namespace
    271 
    272 //===----------------------------------------------------------------------===//
    273 // ScheduleDAGMI - Base class for MachineInstr scheduling with LiveIntervals
    274 // preservation.
    275 //===----------------------------------------------------------------------===//
    276 
    277 namespace {
    278 /// ScheduleDAGMI is an implementation of ScheduleDAGInstrs that schedules
    279 /// machine instructions while updating LiveIntervals.
    280 class ScheduleDAGMI : public ScheduleDAGInstrs {
    281   AliasAnalysis *AA;
    282   MachineSchedStrategy *SchedImpl;
    283 
    284   /// The top of the unscheduled zone.
    285   MachineBasicBlock::iterator CurrentTop;
    286 
    287   /// The bottom of the unscheduled zone.
    288   MachineBasicBlock::iterator CurrentBottom;
    289 
    290   /// The number of instructions scheduled so far. Used to cut off the
    291   /// scheduler at the point determined by misched-cutoff.
    292   unsigned NumInstrsScheduled;
    293 public:
    294   ScheduleDAGMI(MachineSchedContext *C, MachineSchedStrategy *S):
    295     ScheduleDAGInstrs(*C->MF, *C->MLI, *C->MDT, /*IsPostRA=*/false, C->LIS),
    296     AA(C->AA), SchedImpl(S), CurrentTop(), CurrentBottom(),
    297     NumInstrsScheduled(0) {}
    298 
    299   ~ScheduleDAGMI() {
    300     delete SchedImpl;
    301   }
    302 
    303   MachineBasicBlock::iterator top() const { return CurrentTop; }
    304   MachineBasicBlock::iterator bottom() const { return CurrentBottom; }
    305 
    306   /// Implement ScheduleDAGInstrs interface.
    307   void schedule();
    308 
    309 protected:
    310   void moveInstruction(MachineInstr *MI, MachineBasicBlock::iterator InsertPos);
    311   bool checkSchedLimit();
    312 
    313   void releaseSucc(SUnit *SU, SDep *SuccEdge);
    314   void releaseSuccessors(SUnit *SU);
    315   void releasePred(SUnit *SU, SDep *PredEdge);
    316   void releasePredecessors(SUnit *SU);
    317 };
    318 } // namespace
    319 
    320 /// ReleaseSucc - Decrement the NumPredsLeft count of a successor. When
    321 /// NumPredsLeft reaches zero, release the successor node.
    322 void ScheduleDAGMI::releaseSucc(SUnit *SU, SDep *SuccEdge) {
    323   SUnit *SuccSU = SuccEdge->getSUnit();
    324 
    325 #ifndef NDEBUG
    326   if (SuccSU->NumPredsLeft == 0) {
    327     dbgs() << "*** Scheduling failed! ***\n";
    328     SuccSU->dump(this);
    329     dbgs() << " has been released too many times!\n";
    330     llvm_unreachable(0);
    331   }
    332 #endif
    333   --SuccSU->NumPredsLeft;
    334   if (SuccSU->NumPredsLeft == 0 && SuccSU != &ExitSU)
    335     SchedImpl->releaseTopNode(SuccSU);
    336 }
    337 
    338 /// releaseSuccessors - Call releaseSucc on each of SU's successors.
    339 void ScheduleDAGMI::releaseSuccessors(SUnit *SU) {
    340   for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end();
    341        I != E; ++I) {
    342     releaseSucc(SU, &*I);
    343   }
    344 }
    345 
    346 /// ReleasePred - Decrement the NumSuccsLeft count of a predecessor. When
    347 /// NumSuccsLeft reaches zero, release the predecessor node.
    348 void ScheduleDAGMI::releasePred(SUnit *SU, SDep *PredEdge) {
    349   SUnit *PredSU = PredEdge->getSUnit();
    350 
    351 #ifndef NDEBUG
    352   if (PredSU->NumSuccsLeft == 0) {
    353     dbgs() << "*** Scheduling failed! ***\n";
    354     PredSU->dump(this);
    355     dbgs() << " has been released too many times!\n";
    356     llvm_unreachable(0);
    357   }
    358 #endif
    359   --PredSU->NumSuccsLeft;
    360   if (PredSU->NumSuccsLeft == 0 && PredSU != &EntrySU)
    361     SchedImpl->releaseBottomNode(PredSU);
    362 }
    363 
    364 /// releasePredecessors - Call releasePred on each of SU's predecessors.
    365 void ScheduleDAGMI::releasePredecessors(SUnit *SU) {
    366   for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
    367        I != E; ++I) {
    368     releasePred(SU, &*I);
    369   }
    370 }
    371 
    372 void ScheduleDAGMI::moveInstruction(MachineInstr *MI,
    373                                     MachineBasicBlock::iterator InsertPos) {
    374   // Fix RegionBegin if the first instruction moves down.
    375   if (&*RegionBegin == MI)
    376     RegionBegin = llvm::next(RegionBegin);
    377   BB->splice(InsertPos, BB, MI);
    378   LIS->handleMove(MI);
    379   // Fix RegionBegin if another instruction moves above the first instruction.
    380   if (RegionBegin == InsertPos)
    381     RegionBegin = MI;
    382 }
    383 
    384 bool ScheduleDAGMI::checkSchedLimit() {
    385 #ifndef NDEBUG
    386   if (NumInstrsScheduled == MISchedCutoff && MISchedCutoff != ~0U) {
    387     CurrentTop = CurrentBottom;
    388     return false;
    389   }
    390   ++NumInstrsScheduled;
    391 #endif
    392   return true;
    393 }
    394 
    395 /// schedule - Called back from MachineScheduler::runOnMachineFunction
    396 /// after setting up the current scheduling region.
    397 void ScheduleDAGMI::schedule() {
    398   buildSchedGraph(AA);
    399 
    400   DEBUG(dbgs() << "********** MI Scheduling **********\n");
    401   DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su)
    402           SUnits[su].dumpAll(this));
    403 
    404   if (ViewMISchedDAGs) viewGraph();
    405 
    406   SchedImpl->initialize(this);
    407 
    408   // Release edges from the special Entry node or to the special Exit node.
    409   releaseSuccessors(&EntrySU);
    410   releasePredecessors(&ExitSU);
    411 
    412   // Release all DAG roots for scheduling.
    413   for (std::vector<SUnit>::iterator I = SUnits.begin(), E = SUnits.end();
    414        I != E; ++I) {
    415     // A SUnit is ready to top schedule if it has no predecessors.
    416     if (I->Preds.empty())
    417       SchedImpl->releaseTopNode(&(*I));
    418     // A SUnit is ready to bottom schedule if it has no successors.
    419     if (I->Succs.empty())
    420       SchedImpl->releaseBottomNode(&(*I));
    421   }
    422 
    423   CurrentTop = RegionBegin;
    424   CurrentBottom = RegionEnd;
    425   bool IsTopNode = false;
    426   while (SUnit *SU = SchedImpl->pickNode(IsTopNode)) {
    427     DEBUG(dbgs() << "*** " << (IsTopNode ? "Top" : "Bottom")
    428           << " Scheduling Instruction:\n"; SU->dump(this));
    429     if (!checkSchedLimit())
    430       break;
    431 
    432     // Move the instruction to its new location in the instruction stream.
    433     MachineInstr *MI = SU->getInstr();
    434 
    435     if (IsTopNode) {
    436       assert(SU->isTopReady() && "node still has unscheduled dependencies");
    437       if (&*CurrentTop == MI)
    438         ++CurrentTop;
    439       else
    440         moveInstruction(MI, CurrentTop);
    441       // Release dependent instructions for scheduling.
    442       releaseSuccessors(SU);
    443     }
    444     else {
    445       assert(SU->isBottomReady() && "node still has unscheduled dependencies");
    446       if (&*llvm::prior(CurrentBottom) == MI)
    447         --CurrentBottom;
    448       else {
    449         if (&*CurrentTop == MI)
    450           CurrentTop = llvm::next(CurrentTop);
    451         moveInstruction(MI, CurrentBottom);
    452         CurrentBottom = MI;
    453       }
    454       // Release dependent instructions for scheduling.
    455       releasePredecessors(SU);
    456     }
    457     SU->isScheduled = true;
    458   }
    459   assert(CurrentTop == CurrentBottom && "Nonempty unscheduled zone.");
    460 }
    461 
    462 //===----------------------------------------------------------------------===//
    463 // ConvergingScheduler - Implementation of the standard MachineSchedStrategy.
    464 //===----------------------------------------------------------------------===//
    465 
    466 namespace {
    467 /// ConvergingScheduler shrinks the unscheduled zone using heuristics to balance
    468 /// the schedule.
    469 class ConvergingScheduler : public MachineSchedStrategy {
    470   ScheduleDAGMI *DAG;
    471 
    472   unsigned NumTopReady;
    473   unsigned NumBottomReady;
    474 
    475 public:
    476   virtual void initialize(ScheduleDAGMI *dag) {
    477     DAG = dag;
    478 
    479     assert((!ForceTopDown || !ForceBottomUp) &&
    480            "-misched-topdown incompatible with -misched-bottomup");
    481   }
    482 
    483   virtual SUnit *pickNode(bool &IsTopNode) {
    484     if (DAG->top() == DAG->bottom())
    485       return NULL;
    486 
    487     // As an initial placeholder heuristic, schedule in the direction that has
    488     // the fewest choices.
    489     SUnit *SU;
    490     if (ForceTopDown || (!ForceBottomUp && NumTopReady <= NumBottomReady)) {
    491       SU = DAG->getSUnit(DAG->top());
    492       IsTopNode = true;
    493     }
    494     else {
    495       SU = DAG->getSUnit(llvm::prior(DAG->bottom()));
    496       IsTopNode = false;
    497     }
    498     if (SU->isTopReady()) {
    499       assert(NumTopReady > 0 && "bad ready count");
    500       --NumTopReady;
    501     }
    502     if (SU->isBottomReady()) {
    503       assert(NumBottomReady > 0 && "bad ready count");
    504       --NumBottomReady;
    505     }
    506     return SU;
    507   }
    508 
    509   virtual void releaseTopNode(SUnit *SU) {
    510     ++NumTopReady;
    511   }
    512   virtual void releaseBottomNode(SUnit *SU) {
    513     ++NumBottomReady;
    514   }
    515 };
    516 } // namespace
    517 
    518 /// Create the standard converging machine scheduler. This will be used as the
    519 /// default scheduler if the target does not set a default.
    520 static ScheduleDAGInstrs *createConvergingSched(MachineSchedContext *C) {
    521   assert((!ForceTopDown || !ForceBottomUp) &&
    522          "-misched-topdown incompatible with -misched-bottomup");
    523   return new ScheduleDAGMI(C, new ConvergingScheduler());
    524 }
    525 static MachineSchedRegistry
    526 ConvergingSchedRegistry("converge", "Standard converging scheduler.",
    527                         createConvergingSched);
    528 
    529 //===----------------------------------------------------------------------===//
    530 // Machine Instruction Shuffler for Correctness Testing
    531 //===----------------------------------------------------------------------===//
    532 
    533 #ifndef NDEBUG
    534 namespace {
    535 /// Apply a less-than relation on the node order, which corresponds to the
    536 /// instruction order prior to scheduling. IsReverse implements greater-than.
    537 template<bool IsReverse>
    538 struct SUnitOrder {
    539   bool operator()(SUnit *A, SUnit *B) const {
    540     if (IsReverse)
    541       return A->NodeNum > B->NodeNum;
    542     else
    543       return A->NodeNum < B->NodeNum;
    544   }
    545 };
    546 
    547 /// Reorder instructions as much as possible.
    548 class InstructionShuffler : public MachineSchedStrategy {
    549   bool IsAlternating;
    550   bool IsTopDown;
    551 
    552   // Using a less-than relation (SUnitOrder<false>) for the TopQ priority
    553   // gives nodes with a higher number higher priority causing the latest
    554   // instructions to be scheduled first.
    555   PriorityQueue<SUnit*, std::vector<SUnit*>, SUnitOrder<false> >
    556     TopQ;
    557   // When scheduling bottom-up, use greater-than as the queue priority.
    558   PriorityQueue<SUnit*, std::vector<SUnit*>, SUnitOrder<true> >
    559     BottomQ;
    560 public:
    561   InstructionShuffler(bool alternate, bool topdown)
    562     : IsAlternating(alternate), IsTopDown(topdown) {}
    563 
    564   virtual void initialize(ScheduleDAGMI *) {
    565     TopQ.clear();
    566     BottomQ.clear();
    567   }
    568 
    569   /// Implement MachineSchedStrategy interface.
    570   /// -----------------------------------------
    571 
    572   virtual SUnit *pickNode(bool &IsTopNode) {
    573     SUnit *SU;
    574     if (IsTopDown) {
    575       do {
    576         if (TopQ.empty()) return NULL;
    577         SU = TopQ.top();
    578         TopQ.pop();
    579       } while (SU->isScheduled);
    580       IsTopNode = true;
    581     }
    582     else {
    583       do {
    584         if (BottomQ.empty()) return NULL;
    585         SU = BottomQ.top();
    586         BottomQ.pop();
    587       } while (SU->isScheduled);
    588       IsTopNode = false;
    589     }
    590     if (IsAlternating)
    591       IsTopDown = !IsTopDown;
    592     return SU;
    593   }
    594 
    595   virtual void releaseTopNode(SUnit *SU) {
    596     TopQ.push(SU);
    597   }
    598   virtual void releaseBottomNode(SUnit *SU) {
    599     BottomQ.push(SU);
    600   }
    601 };
    602 } // namespace
    603 
    604 static ScheduleDAGInstrs *createInstructionShuffler(MachineSchedContext *C) {
    605   bool Alternate = !ForceTopDown && !ForceBottomUp;
    606   bool TopDown = !ForceBottomUp;
    607   assert((TopDown || !ForceTopDown) &&
    608          "-misched-topdown incompatible with -misched-bottomup");
    609   return new ScheduleDAGMI(C, new InstructionShuffler(Alternate, TopDown));
    610 }
    611 static MachineSchedRegistry ShufflerRegistry(
    612   "shuffle", "Shuffle machine instructions alternating directions",
    613   createInstructionShuffler);
    614 #endif // !NDEBUG
    615