From c5443a90d8e513a037db92c6fcda696248617375 Mon Sep 17 00:00:00 2001 From: Andrew Trick Date: Sat, 28 Dec 2013 21:56:51 +0000 Subject: [PATCH] Stub out a PostMachineScheduler pass. Placeholder and boilerplate for a PostRA MachineScheduler pass. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@198120 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/Passes.h | 16 ++++++-- include/llvm/InitializePasses.h | 1 + lib/CodeGen/CodeGen.cpp | 1 + lib/CodeGen/MachineScheduler.cpp | 69 ++++++++++++++++++++++++++++++++ lib/CodeGen/Passes.cpp | 13 +++++- 5 files changed, 96 insertions(+), 4 deletions(-) diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h index 3fbc081ea3b..3be21e02421 100644 --- a/include/llvm/CodeGen/Passes.h +++ b/include/llvm/CodeGen/Passes.h @@ -207,9 +207,9 @@ public: /// Fully developed targets will not generally override this. virtual void addMachinePasses(); - /// createTargetScheduler - Create an instance of ScheduleDAGInstrs to be run - /// within the standard MachineScheduler pass for this function and target at - /// the current optimization level. + /// Create an instance of ScheduleDAGInstrs to be run within the standard + /// MachineScheduler pass for this function and target at the current + /// optimization level. /// /// This can also be used to plug a new MachineSchedStrategy into an instance /// of the standard ScheduleDAGMI: @@ -221,6 +221,13 @@ public: return 0; } + /// Similar to createMachineScheduler but used when postRA machine scheduling + /// is enabled. + virtual ScheduleDAGInstrs * + createPostMachineScheduler(MachineSchedContext *C) const { + return 0; + } + protected: // Helper to verify the analysis is really immutable. void setOpt(bool &Opt, bool Val); @@ -403,6 +410,9 @@ namespace llvm { /// MachineScheduler - This pass schedules machine instructions. extern char &MachineSchedulerID; + /// PostMachineScheduler - This pass schedules machine instructions postRA. + extern char &PostMachineSchedulerID; + /// SpillPlacement analysis. Suggest optimal placement of spill code between /// basic blocks. extern char &SpillPlacementID; diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h index 7be62ca47c7..e27d6b7d393 100644 --- a/include/llvm/InitializePasses.h +++ b/include/llvm/InitializePasses.h @@ -210,6 +210,7 @@ void initializePostDomPrinterPass(PassRegistry&); void initializePostDomViewerPass(PassRegistry&); void initializePostDominatorTreePass(PassRegistry&); void initializePostRASchedulerPass(PassRegistry&); +void initializePostMachineSchedulerPass(PassRegistry&); void initializePreVerifierPass(PassRegistry&); void initializePrintFunctionPassPass(PassRegistry&); void initializePrintModulePassPass(PassRegistry&); diff --git a/lib/CodeGen/CodeGen.cpp b/lib/CodeGen/CodeGen.cpp index 30b40a12da1..368e7d491ba 100644 --- a/lib/CodeGen/CodeGen.cpp +++ b/lib/CodeGen/CodeGen.cpp @@ -51,6 +51,7 @@ void llvm::initializeCodeGen(PassRegistry &Registry) { initializeOptimizePHIsPass(Registry); initializePHIEliminationPass(Registry); initializePeepholeOptimizerPass(Registry); + initializePostMachineSchedulerPass(Registry); initializePostRASchedulerPass(Registry); initializeProcessImplicitDefsPass(Registry); initializePEIPass(Registry); diff --git a/lib/CodeGen/MachineScheduler.cpp b/lib/CodeGen/MachineScheduler.cpp index dd0b4c8a83c..7dc2315eb4a 100644 --- a/lib/CodeGen/MachineScheduler.cpp +++ b/lib/CodeGen/MachineScheduler.cpp @@ -116,6 +116,21 @@ public: protected: ScheduleDAGInstrs *createMachineScheduler(); }; + +/// PostMachineScheduler runs after shortly before code emission. +class PostMachineScheduler : public MachineSchedulerBase { +public: + PostMachineScheduler(); + + virtual void getAnalysisUsage(AnalysisUsage &AU) const; + + virtual bool runOnMachineFunction(MachineFunction&); + + static char ID; // Class identification, replacement for typeinfo + +protected: + ScheduleDAGInstrs *createPostMachineScheduler(); +}; } // namespace char MachineScheduler::ID = 0; @@ -148,6 +163,26 @@ void MachineScheduler::getAnalysisUsage(AnalysisUsage &AU) const { MachineFunctionPass::getAnalysisUsage(AU); } +char PostMachineScheduler::ID = 0; + +char &llvm::PostMachineSchedulerID = PostMachineScheduler::ID; + +INITIALIZE_PASS(PostMachineScheduler, "postmisched", + "PostRA Machine Instruction Scheduler", false, false); + +PostMachineScheduler::PostMachineScheduler() +: MachineSchedulerBase(ID) { + initializePostMachineSchedulerPass(*PassRegistry::getPassRegistry()); +} + +void PostMachineScheduler::getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesCFG(); + AU.addRequiredID(MachineDominatorsID); + AU.addRequired(); + AU.addRequired(); + MachineFunctionPass::getAnalysisUsage(AU); +} + MachinePassRegistry MachineSchedRegistry::Registry; /// A dummy default scheduler factory indicates whether the scheduler @@ -232,6 +267,20 @@ ScheduleDAGInstrs *MachineScheduler::createMachineScheduler() { return createGenericSched(this); } +/// Instantiate a ScheduleDAGInstrs for PostRA scheduling that will be owned by +/// the caller. We don't have a command line option to override the postRA +/// scheduler. The Target must configure it. +ScheduleDAGInstrs *PostMachineScheduler::createPostMachineScheduler() { + // Get the postRA scheduler set by the target for this function. + ScheduleDAGInstrs *Scheduler = PassConfig->createPostMachineScheduler(this); + if (Scheduler) + return Scheduler; + + // Default to GenericScheduler. + // return createRawGenericSched(this); + return NULL; +} + /// Top-level MachineScheduler pass driver. /// /// Visit blocks in function order. Divide each block into scheduling regions @@ -277,6 +326,26 @@ bool MachineScheduler::runOnMachineFunction(MachineFunction &mf) { return true; } +bool PostMachineScheduler::runOnMachineFunction(MachineFunction &mf) { + DEBUG(dbgs() << "Before post-MI-sched:\n"; mf.print(dbgs())); + + // Initialize the context of the pass. + MF = &mf; + PassConfig = &getAnalysis(); + + if (VerifyScheduling) + MF->verify(this, "Before post machine scheduling."); + + // Instantiate the selected scheduler for this target, function, and + // optimization level. + OwningPtr Scheduler(createPostMachineScheduler()); + scheduleRegions(*Scheduler); + + if (VerifyScheduling) + MF->verify(this, "After post machine scheduling."); + return true; +} + /// Main driver for both MachineScheduler and PostMachineScheduler. void MachineSchedulerBase::scheduleRegions(ScheduleDAGInstrs &Scheduler) { const TargetInstrInfo *TII = MF->getTarget().getInstrInfo(); diff --git a/lib/CodeGen/Passes.cpp b/lib/CodeGen/Passes.cpp index f31a843a94c..fed5a4aaca5 100644 --- a/lib/CodeGen/Passes.cpp +++ b/lib/CodeGen/Passes.cpp @@ -88,6 +88,14 @@ PrintMachineInstrs("print-machineinstrs", cl::ValueOptional, cl::desc("Print machine instrs"), cl::value_desc("pass-name"), cl::init("option-unspecified")); +// Temporary option to allow experimenting with MachineScheduler as a post-RA +// scheduler. Targets can "properly" enable this with +// substitutePass(&PostRASchedulerID, &MachineSchedulerID); Ideally it wouldn't +// be part of the standard pass pipeline, and the target would just add a PostRA +// scheduling pass wherever it wants. +static cl::opt MISchedPostRA("misched-postra", cl::Hidden, + cl::desc("Run MachineScheduler post regalloc (independent of preRA sched)")); + // Experimental option to run live interval analysis early. static cl::opt EarlyLiveIntervals("early-live-intervals", cl::Hidden, cl::desc("Run live interval analysis earlier in the pipeline")); @@ -525,7 +533,10 @@ void TargetPassConfig::addMachinePasses() { // Second pass scheduler. if (getOptLevel() != CodeGenOpt::None) { - addPass(&PostRASchedulerID); + if (MISchedPostRA) + addPass(&PostMachineSchedulerID); + else + addPass(&PostRASchedulerID); printAndVerify("After PostRAScheduler"); }