LLVM API Documentation
00001 //===----- SchedulePostRAList.cpp - list scheduler ------------------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This implements a top-down list scheduler, using standard algorithms. 00011 // The basic approach uses a priority queue of available nodes to schedule. 00012 // One at a time, nodes are taken from the priority queue (thus in priority 00013 // order), checked for legality to schedule, and emitted if legal. 00014 // 00015 // Nodes may not be legal to schedule either due to structural hazards (e.g. 00016 // pipeline or resource constraints) or because an input to the instruction has 00017 // not completed execution. 00018 // 00019 //===----------------------------------------------------------------------===// 00020 00021 #include "llvm/CodeGen/Passes.h" 00022 #include "AggressiveAntiDepBreaker.h" 00023 #include "AntiDepBreaker.h" 00024 #include "CriticalAntiDepBreaker.h" 00025 #include "llvm/ADT/BitVector.h" 00026 #include "llvm/ADT/Statistic.h" 00027 #include "llvm/Analysis/AliasAnalysis.h" 00028 #include "llvm/CodeGen/LatencyPriorityQueue.h" 00029 #include "llvm/CodeGen/MachineDominators.h" 00030 #include "llvm/CodeGen/MachineFrameInfo.h" 00031 #include "llvm/CodeGen/MachineFunctionPass.h" 00032 #include "llvm/CodeGen/MachineLoopInfo.h" 00033 #include "llvm/CodeGen/MachineRegisterInfo.h" 00034 #include "llvm/CodeGen/RegisterClassInfo.h" 00035 #include "llvm/CodeGen/ScheduleDAGInstrs.h" 00036 #include "llvm/CodeGen/ScheduleHazardRecognizer.h" 00037 #include "llvm/CodeGen/SchedulerRegistry.h" 00038 #include "llvm/Support/CommandLine.h" 00039 #include "llvm/Support/Debug.h" 00040 #include "llvm/Support/ErrorHandling.h" 00041 #include "llvm/Support/raw_ostream.h" 00042 #include "llvm/Target/TargetInstrInfo.h" 00043 #include "llvm/Target/TargetLowering.h" 00044 #include "llvm/Target/TargetMachine.h" 00045 #include "llvm/Target/TargetRegisterInfo.h" 00046 #include "llvm/Target/TargetSubtargetInfo.h" 00047 using namespace llvm; 00048 00049 #define DEBUG_TYPE "post-RA-sched" 00050 00051 STATISTIC(NumNoops, "Number of noops inserted"); 00052 STATISTIC(NumStalls, "Number of pipeline stalls"); 00053 STATISTIC(NumFixedAnti, "Number of fixed anti-dependencies"); 00054 00055 // Post-RA scheduling is enabled with 00056 // TargetSubtargetInfo.enablePostRAScheduler(). This flag can be used to 00057 // override the target. 00058 static cl::opt<bool> 00059 EnablePostRAScheduler("post-RA-scheduler", 00060 cl::desc("Enable scheduling after register allocation"), 00061 cl::init(false), cl::Hidden); 00062 static cl::opt<std::string> 00063 EnableAntiDepBreaking("break-anti-dependencies", 00064 cl::desc("Break post-RA scheduling anti-dependencies: " 00065 "\"critical\", \"all\", or \"none\""), 00066 cl::init("none"), cl::Hidden); 00067 00068 // If DebugDiv > 0 then only schedule MBB with (ID % DebugDiv) == DebugMod 00069 static cl::opt<int> 00070 DebugDiv("postra-sched-debugdiv", 00071 cl::desc("Debug control MBBs that are scheduled"), 00072 cl::init(0), cl::Hidden); 00073 static cl::opt<int> 00074 DebugMod("postra-sched-debugmod", 00075 cl::desc("Debug control MBBs that are scheduled"), 00076 cl::init(0), cl::Hidden); 00077 00078 AntiDepBreaker::~AntiDepBreaker() { } 00079 00080 namespace { 00081 class PostRAScheduler : public MachineFunctionPass { 00082 const TargetInstrInfo *TII; 00083 RegisterClassInfo RegClassInfo; 00084 00085 public: 00086 static char ID; 00087 PostRAScheduler() : MachineFunctionPass(ID) {} 00088 00089 void getAnalysisUsage(AnalysisUsage &AU) const override { 00090 AU.setPreservesCFG(); 00091 AU.addRequired<AliasAnalysis>(); 00092 AU.addRequired<TargetPassConfig>(); 00093 AU.addRequired<MachineDominatorTree>(); 00094 AU.addPreserved<MachineDominatorTree>(); 00095 AU.addRequired<MachineLoopInfo>(); 00096 AU.addPreserved<MachineLoopInfo>(); 00097 MachineFunctionPass::getAnalysisUsage(AU); 00098 } 00099 00100 bool runOnMachineFunction(MachineFunction &Fn) override; 00101 00102 bool enablePostRAScheduler( 00103 const TargetSubtargetInfo &ST, CodeGenOpt::Level OptLevel, 00104 TargetSubtargetInfo::AntiDepBreakMode &Mode, 00105 TargetSubtargetInfo::RegClassVector &CriticalPathRCs) const; 00106 }; 00107 char PostRAScheduler::ID = 0; 00108 00109 class SchedulePostRATDList : public ScheduleDAGInstrs { 00110 /// AvailableQueue - The priority queue to use for the available SUnits. 00111 /// 00112 LatencyPriorityQueue AvailableQueue; 00113 00114 /// PendingQueue - This contains all of the instructions whose operands have 00115 /// been issued, but their results are not ready yet (due to the latency of 00116 /// the operation). Once the operands becomes available, the instruction is 00117 /// added to the AvailableQueue. 00118 std::vector<SUnit*> PendingQueue; 00119 00120 /// HazardRec - The hazard recognizer to use. 00121 ScheduleHazardRecognizer *HazardRec; 00122 00123 /// AntiDepBreak - Anti-dependence breaking object, or NULL if none 00124 AntiDepBreaker *AntiDepBreak; 00125 00126 /// AA - AliasAnalysis for making memory reference queries. 00127 AliasAnalysis *AA; 00128 00129 /// The schedule. Null SUnit*'s represent noop instructions. 00130 std::vector<SUnit*> Sequence; 00131 00132 /// The index in BB of RegionEnd. 00133 /// 00134 /// This is the instruction number from the top of the current block, not 00135 /// the SlotIndex. It is only used by the AntiDepBreaker. 00136 unsigned EndIndex; 00137 00138 public: 00139 SchedulePostRATDList( 00140 MachineFunction &MF, MachineLoopInfo &MLI, AliasAnalysis *AA, 00141 const RegisterClassInfo &, 00142 TargetSubtargetInfo::AntiDepBreakMode AntiDepMode, 00143 SmallVectorImpl<const TargetRegisterClass *> &CriticalPathRCs); 00144 00145 ~SchedulePostRATDList(); 00146 00147 /// startBlock - Initialize register live-range state for scheduling in 00148 /// this block. 00149 /// 00150 void startBlock(MachineBasicBlock *BB) override; 00151 00152 // Set the index of RegionEnd within the current BB. 00153 void setEndIndex(unsigned EndIdx) { EndIndex = EndIdx; } 00154 00155 /// Initialize the scheduler state for the next scheduling region. 00156 void enterRegion(MachineBasicBlock *bb, 00157 MachineBasicBlock::iterator begin, 00158 MachineBasicBlock::iterator end, 00159 unsigned regioninstrs) override; 00160 00161 /// Notify that the scheduler has finished scheduling the current region. 00162 void exitRegion() override; 00163 00164 /// Schedule - Schedule the instruction range using list scheduling. 00165 /// 00166 void schedule() override; 00167 00168 void EmitSchedule(); 00169 00170 /// Observe - Update liveness information to account for the current 00171 /// instruction, which will not be scheduled. 00172 /// 00173 void Observe(MachineInstr *MI, unsigned Count); 00174 00175 /// finishBlock - Clean up register live-range state. 00176 /// 00177 void finishBlock() override; 00178 00179 private: 00180 void ReleaseSucc(SUnit *SU, SDep *SuccEdge); 00181 void ReleaseSuccessors(SUnit *SU); 00182 void ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle); 00183 void ListScheduleTopDown(); 00184 00185 void dumpSchedule() const; 00186 void emitNoop(unsigned CurCycle); 00187 }; 00188 } 00189 00190 char &llvm::PostRASchedulerID = PostRAScheduler::ID; 00191 00192 INITIALIZE_PASS(PostRAScheduler, "post-RA-sched", 00193 "Post RA top-down list latency scheduler", false, false) 00194 00195 SchedulePostRATDList::SchedulePostRATDList( 00196 MachineFunction &MF, MachineLoopInfo &MLI, AliasAnalysis *AA, 00197 const RegisterClassInfo &RCI, 00198 TargetSubtargetInfo::AntiDepBreakMode AntiDepMode, 00199 SmallVectorImpl<const TargetRegisterClass *> &CriticalPathRCs) 00200 : ScheduleDAGInstrs(MF, &MLI, /*IsPostRA=*/true), AA(AA), EndIndex(0) { 00201 00202 const TargetMachine &TM = MF.getTarget(); 00203 const InstrItineraryData *InstrItins = 00204 TM.getSubtargetImpl()->getInstrItineraryData(); 00205 HazardRec = 00206 TM.getSubtargetImpl()->getInstrInfo()->CreateTargetPostRAHazardRecognizer( 00207 InstrItins, this); 00208 00209 assert((AntiDepMode == TargetSubtargetInfo::ANTIDEP_NONE || 00210 MRI.tracksLiveness()) && 00211 "Live-ins must be accurate for anti-dependency breaking"); 00212 AntiDepBreak = 00213 ((AntiDepMode == TargetSubtargetInfo::ANTIDEP_ALL) ? 00214 (AntiDepBreaker *)new AggressiveAntiDepBreaker(MF, RCI, CriticalPathRCs) : 00215 ((AntiDepMode == TargetSubtargetInfo::ANTIDEP_CRITICAL) ? 00216 (AntiDepBreaker *)new CriticalAntiDepBreaker(MF, RCI) : nullptr)); 00217 } 00218 00219 SchedulePostRATDList::~SchedulePostRATDList() { 00220 delete HazardRec; 00221 delete AntiDepBreak; 00222 } 00223 00224 /// Initialize state associated with the next scheduling region. 00225 void SchedulePostRATDList::enterRegion(MachineBasicBlock *bb, 00226 MachineBasicBlock::iterator begin, 00227 MachineBasicBlock::iterator end, 00228 unsigned regioninstrs) { 00229 ScheduleDAGInstrs::enterRegion(bb, begin, end, regioninstrs); 00230 Sequence.clear(); 00231 } 00232 00233 /// Print the schedule before exiting the region. 00234 void SchedulePostRATDList::exitRegion() { 00235 DEBUG({ 00236 dbgs() << "*** Final schedule ***\n"; 00237 dumpSchedule(); 00238 dbgs() << '\n'; 00239 }); 00240 ScheduleDAGInstrs::exitRegion(); 00241 } 00242 00243 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 00244 /// dumpSchedule - dump the scheduled Sequence. 00245 void SchedulePostRATDList::dumpSchedule() const { 00246 for (unsigned i = 0, e = Sequence.size(); i != e; i++) { 00247 if (SUnit *SU = Sequence[i]) 00248 SU->dump(this); 00249 else 00250 dbgs() << "**** NOOP ****\n"; 00251 } 00252 } 00253 #endif 00254 00255 bool PostRAScheduler::enablePostRAScheduler( 00256 const TargetSubtargetInfo &ST, 00257 CodeGenOpt::Level OptLevel, 00258 TargetSubtargetInfo::AntiDepBreakMode &Mode, 00259 TargetSubtargetInfo::RegClassVector &CriticalPathRCs) const { 00260 Mode = ST.getAntiDepBreakMode(); 00261 ST.getCriticalPathRCs(CriticalPathRCs); 00262 return ST.enablePostMachineScheduler() && 00263 OptLevel >= ST.getOptLevelToEnablePostRAScheduler(); 00264 } 00265 00266 bool PostRAScheduler::runOnMachineFunction(MachineFunction &Fn) { 00267 if (skipOptnoneFunction(*Fn.getFunction())) 00268 return false; 00269 00270 TII = Fn.getSubtarget().getInstrInfo(); 00271 MachineLoopInfo &MLI = getAnalysis<MachineLoopInfo>(); 00272 AliasAnalysis *AA = &getAnalysis<AliasAnalysis>(); 00273 TargetPassConfig *PassConfig = &getAnalysis<TargetPassConfig>(); 00274 00275 RegClassInfo.runOnMachineFunction(Fn); 00276 00277 // Check for explicit enable/disable of post-ra scheduling. 00278 TargetSubtargetInfo::AntiDepBreakMode AntiDepMode = 00279 TargetSubtargetInfo::ANTIDEP_NONE; 00280 SmallVector<const TargetRegisterClass*, 4> CriticalPathRCs; 00281 if (EnablePostRAScheduler.getPosition() > 0) { 00282 if (!EnablePostRAScheduler) 00283 return false; 00284 } else { 00285 // Check that post-RA scheduling is enabled for this target. 00286 // This may upgrade the AntiDepMode. 00287 const TargetSubtargetInfo &ST = 00288 Fn.getTarget().getSubtarget<TargetSubtargetInfo>(); 00289 if (!enablePostRAScheduler(ST, PassConfig->getOptLevel(), 00290 AntiDepMode, CriticalPathRCs)) 00291 return false; 00292 } 00293 00294 // Check for antidep breaking override... 00295 if (EnableAntiDepBreaking.getPosition() > 0) { 00296 AntiDepMode = (EnableAntiDepBreaking == "all") 00297 ? TargetSubtargetInfo::ANTIDEP_ALL 00298 : ((EnableAntiDepBreaking == "critical") 00299 ? TargetSubtargetInfo::ANTIDEP_CRITICAL 00300 : TargetSubtargetInfo::ANTIDEP_NONE); 00301 } 00302 00303 DEBUG(dbgs() << "PostRAScheduler\n"); 00304 00305 SchedulePostRATDList Scheduler(Fn, MLI, AA, RegClassInfo, AntiDepMode, 00306 CriticalPathRCs); 00307 00308 // Loop over all of the basic blocks 00309 for (MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end(); 00310 MBB != MBBe; ++MBB) { 00311 #ifndef NDEBUG 00312 // If DebugDiv > 0 then only schedule MBB with (ID % DebugDiv) == DebugMod 00313 if (DebugDiv > 0) { 00314 static int bbcnt = 0; 00315 if (bbcnt++ % DebugDiv != DebugMod) 00316 continue; 00317 dbgs() << "*** DEBUG scheduling " << Fn.getName() 00318 << ":BB#" << MBB->getNumber() << " ***\n"; 00319 } 00320 #endif 00321 00322 // Initialize register live-range state for scheduling in this block. 00323 Scheduler.startBlock(MBB); 00324 00325 // Schedule each sequence of instructions not interrupted by a label 00326 // or anything else that effectively needs to shut down scheduling. 00327 MachineBasicBlock::iterator Current = MBB->end(); 00328 unsigned Count = MBB->size(), CurrentCount = Count; 00329 for (MachineBasicBlock::iterator I = Current; I != MBB->begin(); ) { 00330 MachineInstr *MI = std::prev(I); 00331 --Count; 00332 // Calls are not scheduling boundaries before register allocation, but 00333 // post-ra we don't gain anything by scheduling across calls since we 00334 // don't need to worry about register pressure. 00335 if (MI->isCall() || TII->isSchedulingBoundary(MI, MBB, Fn)) { 00336 Scheduler.enterRegion(MBB, I, Current, CurrentCount - Count); 00337 Scheduler.setEndIndex(CurrentCount); 00338 Scheduler.schedule(); 00339 Scheduler.exitRegion(); 00340 Scheduler.EmitSchedule(); 00341 Current = MI; 00342 CurrentCount = Count; 00343 Scheduler.Observe(MI, CurrentCount); 00344 } 00345 I = MI; 00346 if (MI->isBundle()) 00347 Count -= MI->getBundleSize(); 00348 } 00349 assert(Count == 0 && "Instruction count mismatch!"); 00350 assert((MBB->begin() == Current || CurrentCount != 0) && 00351 "Instruction count mismatch!"); 00352 Scheduler.enterRegion(MBB, MBB->begin(), Current, CurrentCount); 00353 Scheduler.setEndIndex(CurrentCount); 00354 Scheduler.schedule(); 00355 Scheduler.exitRegion(); 00356 Scheduler.EmitSchedule(); 00357 00358 // Clean up register live-range state. 00359 Scheduler.finishBlock(); 00360 00361 // Update register kills 00362 Scheduler.fixupKills(MBB); 00363 } 00364 00365 return true; 00366 } 00367 00368 /// StartBlock - Initialize register live-range state for scheduling in 00369 /// this block. 00370 /// 00371 void SchedulePostRATDList::startBlock(MachineBasicBlock *BB) { 00372 // Call the superclass. 00373 ScheduleDAGInstrs::startBlock(BB); 00374 00375 // Reset the hazard recognizer and anti-dep breaker. 00376 HazardRec->Reset(); 00377 if (AntiDepBreak) 00378 AntiDepBreak->StartBlock(BB); 00379 } 00380 00381 /// Schedule - Schedule the instruction range using list scheduling. 00382 /// 00383 void SchedulePostRATDList::schedule() { 00384 // Build the scheduling graph. 00385 buildSchedGraph(AA); 00386 00387 if (AntiDepBreak) { 00388 unsigned Broken = 00389 AntiDepBreak->BreakAntiDependencies(SUnits, RegionBegin, RegionEnd, 00390 EndIndex, DbgValues); 00391 00392 if (Broken != 0) { 00393 // We made changes. Update the dependency graph. 00394 // Theoretically we could update the graph in place: 00395 // When a live range is changed to use a different register, remove 00396 // the def's anti-dependence *and* output-dependence edges due to 00397 // that register, and add new anti-dependence and output-dependence 00398 // edges based on the next live range of the register. 00399 ScheduleDAG::clearDAG(); 00400 buildSchedGraph(AA); 00401 00402 NumFixedAnti += Broken; 00403 } 00404 } 00405 00406 DEBUG(dbgs() << "********** List Scheduling **********\n"); 00407 DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su) 00408 SUnits[su].dumpAll(this)); 00409 00410 AvailableQueue.initNodes(SUnits); 00411 ListScheduleTopDown(); 00412 AvailableQueue.releaseState(); 00413 } 00414 00415 /// Observe - Update liveness information to account for the current 00416 /// instruction, which will not be scheduled. 00417 /// 00418 void SchedulePostRATDList::Observe(MachineInstr *MI, unsigned Count) { 00419 if (AntiDepBreak) 00420 AntiDepBreak->Observe(MI, Count, EndIndex); 00421 } 00422 00423 /// FinishBlock - Clean up register live-range state. 00424 /// 00425 void SchedulePostRATDList::finishBlock() { 00426 if (AntiDepBreak) 00427 AntiDepBreak->FinishBlock(); 00428 00429 // Call the superclass. 00430 ScheduleDAGInstrs::finishBlock(); 00431 } 00432 00433 //===----------------------------------------------------------------------===// 00434 // Top-Down Scheduling 00435 //===----------------------------------------------------------------------===// 00436 00437 /// ReleaseSucc - Decrement the NumPredsLeft count of a successor. Add it to 00438 /// the PendingQueue if the count reaches zero. 00439 void SchedulePostRATDList::ReleaseSucc(SUnit *SU, SDep *SuccEdge) { 00440 SUnit *SuccSU = SuccEdge->getSUnit(); 00441 00442 if (SuccEdge->isWeak()) { 00443 --SuccSU->WeakPredsLeft; 00444 return; 00445 } 00446 #ifndef NDEBUG 00447 if (SuccSU->NumPredsLeft == 0) { 00448 dbgs() << "*** Scheduling failed! ***\n"; 00449 SuccSU->dump(this); 00450 dbgs() << " has been released too many times!\n"; 00451 llvm_unreachable(nullptr); 00452 } 00453 #endif 00454 --SuccSU->NumPredsLeft; 00455 00456 // Standard scheduler algorithms will recompute the depth of the successor 00457 // here as such: 00458 // SuccSU->setDepthToAtLeast(SU->getDepth() + SuccEdge->getLatency()); 00459 // 00460 // However, we lazily compute node depth instead. Note that 00461 // ScheduleNodeTopDown has already updated the depth of this node which causes 00462 // all descendents to be marked dirty. Setting the successor depth explicitly 00463 // here would cause depth to be recomputed for all its ancestors. If the 00464 // successor is not yet ready (because of a transitively redundant edge) then 00465 // this causes depth computation to be quadratic in the size of the DAG. 00466 00467 // If all the node's predecessors are scheduled, this node is ready 00468 // to be scheduled. Ignore the special ExitSU node. 00469 if (SuccSU->NumPredsLeft == 0 && SuccSU != &ExitSU) 00470 PendingQueue.push_back(SuccSU); 00471 } 00472 00473 /// ReleaseSuccessors - Call ReleaseSucc on each of SU's successors. 00474 void SchedulePostRATDList::ReleaseSuccessors(SUnit *SU) { 00475 for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); 00476 I != E; ++I) { 00477 ReleaseSucc(SU, &*I); 00478 } 00479 } 00480 00481 /// ScheduleNodeTopDown - Add the node to the schedule. Decrement the pending 00482 /// count of its successors. If a successor pending count is zero, add it to 00483 /// the Available queue. 00484 void SchedulePostRATDList::ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle) { 00485 DEBUG(dbgs() << "*** Scheduling [" << CurCycle << "]: "); 00486 DEBUG(SU->dump(this)); 00487 00488 Sequence.push_back(SU); 00489 assert(CurCycle >= SU->getDepth() && 00490 "Node scheduled above its depth!"); 00491 SU->setDepthToAtLeast(CurCycle); 00492 00493 ReleaseSuccessors(SU); 00494 SU->isScheduled = true; 00495 AvailableQueue.scheduledNode(SU); 00496 } 00497 00498 /// emitNoop - Add a noop to the current instruction sequence. 00499 void SchedulePostRATDList::emitNoop(unsigned CurCycle) { 00500 DEBUG(dbgs() << "*** Emitting noop in cycle " << CurCycle << '\n'); 00501 HazardRec->EmitNoop(); 00502 Sequence.push_back(nullptr); // NULL here means noop 00503 ++NumNoops; 00504 } 00505 00506 /// ListScheduleTopDown - The main loop of list scheduling for top-down 00507 /// schedulers. 00508 void SchedulePostRATDList::ListScheduleTopDown() { 00509 unsigned CurCycle = 0; 00510 00511 // We're scheduling top-down but we're visiting the regions in 00512 // bottom-up order, so we don't know the hazards at the start of a 00513 // region. So assume no hazards (this should usually be ok as most 00514 // blocks are a single region). 00515 HazardRec->Reset(); 00516 00517 // Release any successors of the special Entry node. 00518 ReleaseSuccessors(&EntrySU); 00519 00520 // Add all leaves to Available queue. 00521 for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { 00522 // It is available if it has no predecessors. 00523 if (!SUnits[i].NumPredsLeft && !SUnits[i].isAvailable) { 00524 AvailableQueue.push(&SUnits[i]); 00525 SUnits[i].isAvailable = true; 00526 } 00527 } 00528 00529 // In any cycle where we can't schedule any instructions, we must 00530 // stall or emit a noop, depending on the target. 00531 bool CycleHasInsts = false; 00532 00533 // While Available queue is not empty, grab the node with the highest 00534 // priority. If it is not ready put it back. Schedule the node. 00535 std::vector<SUnit*> NotReady; 00536 Sequence.reserve(SUnits.size()); 00537 while (!AvailableQueue.empty() || !PendingQueue.empty()) { 00538 // Check to see if any of the pending instructions are ready to issue. If 00539 // so, add them to the available queue. 00540 unsigned MinDepth = ~0u; 00541 for (unsigned i = 0, e = PendingQueue.size(); i != e; ++i) { 00542 if (PendingQueue[i]->getDepth() <= CurCycle) { 00543 AvailableQueue.push(PendingQueue[i]); 00544 PendingQueue[i]->isAvailable = true; 00545 PendingQueue[i] = PendingQueue.back(); 00546 PendingQueue.pop_back(); 00547 --i; --e; 00548 } else if (PendingQueue[i]->getDepth() < MinDepth) 00549 MinDepth = PendingQueue[i]->getDepth(); 00550 } 00551 00552 DEBUG(dbgs() << "\n*** Examining Available\n"; AvailableQueue.dump(this)); 00553 00554 SUnit *FoundSUnit = nullptr, *NotPreferredSUnit = nullptr; 00555 bool HasNoopHazards = false; 00556 while (!AvailableQueue.empty()) { 00557 SUnit *CurSUnit = AvailableQueue.pop(); 00558 00559 ScheduleHazardRecognizer::HazardType HT = 00560 HazardRec->getHazardType(CurSUnit, 0/*no stalls*/); 00561 if (HT == ScheduleHazardRecognizer::NoHazard) { 00562 if (HazardRec->ShouldPreferAnother(CurSUnit)) { 00563 if (!NotPreferredSUnit) { 00564 // If this is the first non-preferred node for this cycle, then 00565 // record it and continue searching for a preferred node. If this 00566 // is not the first non-preferred node, then treat it as though 00567 // there had been a hazard. 00568 NotPreferredSUnit = CurSUnit; 00569 continue; 00570 } 00571 } else { 00572 FoundSUnit = CurSUnit; 00573 break; 00574 } 00575 } 00576 00577 // Remember if this is a noop hazard. 00578 HasNoopHazards |= HT == ScheduleHazardRecognizer::NoopHazard; 00579 00580 NotReady.push_back(CurSUnit); 00581 } 00582 00583 // If we have a non-preferred node, push it back onto the available list. 00584 // If we did not find a preferred node, then schedule this first 00585 // non-preferred node. 00586 if (NotPreferredSUnit) { 00587 if (!FoundSUnit) { 00588 DEBUG(dbgs() << "*** Will schedule a non-preferred instruction...\n"); 00589 FoundSUnit = NotPreferredSUnit; 00590 } else { 00591 AvailableQueue.push(NotPreferredSUnit); 00592 } 00593 00594 NotPreferredSUnit = nullptr; 00595 } 00596 00597 // Add the nodes that aren't ready back onto the available list. 00598 if (!NotReady.empty()) { 00599 AvailableQueue.push_all(NotReady); 00600 NotReady.clear(); 00601 } 00602 00603 // If we found a node to schedule... 00604 if (FoundSUnit) { 00605 // If we need to emit noops prior to this instruction, then do so. 00606 unsigned NumPreNoops = HazardRec->PreEmitNoops(FoundSUnit); 00607 for (unsigned i = 0; i != NumPreNoops; ++i) 00608 emitNoop(CurCycle); 00609 00610 // ... schedule the node... 00611 ScheduleNodeTopDown(FoundSUnit, CurCycle); 00612 HazardRec->EmitInstruction(FoundSUnit); 00613 CycleHasInsts = true; 00614 if (HazardRec->atIssueLimit()) { 00615 DEBUG(dbgs() << "*** Max instructions per cycle " << CurCycle << '\n'); 00616 HazardRec->AdvanceCycle(); 00617 ++CurCycle; 00618 CycleHasInsts = false; 00619 } 00620 } else { 00621 if (CycleHasInsts) { 00622 DEBUG(dbgs() << "*** Finished cycle " << CurCycle << '\n'); 00623 HazardRec->AdvanceCycle(); 00624 } else if (!HasNoopHazards) { 00625 // Otherwise, we have a pipeline stall, but no other problem, 00626 // just advance the current cycle and try again. 00627 DEBUG(dbgs() << "*** Stall in cycle " << CurCycle << '\n'); 00628 HazardRec->AdvanceCycle(); 00629 ++NumStalls; 00630 } else { 00631 // Otherwise, we have no instructions to issue and we have instructions 00632 // that will fault if we don't do this right. This is the case for 00633 // processors without pipeline interlocks and other cases. 00634 emitNoop(CurCycle); 00635 } 00636 00637 ++CurCycle; 00638 CycleHasInsts = false; 00639 } 00640 } 00641 00642 #ifndef NDEBUG 00643 unsigned ScheduledNodes = VerifyScheduledDAG(/*isBottomUp=*/false); 00644 unsigned Noops = 0; 00645 for (unsigned i = 0, e = Sequence.size(); i != e; ++i) 00646 if (!Sequence[i]) 00647 ++Noops; 00648 assert(Sequence.size() - Noops == ScheduledNodes && 00649 "The number of nodes scheduled doesn't match the expected number!"); 00650 #endif // NDEBUG 00651 } 00652 00653 // EmitSchedule - Emit the machine code in scheduled order. 00654 void SchedulePostRATDList::EmitSchedule() { 00655 RegionBegin = RegionEnd; 00656 00657 // If first instruction was a DBG_VALUE then put it back. 00658 if (FirstDbgValue) 00659 BB->splice(RegionEnd, BB, FirstDbgValue); 00660 00661 // Then re-insert them according to the given schedule. 00662 for (unsigned i = 0, e = Sequence.size(); i != e; i++) { 00663 if (SUnit *SU = Sequence[i]) 00664 BB->splice(RegionEnd, BB, SU->getInstr()); 00665 else 00666 // Null SUnit* is a noop. 00667 TII->insertNoop(*BB, RegionEnd); 00668 00669 // Update the Begin iterator, as the first instruction in the block 00670 // may have been scheduled later. 00671 if (i == 0) 00672 RegionBegin = std::prev(RegionEnd); 00673 } 00674 00675 // Reinsert any remaining debug_values. 00676 for (std::vector<std::pair<MachineInstr *, MachineInstr *> >::iterator 00677 DI = DbgValues.end(), DE = DbgValues.begin(); DI != DE; --DI) { 00678 std::pair<MachineInstr *, MachineInstr *> P = *std::prev(DI); 00679 MachineInstr *DbgValue = P.first; 00680 MachineBasicBlock::iterator OrigPrivMI = P.second; 00681 BB->splice(++OrigPrivMI, BB, DbgValue); 00682 } 00683 DbgValues.clear(); 00684 FirstDbgValue = nullptr; 00685 }