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 DEBUG(LIS->print(dbgs())); 231 return true; 232 } 233 234 void MachineScheduler::print(raw_ostream &O, const Module* m) const { 235 // unimplemented 236 } 237 238 //===----------------------------------------------------------------------===// 239 // MachineSchedStrategy - Interface to a machine scheduling algorithm. 240 //===----------------------------------------------------------------------===// 241 242 namespace { 243 class ScheduleDAGMI; 244 245 /// MachineSchedStrategy - Interface used by ScheduleDAGMI to drive the selected 246 /// scheduling algorithm. 247 /// 248 /// If this works well and targets wish to reuse ScheduleDAGMI, we may expose it 249 /// in ScheduleDAGInstrs.h 250 class MachineSchedStrategy { 251 public: 252 virtual ~MachineSchedStrategy() {} 253 254 /// Initialize the strategy after building the DAG for a new region. 255 virtual void initialize(ScheduleDAGMI *DAG) = 0; 256 257 /// Pick the next node to schedule, or return NULL. Set IsTopNode to true to 258 /// schedule the node at the top of the unscheduled region. Otherwise it will 259 /// be scheduled at the bottom. 260 virtual SUnit *pickNode(bool &IsTopNode) = 0; 261 262 /// When all predecessor dependencies have been resolved, free this node for 263 /// top-down scheduling. 264 virtual void releaseTopNode(SUnit *SU) = 0; 265 /// When all successor dependencies have been resolved, free this node for 266 /// bottom-up scheduling. 267 virtual void releaseBottomNode(SUnit *SU) = 0; 268 }; 269 } // namespace 270 271 //===----------------------------------------------------------------------===// 272 // ScheduleDAGMI - Base class for MachineInstr scheduling with LiveIntervals 273 // preservation. 274 //===----------------------------------------------------------------------===// 275 276 namespace { 277 /// ScheduleDAGMI is an implementation of ScheduleDAGInstrs that schedules 278 /// machine instructions while updating LiveIntervals. 279 class ScheduleDAGMI : public ScheduleDAGInstrs { 280 AliasAnalysis *AA; 281 MachineSchedStrategy *SchedImpl; 282 283 /// The top of the unscheduled zone. 284 MachineBasicBlock::iterator CurrentTop; 285 286 /// The bottom of the unscheduled zone. 287 MachineBasicBlock::iterator CurrentBottom; 288 289 /// The number of instructions scheduled so far. Used to cut off the 290 /// scheduler at the point determined by misched-cutoff. 291 unsigned NumInstrsScheduled; 292 public: 293 ScheduleDAGMI(MachineSchedContext *C, MachineSchedStrategy *S): 294 ScheduleDAGInstrs(*C->MF, *C->MLI, *C->MDT, /*IsPostRA=*/false, C->LIS), 295 AA(C->AA), SchedImpl(S), CurrentTop(), CurrentBottom(), 296 NumInstrsScheduled(0) {} 297 298 ~ScheduleDAGMI() { 299 delete SchedImpl; 300 } 301 302 MachineBasicBlock::iterator top() const { return CurrentTop; } 303 MachineBasicBlock::iterator bottom() const { return CurrentBottom; } 304 305 /// Implement ScheduleDAGInstrs interface. 306 void schedule(); 307 308 protected: 309 void moveInstruction(MachineInstr *MI, MachineBasicBlock::iterator InsertPos); 310 bool checkSchedLimit(); 311 312 void releaseSucc(SUnit *SU, SDep *SuccEdge); 313 void releaseSuccessors(SUnit *SU); 314 void releasePred(SUnit *SU, SDep *PredEdge); 315 void releasePredecessors(SUnit *SU); 316 }; 317 } // namespace 318 319 /// ReleaseSucc - Decrement the NumPredsLeft count of a successor. When 320 /// NumPredsLeft reaches zero, release the successor node. 321 void ScheduleDAGMI::releaseSucc(SUnit *SU, SDep *SuccEdge) { 322 SUnit *SuccSU = SuccEdge->getSUnit(); 323 324 #ifndef NDEBUG 325 if (SuccSU->NumPredsLeft == 0) { 326 dbgs() << "*** Scheduling failed! ***\n"; 327 SuccSU->dump(this); 328 dbgs() << " has been released too many times!\n"; 329 llvm_unreachable(0); 330 } 331 #endif 332 --SuccSU->NumPredsLeft; 333 if (SuccSU->NumPredsLeft == 0 && SuccSU != &ExitSU) 334 SchedImpl->releaseTopNode(SuccSU); 335 } 336 337 /// releaseSuccessors - Call releaseSucc on each of SU's successors. 338 void ScheduleDAGMI::releaseSuccessors(SUnit *SU) { 339 for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); 340 I != E; ++I) { 341 releaseSucc(SU, &*I); 342 } 343 } 344 345 /// ReleasePred - Decrement the NumSuccsLeft count of a predecessor. When 346 /// NumSuccsLeft reaches zero, release the predecessor node. 347 void ScheduleDAGMI::releasePred(SUnit *SU, SDep *PredEdge) { 348 SUnit *PredSU = PredEdge->getSUnit(); 349 350 #ifndef NDEBUG 351 if (PredSU->NumSuccsLeft == 0) { 352 dbgs() << "*** Scheduling failed! ***\n"; 353 PredSU->dump(this); 354 dbgs() << " has been released too many times!\n"; 355 llvm_unreachable(0); 356 } 357 #endif 358 --PredSU->NumSuccsLeft; 359 if (PredSU->NumSuccsLeft == 0 && PredSU != &EntrySU) 360 SchedImpl->releaseBottomNode(PredSU); 361 } 362 363 /// releasePredecessors - Call releasePred on each of SU's predecessors. 364 void ScheduleDAGMI::releasePredecessors(SUnit *SU) { 365 for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); 366 I != E; ++I) { 367 releasePred(SU, &*I); 368 } 369 } 370 371 void ScheduleDAGMI::moveInstruction(MachineInstr *MI, 372 MachineBasicBlock::iterator InsertPos) { 373 // Fix RegionBegin if the first instruction moves down. 374 if (&*RegionBegin == MI) 375 RegionBegin = llvm::next(RegionBegin); 376 BB->splice(InsertPos, BB, MI); 377 LIS->handleMove(MI); 378 // Fix RegionBegin if another instruction moves above the first instruction. 379 if (RegionBegin == InsertPos) 380 RegionBegin = MI; 381 } 382 383 bool ScheduleDAGMI::checkSchedLimit() { 384 #ifndef NDEBUG 385 if (NumInstrsScheduled == MISchedCutoff && MISchedCutoff != ~0U) { 386 CurrentTop = CurrentBottom; 387 return false; 388 } 389 ++NumInstrsScheduled; 390 #endif 391 return true; 392 } 393 394 /// schedule - Called back from MachineScheduler::runOnMachineFunction 395 /// after setting up the current scheduling region. 396 void ScheduleDAGMI::schedule() { 397 buildSchedGraph(AA); 398 399 DEBUG(dbgs() << "********** MI Scheduling **********\n"); 400 DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su) 401 SUnits[su].dumpAll(this)); 402 403 if (ViewMISchedDAGs) viewGraph(); 404 405 SchedImpl->initialize(this); 406 407 // Release edges from the special Entry node or to the special Exit node. 408 releaseSuccessors(&EntrySU); 409 releasePredecessors(&ExitSU); 410 411 // Release all DAG roots for scheduling. 412 for (std::vector<SUnit>::iterator I = SUnits.begin(), E = SUnits.end(); 413 I != E; ++I) { 414 // A SUnit is ready to top schedule if it has no predecessors. 415 if (I->Preds.empty()) 416 SchedImpl->releaseTopNode(&(*I)); 417 // A SUnit is ready to bottom schedule if it has no successors. 418 if (I->Succs.empty()) 419 SchedImpl->releaseBottomNode(&(*I)); 420 } 421 422 CurrentTop = RegionBegin; 423 CurrentBottom = RegionEnd; 424 bool IsTopNode = false; 425 while (SUnit *SU = SchedImpl->pickNode(IsTopNode)) { 426 DEBUG(dbgs() << "*** " << (IsTopNode ? "Top" : "Bottom") 427 << " Scheduling Instruction:\n"; SU->dump(this)); 428 if (!checkSchedLimit()) 429 break; 430 431 // Move the instruction to its new location in the instruction stream. 432 MachineInstr *MI = SU->getInstr(); 433 434 if (IsTopNode) { 435 assert(SU->isTopReady() && "node still has unscheduled dependencies"); 436 if (&*CurrentTop == MI) 437 ++CurrentTop; 438 else 439 moveInstruction(MI, CurrentTop); 440 // Release dependent instructions for scheduling. 441 releaseSuccessors(SU); 442 } 443 else { 444 assert(SU->isBottomReady() && "node still has unscheduled dependencies"); 445 if (&*llvm::prior(CurrentBottom) == MI) 446 --CurrentBottom; 447 else { 448 if (&*CurrentTop == MI) 449 CurrentTop = llvm::next(CurrentTop); 450 moveInstruction(MI, CurrentBottom); 451 CurrentBottom = MI; 452 } 453 // Release dependent instructions for scheduling. 454 releasePredecessors(SU); 455 } 456 SU->isScheduled = true; 457 } 458 assert(CurrentTop == CurrentBottom && "Nonempty unscheduled zone."); 459 } 460 461 //===----------------------------------------------------------------------===// 462 // ConvergingScheduler - Implementation of the standard MachineSchedStrategy. 463 //===----------------------------------------------------------------------===// 464 465 namespace { 466 /// ConvergingScheduler shrinks the unscheduled zone using heuristics to balance 467 /// the schedule. 468 class ConvergingScheduler : public MachineSchedStrategy { 469 ScheduleDAGMI *DAG; 470 471 unsigned NumTopReady; 472 unsigned NumBottomReady; 473 474 public: 475 virtual void initialize(ScheduleDAGMI *dag) { 476 DAG = dag; 477 478 assert((!ForceTopDown || !ForceBottomUp) && 479 "-misched-topdown incompatible with -misched-bottomup"); 480 } 481 482 virtual SUnit *pickNode(bool &IsTopNode) { 483 if (DAG->top() == DAG->bottom()) 484 return NULL; 485 486 // As an initial placeholder heuristic, schedule in the direction that has 487 // the fewest choices. 488 SUnit *SU; 489 if (ForceTopDown || (!ForceBottomUp && NumTopReady <= NumBottomReady)) { 490 SU = DAG->getSUnit(DAG->top()); 491 IsTopNode = true; 492 } 493 else { 494 SU = DAG->getSUnit(llvm::prior(DAG->bottom())); 495 IsTopNode = false; 496 } 497 if (SU->isTopReady()) { 498 assert(NumTopReady > 0 && "bad ready count"); 499 --NumTopReady; 500 } 501 if (SU->isBottomReady()) { 502 assert(NumBottomReady > 0 && "bad ready count"); 503 --NumBottomReady; 504 } 505 return SU; 506 } 507 508 virtual void releaseTopNode(SUnit *SU) { 509 ++NumTopReady; 510 } 511 virtual void releaseBottomNode(SUnit *SU) { 512 ++NumBottomReady; 513 } 514 }; 515 } // namespace 516 517 /// Create the standard converging machine scheduler. This will be used as the 518 /// default scheduler if the target does not set a default. 519 static ScheduleDAGInstrs *createConvergingSched(MachineSchedContext *C) { 520 assert((!ForceTopDown || !ForceBottomUp) && 521 "-misched-topdown incompatible with -misched-bottomup"); 522 return new ScheduleDAGMI(C, new ConvergingScheduler()); 523 } 524 static MachineSchedRegistry 525 ConvergingSchedRegistry("converge", "Standard converging scheduler.", 526 createConvergingSched); 527 528 //===----------------------------------------------------------------------===// 529 // Machine Instruction Shuffler for Correctness Testing 530 //===----------------------------------------------------------------------===// 531 532 #ifndef NDEBUG 533 namespace { 534 /// Apply a less-than relation on the node order, which corresponds to the 535 /// instruction order prior to scheduling. IsReverse implements greater-than. 536 template<bool IsReverse> 537 struct SUnitOrder { 538 bool operator()(SUnit *A, SUnit *B) const { 539 if (IsReverse) 540 return A->NodeNum > B->NodeNum; 541 else 542 return A->NodeNum < B->NodeNum; 543 } 544 }; 545 546 /// Reorder instructions as much as possible. 547 class InstructionShuffler : public MachineSchedStrategy { 548 bool IsAlternating; 549 bool IsTopDown; 550 551 // Using a less-than relation (SUnitOrder<false>) for the TopQ priority 552 // gives nodes with a higher number higher priority causing the latest 553 // instructions to be scheduled first. 554 PriorityQueue<SUnit*, std::vector<SUnit*>, SUnitOrder<false> > 555 TopQ; 556 // When scheduling bottom-up, use greater-than as the queue priority. 557 PriorityQueue<SUnit*, std::vector<SUnit*>, SUnitOrder<true> > 558 BottomQ; 559 public: 560 InstructionShuffler(bool alternate, bool topdown) 561 : IsAlternating(alternate), IsTopDown(topdown) {} 562 563 virtual void initialize(ScheduleDAGMI *) { 564 TopQ.clear(); 565 BottomQ.clear(); 566 } 567 568 /// Implement MachineSchedStrategy interface. 569 /// ----------------------------------------- 570 571 virtual SUnit *pickNode(bool &IsTopNode) { 572 SUnit *SU; 573 if (IsTopDown) { 574 do { 575 if (TopQ.empty()) return NULL; 576 SU = TopQ.top(); 577 TopQ.pop(); 578 } while (SU->isScheduled); 579 IsTopNode = true; 580 } 581 else { 582 do { 583 if (BottomQ.empty()) return NULL; 584 SU = BottomQ.top(); 585 BottomQ.pop(); 586 } while (SU->isScheduled); 587 IsTopNode = false; 588 } 589 if (IsAlternating) 590 IsTopDown = !IsTopDown; 591 return SU; 592 } 593 594 virtual void releaseTopNode(SUnit *SU) { 595 TopQ.push(SU); 596 } 597 virtual void releaseBottomNode(SUnit *SU) { 598 BottomQ.push(SU); 599 } 600 }; 601 } // namespace 602 603 static ScheduleDAGInstrs *createInstructionShuffler(MachineSchedContext *C) { 604 bool Alternate = !ForceTopDown && !ForceBottomUp; 605 bool TopDown = !ForceBottomUp; 606 assert((TopDown || !ForceTopDown) && 607 "-misched-topdown incompatible with -misched-bottomup"); 608 return new ScheduleDAGMI(C, new InstructionShuffler(Alternate, TopDown)); 609 } 610 static MachineSchedRegistry ShufflerRegistry( 611 "shuffle", "Shuffle machine instructions alternating directions", 612 createInstructionShuffler); 613 #endif // !NDEBUG 614