diff options
Diffstat (limited to 'lib/CodeGen/MachineScheduler.cpp')
-rw-r--r-- | lib/CodeGen/MachineScheduler.cpp | 246 |
1 files changed, 102 insertions, 144 deletions
diff --git a/lib/CodeGen/MachineScheduler.cpp b/lib/CodeGen/MachineScheduler.cpp index aff67ce09e..203ddfd18b 100644 --- a/lib/CodeGen/MachineScheduler.cpp +++ b/lib/CodeGen/MachineScheduler.cpp @@ -15,7 +15,7 @@ #define DEBUG_TYPE "misched" #include "llvm/CodeGen/LiveIntervalAnalysis.h" -#include "llvm/CodeGen/MachinePassRegistry.h" +#include "llvm/CodeGen/MachineScheduler.h" #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/ScheduleDAGInstrs.h" #include "llvm/Analysis/AliasAnalysis.h" @@ -43,14 +43,9 @@ static bool ViewMISchedDAGs = false; namespace { /// MachineScheduler runs after coalescing and before register allocation. -class MachineScheduler : public MachineFunctionPass { +class MachineScheduler : public MachineSchedContext, + public MachineFunctionPass { public: - MachineFunction *MF; - const TargetInstrInfo *TII; - const MachineLoopInfo *MLI; - const MachineDominatorTree *MDT; - LiveIntervals *LIS; - MachineScheduler(); virtual void getAnalysisUsage(AnalysisUsage &AU) const; @@ -78,7 +73,7 @@ INITIALIZE_PASS_END(MachineScheduler, "misched", "Machine Instruction Scheduler", false, false) MachineScheduler::MachineScheduler() -: MachineFunctionPass(ID), MF(0), MLI(0), MDT(0) { +: MachineFunctionPass(ID) { initializeMachineSchedulerPass(*PassRegistry::getPassRegistry()); } @@ -95,47 +90,9 @@ void MachineScheduler::getAnalysisUsage(AnalysisUsage &AU) const { MachineFunctionPass::getAnalysisUsage(AU); } -namespace { -/// MachineSchedRegistry provides a selection of available machine instruction -/// schedulers. -class MachineSchedRegistry : public MachinePassRegistryNode { -public: - typedef ScheduleDAGInstrs *(*ScheduleDAGCtor)(MachineScheduler *); - - // RegisterPassParser requires a (misnamed) FunctionPassCtor type. - typedef ScheduleDAGCtor FunctionPassCtor; - - static MachinePassRegistry Registry; - - MachineSchedRegistry(const char *N, const char *D, ScheduleDAGCtor C) - : MachinePassRegistryNode(N, D, (MachinePassCtor)C) { - Registry.Add(this); - } - ~MachineSchedRegistry() { Registry.Remove(this); } - - // Accessors. - // - MachineSchedRegistry *getNext() const { - return (MachineSchedRegistry *)MachinePassRegistryNode::getNext(); - } - static MachineSchedRegistry *getList() { - return (MachineSchedRegistry *)Registry.getList(); - } - static ScheduleDAGCtor getDefault() { - return (ScheduleDAGCtor)Registry.getDefault(); - } - static void setDefault(ScheduleDAGCtor C) { - Registry.setDefault((MachinePassCtor)C); - } - static void setListener(MachinePassRegistryListener *L) { - Registry.setListener(L); - } -}; -} // namespace - MachinePassRegistry MachineSchedRegistry::Registry; -static ScheduleDAGInstrs *createDefaultMachineSched(MachineScheduler *P); +static ScheduleDAGInstrs *createDefaultMachineSched(MachineSchedContext *C); /// MachineSchedOpt allows command line selection of the scheduler. static cl::opt<MachineSchedRegistry::ScheduleDAGCtor, false, @@ -144,22 +101,97 @@ MachineSchedOpt("misched", cl::init(&createDefaultMachineSched), cl::Hidden, cl::desc("Machine instruction scheduler to use")); +bool MachineScheduler::runOnMachineFunction(MachineFunction &mf) { + // Initialize the context of the pass. + MF = &mf; + MLI = &getAnalysis<MachineLoopInfo>(); + MDT = &getAnalysis<MachineDominatorTree>(); + AA = &getAnalysis<AliasAnalysis>(); + + LIS = &getAnalysis<LiveIntervals>(); + const TargetInstrInfo *TII = MF->getTarget().getInstrInfo(); + + // Select the scheduler, or set the default. + MachineSchedRegistry::ScheduleDAGCtor Ctor = + MachineSchedRegistry::getDefault(); + if (!Ctor) { + Ctor = MachineSchedOpt; + MachineSchedRegistry::setDefault(Ctor); + } + // Instantiate the selected scheduler. + OwningPtr<ScheduleDAGInstrs> Scheduler(Ctor(this)); + + // Visit all machine basic blocks. + for (MachineFunction::iterator MBB = MF->begin(), MBBEnd = MF->end(); + MBB != MBBEnd; ++MBB) { + + // Break the block into scheduling regions [I, RegionEnd), and schedule each + // region as soon as it is discovered. + unsigned RemainingCount = MBB->size(); + for(MachineBasicBlock::iterator RegionEnd = MBB->end(); + RegionEnd != MBB->begin();) { + Scheduler->startBlock(MBB); + // The next region starts above the previous region. Look backward in the + // instruction stream until we find the nearest boundary. + MachineBasicBlock::iterator I = RegionEnd; + for(;I != MBB->begin(); --I, --RemainingCount) { + if (TII->isSchedulingBoundary(llvm::prior(I), MBB, *MF)) + break; + } + // Notify the scheduler of the region, even if we may skip scheduling + // it. Perhaps it still needs to be bundled. + Scheduler->enterRegion(MBB, I, RegionEnd, RemainingCount); + + // Skip empty scheduling regions (0 or 1 schedulable instructions). + if (I == RegionEnd || I == llvm::prior(RegionEnd)) { + RegionEnd = llvm::prior(RegionEnd); + if (I != RegionEnd) + --RemainingCount; + // Close the current region. Bundle the terminator if needed. + Scheduler->exitRegion(); + continue; + } + DEBUG(dbgs() << "MachineScheduling " << MF->getFunction()->getName() + << ":BB#" << MBB->getNumber() << "\n From: " << *I << " To: "; + if (RegionEnd != MBB->end()) dbgs() << *RegionEnd; + else dbgs() << "End"; + dbgs() << " Remaining: " << RemainingCount << "\n"); + + // Inform ScheduleDAGInstrs of the region being scheduled. It calls back + // to our schedule() method. + Scheduler->schedule(); + Scheduler->exitRegion(); + + // Scheduling has invalidated the current iterator 'I'. Ask the + // scheduler for the top of it's scheduled region. + RegionEnd = Scheduler->begin(); + } + assert(RemainingCount == 0 && "Instruction count mismatch!"); + Scheduler->finishBlock(); + } + return true; +} + +void MachineScheduler::print(raw_ostream &O, const Module* m) const { + // unimplemented +} + //===----------------------------------------------------------------------===// -// Machine Instruction Scheduling Common Implementation -//===----------------------------------------------------------------------===// +// ScheduleTopeDownLive - Base class for basic top-down scheduling with +// LiveIntervals preservation. +// ===----------------------------------------------------------------------===// namespace { /// ScheduleTopDownLive is an implementation of ScheduleDAGInstrs that schedules /// machine instructions while updating LiveIntervals. class ScheduleTopDownLive : public ScheduleDAGInstrs { -protected: - MachineScheduler *Pass; + AliasAnalysis *AA; public: - ScheduleTopDownLive(MachineScheduler *P): - ScheduleDAGInstrs(*P->MF, *P->MLI, *P->MDT, /*IsPostRA=*/false, P->LIS), - Pass(P) {} + ScheduleTopDownLive(MachineSchedContext *C): + ScheduleDAGInstrs(*C->MF, *C->MLI, *C->MDT, /*IsPostRA=*/false, C->LIS), + AA(C->AA) {} - /// ScheduleDAGInstrs callback. + /// ScheduleDAGInstrs interface. void schedule(); /// Interface implemented by the selected top-down liveinterval scheduler. @@ -206,7 +238,7 @@ void ScheduleTopDownLive::releaseSuccessors(SUnit *SU) { /// schedule - This is called back from ScheduleDAGInstrs::Run() when it's /// time to do some work. void ScheduleTopDownLive::schedule() { - buildSchedGraph(&Pass->getAnalysis<AliasAnalysis>()); + buildSchedGraph(AA); DEBUG(dbgs() << "********** MI Scheduling **********\n"); DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su) @@ -236,7 +268,7 @@ void ScheduleTopDownLive::schedule() { ++InsertPos; else { BB->splice(InsertPos, BB, MI); - Pass->LIS->handleMove(MI); + LIS->handleMove(MI); if (Begin == InsertPos) Begin = MI; } @@ -246,90 +278,17 @@ void ScheduleTopDownLive::schedule() { } } -bool MachineScheduler::runOnMachineFunction(MachineFunction &mf) { - // Initialize the context of the pass. - MF = &mf; - MLI = &getAnalysis<MachineLoopInfo>(); - MDT = &getAnalysis<MachineDominatorTree>(); - LIS = &getAnalysis<LiveIntervals>(); - TII = MF->getTarget().getInstrInfo(); - - // Select the scheduler, or set the default. - MachineSchedRegistry::ScheduleDAGCtor Ctor = - MachineSchedRegistry::getDefault(); - if (!Ctor) { - Ctor = MachineSchedOpt; - MachineSchedRegistry::setDefault(Ctor); - } - // Instantiate the selected scheduler. - OwningPtr<ScheduleDAGInstrs> Scheduler(Ctor(this)); - - // Visit all machine basic blocks. - for (MachineFunction::iterator MBB = MF->begin(), MBBEnd = MF->end(); - MBB != MBBEnd; ++MBB) { - - // Break the block into scheduling regions [I, RegionEnd), and schedule each - // region as soon as it is discovered. - unsigned RemainingCount = MBB->size(); - for(MachineBasicBlock::iterator RegionEnd = MBB->end(); - RegionEnd != MBB->begin();) { - Scheduler->startBlock(MBB); - // The next region starts above the previous region. Look backward in the - // instruction stream until we find the nearest boundary. - MachineBasicBlock::iterator I = RegionEnd; - for(;I != MBB->begin(); --I, --RemainingCount) { - if (TII->isSchedulingBoundary(llvm::prior(I), MBB, *MF)) - break; - } - // Notify the scheduler of the region, even if we may skip scheduling - // it. Perhaps it still needs to be bundled. - Scheduler->enterRegion(MBB, I, RegionEnd, RemainingCount); - - // Skip empty scheduling regions (0 or 1 schedulable instructions). - if (I == RegionEnd || I == llvm::prior(RegionEnd)) { - RegionEnd = llvm::prior(RegionEnd); - if (I != RegionEnd) - --RemainingCount; - // Close the current region. Bundle the terminator if needed. - Scheduler->exitRegion(); - continue; - } - DEBUG(dbgs() << "MachineScheduling " << MF->getFunction()->getName() - << ":BB#" << MBB->getNumber() << "\n From: " << *I << " To: "; - if (RegionEnd != MBB->end()) dbgs() << *RegionEnd; - else dbgs() << "End"; - dbgs() << " Remaining: " << RemainingCount << "\n"); - - // Inform ScheduleDAGInstrs of the region being scheduled. It calls back - // to our schedule() method. - Scheduler->schedule(); - Scheduler->exitRegion(); - - // Scheduling has invalidated the current iterator 'I'. Ask the - // scheduler for the top of it's scheduled region. - RegionEnd = Scheduler->begin(); - } - assert(RemainingCount == 0 && "Instruction count mismatch!"); - Scheduler->finishBlock(); - } - return true; -} - -void MachineScheduler::print(raw_ostream &O, const Module* m) const { - // unimplemented -} - //===----------------------------------------------------------------------===// -// Placeholder for extending the machine instruction scheduler. +// Placeholder for the default machine instruction scheduler. //===----------------------------------------------------------------------===// namespace { class DefaultMachineScheduler : public ScheduleDAGInstrs { - MachineScheduler *Pass; + AliasAnalysis *AA; public: - DefaultMachineScheduler(MachineScheduler *P): - ScheduleDAGInstrs(*P->MF, *P->MLI, *P->MDT, /*IsPostRA=*/false, P->LIS), - Pass(P) {} + DefaultMachineScheduler(MachineSchedContext *C): + ScheduleDAGInstrs(*C->MF, *C->MLI, *C->MDT, /*IsPostRA=*/false, C->LIS), + AA(C->AA) {} /// schedule - This is called back from ScheduleDAGInstrs::Run() when it's /// time to do some work. @@ -337,19 +296,18 @@ public: }; } // namespace -static ScheduleDAGInstrs *createDefaultMachineSched(MachineScheduler *P) { - return new DefaultMachineScheduler(P); +static ScheduleDAGInstrs *createDefaultMachineSched(MachineSchedContext *C) { + return new DefaultMachineScheduler(C); } static MachineSchedRegistry SchedDefaultRegistry("default", "Activate the scheduler pass, " "but don't reorder instructions", createDefaultMachineSched); - /// Schedule - This is called back from ScheduleDAGInstrs::Run() when it's /// time to do some work. void DefaultMachineScheduler::schedule() { - buildSchedGraph(&Pass->getAnalysis<AliasAnalysis>()); + buildSchedGraph(AA); DEBUG(dbgs() << "********** MI Scheduling **********\n"); DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su) @@ -382,8 +340,8 @@ struct ShuffleSUnitOrder { class InstructionShuffler : public ScheduleTopDownLive { std::priority_queue<SUnit*, std::vector<SUnit*>, ShuffleSUnitOrder> Queue; public: - InstructionShuffler(MachineScheduler *P): - ScheduleTopDownLive(P) {} + InstructionShuffler(MachineSchedContext *C): + ScheduleTopDownLive(C) {} /// ScheduleTopDownLive Interface @@ -400,8 +358,8 @@ public: }; } // namespace -static ScheduleDAGInstrs *createInstructionShuffler(MachineScheduler *P) { - return new InstructionShuffler(P); +static ScheduleDAGInstrs *createInstructionShuffler(MachineSchedContext *C) { + return new InstructionShuffler(C); } static MachineSchedRegistry ShufflerRegistry("shuffle", "Shuffle machine instructions", |