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