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 "ScheduleDAGInstrs.h" 18 #include "LiveDebugVariables.h" 19 #include "llvm/CodeGen/LiveIntervalAnalysis.h" 20 #include "llvm/CodeGen/MachinePassRegistry.h" 21 #include "llvm/CodeGen/Passes.h" 22 #include "llvm/Analysis/AliasAnalysis.h" 23 #include "llvm/Target/TargetInstrInfo.h" 24 #include "llvm/Support/CommandLine.h" 25 #include "llvm/Support/Debug.h" 26 #include "llvm/Support/ErrorHandling.h" 27 #include "llvm/Support/raw_ostream.h" 28 #include "llvm/ADT/OwningPtr.h" 29 30 #include <queue> 31 32 using namespace llvm; 33 34 //===----------------------------------------------------------------------===// 35 // Machine Instruction Scheduling Pass and Registry 36 //===----------------------------------------------------------------------===// 37 38 namespace { 39 /// MachineScheduler runs after coalescing and before register allocation. 40 class MachineScheduler : public MachineFunctionPass { 41 public: 42 MachineFunction *MF; 43 const TargetInstrInfo *TII; 44 const MachineLoopInfo *MLI; 45 const MachineDominatorTree *MDT; 46 LiveIntervals *LIS; 47 48 MachineScheduler(); 49 50 virtual void getAnalysisUsage(AnalysisUsage &AU) const; 51 52 virtual void releaseMemory() {} 53 54 virtual bool runOnMachineFunction(MachineFunction&); 55 56 virtual void print(raw_ostream &O, const Module* = 0) const; 57 58 static char ID; // Class identification, replacement for typeinfo 59 }; 60 } // namespace 61 62 char MachineScheduler::ID = 0; 63 64 char &llvm::MachineSchedulerID = MachineScheduler::ID; 65 66 INITIALIZE_PASS_BEGIN(MachineScheduler, "misched", 67 "Machine Instruction Scheduler", false, false) 68 INITIALIZE_AG_DEPENDENCY(AliasAnalysis) 69 INITIALIZE_PASS_DEPENDENCY(SlotIndexes) 70 INITIALIZE_PASS_DEPENDENCY(LiveIntervals) 71 INITIALIZE_PASS_DEPENDENCY(LiveDebugVariables) 72 INITIALIZE_PASS_DEPENDENCY(StrongPHIElimination) 73 INITIALIZE_PASS_DEPENDENCY(RegisterCoalescer) 74 INITIALIZE_PASS_END(MachineScheduler, "misched", 75 "Machine Instruction Scheduler", false, false) 76 77 MachineScheduler::MachineScheduler() 78 : MachineFunctionPass(ID), MF(0), MLI(0), MDT(0) { 79 initializeMachineSchedulerPass(*PassRegistry::getPassRegistry()); 80 } 81 82 void MachineScheduler::getAnalysisUsage(AnalysisUsage &AU) const { 83 AU.setPreservesCFG(); 84 AU.addRequiredID(MachineDominatorsID); 85 AU.addRequired<MachineLoopInfo>(); 86 AU.addRequired<AliasAnalysis>(); 87 AU.addPreserved<AliasAnalysis>(); 88 AU.addRequired<SlotIndexes>(); 89 AU.addPreserved<SlotIndexes>(); 90 AU.addRequired<LiveIntervals>(); 91 AU.addPreserved<LiveIntervals>(); 92 AU.addRequired<LiveDebugVariables>(); 93 AU.addPreserved<LiveDebugVariables>(); 94 if (StrongPHIElim) { 95 AU.addRequiredID(StrongPHIEliminationID); 96 AU.addPreservedID(StrongPHIEliminationID); 97 } 98 AU.addRequiredID(RegisterCoalescerPassID); 99 AU.addPreservedID(RegisterCoalescerPassID); 100 MachineFunctionPass::getAnalysisUsage(AU); 101 } 102 103 namespace { 104 /// MachineSchedRegistry provides a selection of available machine instruction 105 /// schedulers. 106 class MachineSchedRegistry : public MachinePassRegistryNode { 107 public: 108 typedef ScheduleDAGInstrs *(*ScheduleDAGCtor)(MachineScheduler *); 109 110 // RegisterPassParser requires a (misnamed) FunctionPassCtor type. 111 typedef ScheduleDAGCtor FunctionPassCtor; 112 113 static MachinePassRegistry Registry; 114 115 MachineSchedRegistry(const char *N, const char *D, ScheduleDAGCtor C) 116 : MachinePassRegistryNode(N, D, (MachinePassCtor)C) { 117 Registry.Add(this); 118 } 119 ~MachineSchedRegistry() { Registry.Remove(this); } 120 121 // Accessors. 122 // 123 MachineSchedRegistry *getNext() const { 124 return (MachineSchedRegistry *)MachinePassRegistryNode::getNext(); 125 } 126 static MachineSchedRegistry *getList() { 127 return (MachineSchedRegistry *)Registry.getList(); 128 } 129 static ScheduleDAGCtor getDefault() { 130 return (ScheduleDAGCtor)Registry.getDefault(); 131 } 132 static void setDefault(ScheduleDAGCtor C) { 133 Registry.setDefault((MachinePassCtor)C); 134 } 135 static void setListener(MachinePassRegistryListener *L) { 136 Registry.setListener(L); 137 } 138 }; 139 } // namespace 140 141 MachinePassRegistry MachineSchedRegistry::Registry; 142 143 static ScheduleDAGInstrs *createDefaultMachineSched(MachineScheduler *P); 144 145 /// MachineSchedOpt allows command line selection of the scheduler. 146 static cl::opt<MachineSchedRegistry::ScheduleDAGCtor, false, 147 RegisterPassParser<MachineSchedRegistry> > 148 MachineSchedOpt("misched", 149 cl::init(&createDefaultMachineSched), cl::Hidden, 150 cl::desc("Machine instruction scheduler to use")); 151 152 //===----------------------------------------------------------------------===// 153 // Machine Instruction Scheduling Common Implementation 154 //===----------------------------------------------------------------------===// 155 156 namespace { 157 /// ScheduleTopDownLive is an implementation of ScheduleDAGInstrs that schedules 158 /// machine instructions while updating LiveIntervals. 159 class ScheduleTopDownLive : public ScheduleDAGInstrs { 160 protected: 161 MachineScheduler *Pass; 162 public: 163 ScheduleTopDownLive(MachineScheduler *P): 164 ScheduleDAGInstrs(*P->MF, *P->MLI, *P->MDT, /*IsPostRA=*/false), Pass(P) {} 165 166 /// ScheduleDAGInstrs callback. 167 void Schedule(); 168 169 /// Interface implemented by the selected top-down liveinterval scheduler. 170 /// 171 /// Pick the next node to schedule, or return NULL. 172 virtual SUnit *pickNode() = 0; 173 174 /// When all preceeding dependencies have been resolved, free this node for 175 /// scheduling. 176 virtual void releaseNode(SUnit *SU) = 0; 177 178 protected: 179 void releaseSucc(SUnit *SU, SDep *SuccEdge); 180 void releaseSuccessors(SUnit *SU); 181 }; 182 } // namespace 183 184 /// ReleaseSucc - Decrement the NumPredsLeft count of a successor. When 185 /// NumPredsLeft reaches zero, release the successor node. 186 void ScheduleTopDownLive::releaseSucc(SUnit *SU, SDep *SuccEdge) { 187 SUnit *SuccSU = SuccEdge->getSUnit(); 188 189 #ifndef NDEBUG 190 if (SuccSU->NumPredsLeft == 0) { 191 dbgs() << "*** Scheduling failed! ***\n"; 192 SuccSU->dump(this); 193 dbgs() << " has been released too many times!\n"; 194 llvm_unreachable(0); 195 } 196 #endif 197 --SuccSU->NumPredsLeft; 198 if (SuccSU->NumPredsLeft == 0 && SuccSU != &ExitSU) 199 releaseNode(SuccSU); 200 } 201 202 /// releaseSuccessors - Call releaseSucc on each of SU's successors. 203 void ScheduleTopDownLive::releaseSuccessors(SUnit *SU) { 204 for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); 205 I != E; ++I) { 206 releaseSucc(SU, &*I); 207 } 208 } 209 210 /// Schedule - This is called back from ScheduleDAGInstrs::Run() when it's 211 /// time to do some work. 212 void ScheduleTopDownLive::Schedule() { 213 BuildSchedGraph(&Pass->getAnalysis<AliasAnalysis>()); 214 215 DEBUG(dbgs() << "********** MI Scheduling **********\n"); 216 DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su) 217 SUnits[su].dumpAll(this)); 218 219 // Release any successors of the special Entry node. It is currently unused, 220 // but we keep up appearances. 221 releaseSuccessors(&EntrySU); 222 223 // Release all DAG roots for scheduling. 224 for (std::vector<SUnit>::iterator I = SUnits.begin(), E = SUnits.end(); 225 I != E; ++I) { 226 // A SUnit is ready to schedule if it has no predecessors. 227 if (I->Preds.empty()) 228 releaseNode(&(*I)); 229 } 230 231 InsertPos = Begin; 232 while (SUnit *SU = pickNode()) { 233 DEBUG(dbgs() << "*** Scheduling Instruction:\n"; SU->dump(this)); 234 235 // Move the instruction to its new location in the instruction stream. 236 MachineInstr *MI = SU->getInstr(); 237 if (&*InsertPos == MI) 238 ++InsertPos; 239 else { 240 Pass->LIS->moveInstr(InsertPos, MI); 241 if (Begin == InsertPos) 242 Begin = MI; 243 } 244 245 // Release dependent instructions for scheduling. 246 releaseSuccessors(SU); 247 } 248 } 249 250 bool MachineScheduler::runOnMachineFunction(MachineFunction &mf) { 251 // Initialize the context of the pass. 252 MF = &mf; 253 MLI = &getAnalysis<MachineLoopInfo>(); 254 MDT = &getAnalysis<MachineDominatorTree>(); 255 LIS = &getAnalysis<LiveIntervals>(); 256 TII = MF->getTarget().getInstrInfo(); 257 258 // Select the scheduler, or set the default. 259 MachineSchedRegistry::ScheduleDAGCtor Ctor = 260 MachineSchedRegistry::getDefault(); 261 if (!Ctor) { 262 Ctor = MachineSchedOpt; 263 MachineSchedRegistry::setDefault(Ctor); 264 } 265 // Instantiate the selected scheduler. 266 OwningPtr<ScheduleDAGInstrs> Scheduler(Ctor(this)); 267 268 // Visit all machine basic blocks. 269 for (MachineFunction::iterator MBB = MF->begin(), MBBEnd = MF->end(); 270 MBB != MBBEnd; ++MBB) { 271 272 // Break the block into scheduling regions [I, RegionEnd), and schedule each 273 // region as soon as it is discovered. 274 unsigned RemainingCount = MBB->size(); 275 for(MachineBasicBlock::iterator RegionEnd = MBB->end(); 276 RegionEnd != MBB->begin();) { 277 // The next region starts above the previous region. Look backward in the 278 // instruction stream until we find the nearest boundary. 279 MachineBasicBlock::iterator I = RegionEnd; 280 for(;I != MBB->begin(); --I, --RemainingCount) { 281 if (TII->isSchedulingBoundary(llvm::prior(I), MBB, *MF)) 282 break; 283 } 284 if (I == RegionEnd) { 285 // Skip empty scheduling regions. 286 RegionEnd = llvm::prior(RegionEnd); 287 --RemainingCount; 288 continue; 289 } 290 // Skip regions with one instruction. 291 if (I == llvm::prior(RegionEnd)) { 292 RegionEnd = llvm::prior(RegionEnd); 293 continue; 294 } 295 DEBUG(dbgs() << "MachineScheduling " << MF->getFunction()->getName() 296 << ":BB#" << MBB->getNumber() << "\n From: " << *I << " To: "; 297 if (RegionEnd != MBB->end()) dbgs() << *RegionEnd; 298 else dbgs() << "End"; 299 dbgs() << " Remaining: " << RemainingCount << "\n"); 300 301 // Inform ScheduleDAGInstrs of the region being scheduled. It calls back 302 // to our Schedule() method. 303 Scheduler->Run(MBB, I, RegionEnd, MBB->size()); 304 RegionEnd = Scheduler->Begin; 305 } 306 assert(RemainingCount == 0 && "Instruction count mismatch!"); 307 } 308 return true; 309 } 310 311 void MachineScheduler::print(raw_ostream &O, const Module* m) const { 312 // unimplemented 313 } 314 315 //===----------------------------------------------------------------------===// 316 // Placeholder for extending the machine instruction scheduler. 317 //===----------------------------------------------------------------------===// 318 319 namespace { 320 class DefaultMachineScheduler : public ScheduleDAGInstrs { 321 MachineScheduler *Pass; 322 public: 323 DefaultMachineScheduler(MachineScheduler *P): 324 ScheduleDAGInstrs(*P->MF, *P->MLI, *P->MDT, /*IsPostRA=*/false), Pass(P) {} 325 326 /// Schedule - This is called back from ScheduleDAGInstrs::Run() when it's 327 /// time to do some work. 328 void Schedule(); 329 }; 330 } // namespace 331 332 static ScheduleDAGInstrs *createDefaultMachineSched(MachineScheduler *P) { 333 return new DefaultMachineScheduler(P); 334 } 335 static MachineSchedRegistry 336 SchedDefaultRegistry("default", "Activate the scheduler pass, " 337 "but don't reorder instructions", 338 createDefaultMachineSched); 339 340 341 /// Schedule - This is called back from ScheduleDAGInstrs::Run() when it's 342 /// time to do some work. 343 void DefaultMachineScheduler::Schedule() { 344 BuildSchedGraph(&Pass->getAnalysis<AliasAnalysis>()); 345 346 DEBUG(dbgs() << "********** MI Scheduling **********\n"); 347 DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su) 348 SUnits[su].dumpAll(this)); 349 350 // TODO: Put interesting things here. 351 // 352 // When this is fully implemented, it will become a subclass of 353 // ScheduleTopDownLive. So this driver will disappear. 354 } 355 356 //===----------------------------------------------------------------------===// 357 // Machine Instruction Shuffler for Correctness Testing 358 //===----------------------------------------------------------------------===// 359 360 #ifndef NDEBUG 361 namespace { 362 // Nodes with a higher number have lower priority. This way we attempt to 363 // schedule the latest instructions earliest. 364 // 365 // TODO: Relies on the property of the BuildSchedGraph that results in SUnits 366 // being ordered in sequence bottom-up. This will be formalized, probably be 367 // constructing SUnits in a prepass. 368 struct ShuffleSUnitOrder { 369 bool operator()(SUnit *A, SUnit *B) const { 370 return A->NodeNum > B->NodeNum; 371 } 372 }; 373 374 /// Reorder instructions as much as possible. 375 class InstructionShuffler : public ScheduleTopDownLive { 376 std::priority_queue<SUnit*, std::vector<SUnit*>, ShuffleSUnitOrder> Queue; 377 public: 378 InstructionShuffler(MachineScheduler *P): 379 ScheduleTopDownLive(P) {} 380 381 /// ScheduleTopDownLive Interface 382 383 virtual SUnit *pickNode() { 384 if (Queue.empty()) return NULL; 385 SUnit *SU = Queue.top(); 386 Queue.pop(); 387 return SU; 388 } 389 390 virtual void releaseNode(SUnit *SU) { 391 Queue.push(SU); 392 } 393 }; 394 } // namespace 395 396 static ScheduleDAGInstrs *createInstructionShuffler(MachineScheduler *P) { 397 return new InstructionShuffler(P); 398 } 399 static MachineSchedRegistry ShufflerRegistry("shuffle", 400 "Shuffle machine instructions", 401 createInstructionShuffler); 402 #endif // !NDEBUG 403