MachineScheduler.cpp revision e9ef4ed13ba84ef27da831afa27b7955c8f09530
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 30using namespace llvm; 31 32//===----------------------------------------------------------------------===// 33// Machine Instruction Scheduling Pass and Registry 34//===----------------------------------------------------------------------===// 35 36namespace { 37/// MachineSchedulerPass runs after coalescing and before register allocation. 38class MachineSchedulerPass : public MachineFunctionPass { 39public: 40 MachineFunction *MF; 41 const TargetInstrInfo *TII; 42 const MachineLoopInfo *MLI; 43 const MachineDominatorTree *MDT; 44 45 MachineSchedulerPass(); 46 47 virtual void getAnalysisUsage(AnalysisUsage &AU) const; 48 49 virtual void releaseMemory() {} 50 51 virtual bool runOnMachineFunction(MachineFunction&); 52 53 virtual void print(raw_ostream &O, const Module* = 0) const; 54 55 static char ID; // Class identification, replacement for typeinfo 56}; 57} // namespace 58 59char MachineSchedulerPass::ID = 0; 60 61char &llvm::MachineSchedulerPassID = MachineSchedulerPass::ID; 62 63INITIALIZE_PASS_BEGIN(MachineSchedulerPass, "misched", 64 "Machine Instruction Scheduler", false, false) 65INITIALIZE_AG_DEPENDENCY(AliasAnalysis) 66INITIALIZE_PASS_DEPENDENCY(SlotIndexes) 67INITIALIZE_PASS_DEPENDENCY(LiveIntervals) 68INITIALIZE_PASS_DEPENDENCY(LiveDebugVariables) 69INITIALIZE_PASS_DEPENDENCY(StrongPHIElimination) 70INITIALIZE_PASS_DEPENDENCY(RegisterCoalescer) 71INITIALIZE_PASS_END(MachineSchedulerPass, "misched", 72 "Machine Instruction Scheduler", false, false) 73 74MachineSchedulerPass::MachineSchedulerPass() 75: MachineFunctionPass(ID), MF(0), MLI(0), MDT(0) { 76 initializeMachineSchedulerPassPass(*PassRegistry::getPassRegistry()); 77} 78 79void MachineSchedulerPass::getAnalysisUsage(AnalysisUsage &AU) const { 80 AU.setPreservesCFG(); 81 AU.addRequiredID(MachineDominatorsID); 82 AU.addRequired<MachineLoopInfo>(); 83 AU.addRequired<AliasAnalysis>(); 84 AU.addPreserved<AliasAnalysis>(); 85 AU.addRequired<SlotIndexes>(); 86 AU.addPreserved<SlotIndexes>(); 87 AU.addRequired<LiveIntervals>(); 88 AU.addPreserved<LiveIntervals>(); 89 AU.addRequired<LiveDebugVariables>(); 90 AU.addPreserved<LiveDebugVariables>(); 91 if (StrongPHIElim) { 92 AU.addRequiredID(StrongPHIEliminationID); 93 AU.addPreservedID(StrongPHIEliminationID); 94 } 95 AU.addRequiredID(RegisterCoalescerPassID); 96 AU.addPreservedID(RegisterCoalescerPassID); 97 MachineFunctionPass::getAnalysisUsage(AU); 98} 99 100namespace { 101/// MachineSchedRegistry provides a selection of available machine instruction 102/// schedulers. 103class MachineSchedRegistry : public MachinePassRegistryNode { 104public: 105 typedef ScheduleDAGInstrs *(*ScheduleDAGCtor)(MachineSchedulerPass *); 106 107 // RegisterPassParser requires a (misnamed) FunctionPassCtor type. 108 typedef ScheduleDAGCtor FunctionPassCtor; 109 110 static MachinePassRegistry Registry; 111 112 MachineSchedRegistry(const char *N, const char *D, ScheduleDAGCtor C) 113 : MachinePassRegistryNode(N, D, (MachinePassCtor)C) { 114 Registry.Add(this); 115 } 116 ~MachineSchedRegistry() { Registry.Remove(this); } 117 118 // Accessors. 119 // 120 MachineSchedRegistry *getNext() const { 121 return (MachineSchedRegistry *)MachinePassRegistryNode::getNext(); 122 } 123 static MachineSchedRegistry *getList() { 124 return (MachineSchedRegistry *)Registry.getList(); 125 } 126 static ScheduleDAGCtor getDefault() { 127 return (ScheduleDAGCtor)Registry.getDefault(); 128 } 129 static void setDefault(ScheduleDAGCtor C) { 130 Registry.setDefault((MachinePassCtor)C); 131 } 132 static void setListener(MachinePassRegistryListener *L) { 133 Registry.setListener(L); 134 } 135}; 136} // namespace 137 138MachinePassRegistry MachineSchedRegistry::Registry; 139 140static ScheduleDAGInstrs *createDefaultMachineSched(MachineSchedulerPass *P); 141 142/// MachineSchedOpt allows command line selection of the scheduler. 143static cl::opt<MachineSchedRegistry::ScheduleDAGCtor, false, 144 RegisterPassParser<MachineSchedRegistry> > 145MachineSchedOpt("misched", 146 cl::init(&createDefaultMachineSched), cl::Hidden, 147 cl::desc("Machine instruction scheduler to use")); 148 149//===----------------------------------------------------------------------===// 150// Machine Instruction Scheduling Implementation 151//===----------------------------------------------------------------------===// 152 153namespace { 154/// MachineScheduler is an implementation of ScheduleDAGInstrs that schedules 155/// machine instructions while updating LiveIntervals. 156class MachineScheduler : public ScheduleDAGInstrs { 157 MachineSchedulerPass *Pass; 158public: 159 MachineScheduler(MachineSchedulerPass *P): 160 ScheduleDAGInstrs(*P->MF, *P->MLI, *P->MDT), Pass(P) {} 161 162 /// Schedule - This is called back from ScheduleDAGInstrs::Run() when it's 163 /// time to do some work. 164 virtual void Schedule(); 165}; 166} // namespace 167 168static ScheduleDAGInstrs *createDefaultMachineSched(MachineSchedulerPass *P) { 169 return new MachineScheduler(P); 170} 171static MachineSchedRegistry 172SchedDefaultRegistry("default", "Activate the scheduler pass, " 173 "but don't reorder instructions", 174 createDefaultMachineSched); 175 176/// Schedule - This is called back from ScheduleDAGInstrs::Run() when it's 177/// time to do some work. 178void MachineScheduler::Schedule() { 179 BuildSchedGraph(&Pass->getAnalysis<AliasAnalysis>()); 180 181 DEBUG(dbgs() << "********** MI Scheduling **********\n"); 182 DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su) 183 SUnits[su].dumpAll(this)); 184 185 // TODO: Put interesting things here. 186} 187 188bool MachineSchedulerPass::runOnMachineFunction(MachineFunction &mf) { 189 // Initialize the context of the pass. 190 MF = &mf; 191 MLI = &getAnalysis<MachineLoopInfo>(); 192 MDT = &getAnalysis<MachineDominatorTree>(); 193 TII = MF->getTarget().getInstrInfo(); 194 195 // Select the scheduler, or set the default. 196 MachineSchedRegistry::ScheduleDAGCtor Ctor = 197 MachineSchedRegistry::getDefault(); 198 if (!Ctor) { 199 Ctor = MachineSchedOpt; 200 MachineSchedRegistry::setDefault(Ctor); 201 } 202 // Instantiate the selected scheduler. 203 OwningPtr<ScheduleDAGInstrs> Scheduler(Ctor(this)); 204 205 // Visit all machine basic blocks. 206 for (MachineFunction::iterator MBB = MF->begin(), MBBEnd = MF->end(); 207 MBB != MBBEnd; ++MBB) { 208 209 // Break the block into scheduling regions [I, RegionEnd), and schedule each 210 // region as soon as it is discovered. 211 unsigned RemainingCount = MBB->size(); 212 for(MachineBasicBlock::iterator RegionEnd = MBB->end(); 213 RegionEnd != MBB->begin();) { 214 // The next region starts above the previous region. Look backward in the 215 // instruction stream until we find the nearest boundary. 216 MachineBasicBlock::iterator I = RegionEnd; 217 for(;I != MBB->begin(); --I) { 218 if (TII->isSchedulingBoundary(llvm::prior(I), MBB, *MF)) 219 break; 220 } 221 if (I == RegionEnd || I == llvm::prior(RegionEnd)) { 222 // Skip empty or single instruction scheduling regions. 223 RegionEnd = llvm::prior(RegionEnd); 224 continue; 225 } 226 DEBUG(dbgs() << "MachineScheduling " << MF->getFunction()->getName() 227 << ":BB#" << MBB->getNumber() << "\n From: " << *I << " To: " 228 << *RegionEnd << " Remaining: " << RemainingCount << "\n"); 229 230 // Inform ScheduleDAGInstrs of the region being scheduler. It calls back 231 // to our Schedule() method. 232 Scheduler->Run(MBB, I, RegionEnd, MBB->size()); 233 RegionEnd = I; 234 } 235 assert(RemainingCount == 0 && "Instruction count mismatch!"); 236 } 237 return true; 238} 239 240void MachineSchedulerPass::print(raw_ostream &O, const Module* m) const { 241 // unimplemented 242} 243 244//===----------------------------------------------------------------------===// 245// Machine Instruction Shuffler for Correctness Testing 246//===----------------------------------------------------------------------===// 247 248#ifndef NDEBUG 249namespace { 250/// Reorder instructions as much as possible. 251class InstructionShuffler : public ScheduleDAGInstrs { 252 MachineSchedulerPass *Pass; 253public: 254 InstructionShuffler(MachineSchedulerPass *P): 255 ScheduleDAGInstrs(*P->MF, *P->MLI, *P->MDT), Pass(P) {} 256 257 /// Schedule - This is called back from ScheduleDAGInstrs::Run() when it's 258 /// time to do some work. 259 virtual void Schedule() { 260 llvm_unreachable("unimplemented"); 261 } 262}; 263} // namespace 264 265static ScheduleDAGInstrs *createInstructionShuffler(MachineSchedulerPass *P) { 266 return new InstructionShuffler(P); 267} 268static MachineSchedRegistry ShufflerRegistry("shuffle", 269 "Shuffle machine instructions", 270 createInstructionShuffler); 271#endif // !NDEBUG 272