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