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