Index: include/llvm/CodeGen/Passes.h =================================================================== --- include/llvm/CodeGen/Passes.h +++ include/llvm/CodeGen/Passes.h @@ -21,6 +21,7 @@ namespace llvm { class Function; +class MachineFunction; class FunctionPass; class MachineFunctionPass; class ModulePass; @@ -116,6 +117,8 @@ /// PostMachineScheduler - This pass schedules machine instructions postRA. extern char &PostMachineSchedulerID; + MachineFunctionPass * + createPostMachineScheduler(std::function); /// SpillPlacement analysis. Suggest optimal placement of spill code between /// basic blocks. extern char &SpillPlacementID; @@ -175,6 +178,8 @@ /// scheduling. extern char &PostRASchedulerID; + MachineFunctionPass * + createPostRAScheduler(std::function); /// BranchFolding - This pass performs machine code CFG based /// optimizations to delete branches to branches, eliminate branches to /// successor blocks (creating fall throughs), and eliminating branches over Index: include/llvm/CodeGen/TargetPassConfig.h =================================================================== --- include/llvm/CodeGen/TargetPassConfig.h +++ include/llvm/CodeGen/TargetPassConfig.h @@ -253,6 +253,11 @@ /// Fully developed targets will not generally override this. virtual void addMachinePasses(); + /// Add scheduler passes to be executed after register allocation. + /// Target can optionally insert this pass by itself at some other point by + /// overriding this with an empty function. + virtual void addPostRASched(); + /// Create an instance of ScheduleDAGInstrs to be run within the standard /// MachineScheduler pass for this function and target at the current /// optimization level. @@ -402,6 +407,32 @@ /// addMachinePasses helper to create the target-selected or overriden /// regalloc pass. FunctionPass *createRegAllocPass(bool Optimized); + + /// Allow standard passes to be disabled by the command line, regardless of + /// who is adding the pass. + /// + /// StandardID is the pass identified in the standard pass pipeline and + /// provided + /// to addPass(). It may be a target-specific ID in the case that the target + /// directly adds its own pass, but in that case we harmlessly fall through. + /// + /// TargetID is the pass that the target has configured to override + /// StandardID. + /// + /// StandardID may be a pseudo ID. In that case TargetID is the name of the + /// real + /// pass to run. This allows multiple options to control a single pass + /// depending + /// on where in the pipeline that pass is added. + virtual IdentifyingPassPtr overridePass(AnalysisID StandardID, + IdentifyingPassPtr TargetID) const; + + /// Allow standard passes to be disabled by command line options. This + /// supports simple binary flags that either suppress the pass or do nothing. + /// i.e. -disable-mypass=false has no effect. + /// These should be converted to boolOrDefault in order to use applyOverride. + IdentifyingPassPtr applyDisable(IdentifyingPassPtr PassID, + bool Override) const; }; } // end namespace llvm Index: include/llvm/Target/TargetMachine.h =================================================================== --- include/llvm/Target/TargetMachine.h +++ include/llvm/Target/TargetMachine.h @@ -252,13 +252,6 @@ return true; } - /// True if subtarget inserts the final scheduling pass on its own. - /// - /// Branch relaxation, which must happen after block placement, can - /// on some targets (e.g. SystemZ) expose additional post-RA - /// scheduling opportunities. - virtual bool targetSchedulesPostRAScheduling() const { return false; }; - void getNameWithPrefix(SmallVectorImpl &Name, const GlobalValue *GV, Mangler &Mang, bool MayAlwaysUsePrivate = false) const; MCSymbol *getSymbol(const GlobalValue *GV, Mangler &Mang) const; Index: lib/CodeGen/MachineScheduler.cpp =================================================================== --- lib/CodeGen/MachineScheduler.cpp +++ lib/CodeGen/MachineScheduler.cpp @@ -137,8 +137,12 @@ /// PostMachineScheduler runs after shortly before code emission. class PostMachineScheduler : public MachineSchedulerBase { + + std::function PredicateFtor; + public: - PostMachineScheduler(); + PostMachineScheduler( + std::function Ftor = nullptr); void getAnalysisUsage(AnalysisUsage &AU) const override; @@ -188,8 +192,9 @@ INITIALIZE_PASS(PostMachineScheduler, "postmisched", "PostRA Machine Instruction Scheduler", false, false) -PostMachineScheduler::PostMachineScheduler() -: MachineSchedulerBase(ID) { +PostMachineScheduler::PostMachineScheduler( + std::function Ftor) + : MachineSchedulerBase(ID), PredicateFtor(Ftor) { initializePostMachineSchedulerPass(*PassRegistry::getPassRegistry()); } @@ -359,6 +364,10 @@ } bool PostMachineScheduler::runOnMachineFunction(MachineFunction &mf) { + + if (PredicateFtor && !PredicateFtor(mf)) + return false; + if (skipFunction(*mf.getFunction())) return false; @@ -3560,3 +3569,8 @@ void ScheduleDAGMI::viewGraph() { viewGraph(getDAGName(), "Scheduling-Units Graph for " + getDAGName()); } + +MachineFunctionPass *llvm::createPostMachineScheduler( + std::function Ftor) { + return new PostMachineScheduler(Ftor); +} Index: lib/CodeGen/PostRASchedulerList.cpp =================================================================== --- lib/CodeGen/PostRASchedulerList.cpp +++ lib/CodeGen/PostRASchedulerList.cpp @@ -80,10 +80,12 @@ class PostRAScheduler : public MachineFunctionPass { const TargetInstrInfo *TII; RegisterClassInfo RegClassInfo; + std::function PredicateFtor; public: static char ID; - PostRAScheduler() : MachineFunctionPass(ID) {} + PostRAScheduler(std::function Ftor = nullptr) + : MachineFunctionPass(ID), PredicateFtor(Ftor) {} void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesCFG(); @@ -280,6 +282,10 @@ } bool PostRAScheduler::runOnMachineFunction(MachineFunction &Fn) { + + if (PredicateFtor && !PredicateFtor(Fn)) + return false; + if (skipFunction(*Fn.getFunction())) return false; @@ -703,3 +709,9 @@ DbgValues.clear(); FirstDbgValue = nullptr; } + +MachineFunctionPass * +llvm::createPostRAScheduler(std::function Ftor) { + return new PostRAScheduler(Ftor); +} + Index: lib/CodeGen/TargetPassConfig.cpp =================================================================== --- lib/CodeGen/TargetPassConfig.cpp +++ lib/CodeGen/TargetPassConfig.cpp @@ -38,7 +38,7 @@ using namespace llvm; -static cl::opt DisablePostRA("disable-post-ra", cl::Hidden, +cl::opt DisablePostRA("disable-post-ra", cl::Hidden, cl::desc("Disable Post Regalloc")); static cl::opt DisableBranchFold("disable-branch-fold", cl::Hidden, cl::desc("Disable branch folding")); @@ -109,8 +109,6 @@ // Temporary option to allow experimenting with MachineScheduler as a post-RA // scheduler. Targets can "properly" enable this with // substitutePass(&PostRASchedulerID, &PostMachineSchedulerID). -// Targets can return true in targetSchedulesPostRAScheduling() and -// insert a PostRA scheduling pass wherever it wants. cl::opt MISchedPostRA("misched-postra", cl::Hidden, cl::desc("Run MachineScheduler post regalloc (independent of preRA sched)")); @@ -131,72 +129,7 @@ clEnumValN(CFLAAType::Both, "both", "Enable both variants of CFL-AA"))); -/// Allow standard passes to be disabled by command line options. This supports -/// simple binary flags that either suppress the pass or do nothing. -/// i.e. -disable-mypass=false has no effect. -/// These should be converted to boolOrDefault in order to use applyOverride. -static IdentifyingPassPtr applyDisable(IdentifyingPassPtr PassID, - bool Override) { - if (Override) - return IdentifyingPassPtr(); - return PassID; -} - -/// Allow standard passes to be disabled by the command line, regardless of who -/// is adding the pass. -/// -/// StandardID is the pass identified in the standard pass pipeline and provided -/// to addPass(). It may be a target-specific ID in the case that the target -/// directly adds its own pass, but in that case we harmlessly fall through. -/// -/// TargetID is the pass that the target has configured to override StandardID. -/// -/// StandardID may be a pseudo ID. In that case TargetID is the name of the real -/// pass to run. This allows multiple options to control a single pass depending -/// on where in the pipeline that pass is added. -static IdentifyingPassPtr overridePass(AnalysisID StandardID, - IdentifyingPassPtr TargetID) { - if (StandardID == &PostRASchedulerID) - return applyDisable(TargetID, DisablePostRA); - - if (StandardID == &BranchFolderPassID) - return applyDisable(TargetID, DisableBranchFold); - - if (StandardID == &TailDuplicateID) - return applyDisable(TargetID, DisableTailDuplicate); - - if (StandardID == &TargetPassConfig::EarlyTailDuplicateID) - return applyDisable(TargetID, DisableEarlyTailDup); - - if (StandardID == &MachineBlockPlacementID) - return applyDisable(TargetID, DisableBlockPlacement); - - if (StandardID == &StackSlotColoringID) - return applyDisable(TargetID, DisableSSC); - - if (StandardID == &DeadMachineInstructionElimID) - return applyDisable(TargetID, DisableMachineDCE); - - if (StandardID == &EarlyIfConverterID) - return applyDisable(TargetID, DisableEarlyIfConversion); - - if (StandardID == &MachineLICMID) - return applyDisable(TargetID, DisableMachineLICM); - if (StandardID == &MachineCSEID) - return applyDisable(TargetID, DisableMachineCSE); - - if (StandardID == &TargetPassConfig::PostRAMachineLICMID) - return applyDisable(TargetID, DisablePostRAMachineLICM); - - if (StandardID == &MachineSinkingID) - return applyDisable(TargetID, DisableMachineSink); - - if (StandardID == &MachineCopyPropagationID) - return applyDisable(TargetID, DisableCopyProp); - - return TargetID; -} //===---------------------------------------------------------------------===// /// TargetPassConfig @@ -337,6 +270,57 @@ FinalPtr.getID() != ID; } +IdentifyingPassPtr TargetPassConfig::applyDisable(IdentifyingPassPtr PassID, + bool Override) const { + if (Override) + return IdentifyingPassPtr(); + return PassID; +} + +IdentifyingPassPtr TargetPassConfig::overridePass(AnalysisID StandardID, + IdentifyingPassPtr TargetID) const { + if (StandardID == &PostRASchedulerID) + return applyDisable(TargetID, DisablePostRA); + + if (StandardID == &BranchFolderPassID) + return applyDisable(TargetID, DisableBranchFold); + + if (StandardID == &TailDuplicateID) + return applyDisable(TargetID, DisableTailDuplicate); + + if (StandardID == &TargetPassConfig::EarlyTailDuplicateID) + return applyDisable(TargetID, DisableEarlyTailDup); + + if (StandardID == &MachineBlockPlacementID) + return applyDisable(TargetID, DisableBlockPlacement); + + if (StandardID == &StackSlotColoringID) + return applyDisable(TargetID, DisableSSC); + + if (StandardID == &DeadMachineInstructionElimID) + return applyDisable(TargetID, DisableMachineDCE); + + if (StandardID == &EarlyIfConverterID) + return applyDisable(TargetID, DisableEarlyIfConversion); + + if (StandardID == &MachineLICMID) + return applyDisable(TargetID, DisableMachineLICM); + + if (StandardID == &MachineCSEID) + return applyDisable(TargetID, DisableMachineCSE); + + if (StandardID == &TargetPassConfig::PostRAMachineLICMID) + return applyDisable(TargetID, DisablePostRAMachineLICM); + + if (StandardID == &MachineSinkingID) + return applyDisable(TargetID, DisableMachineSink); + + if (StandardID == &MachineCopyPropagationID) + return applyDisable(TargetID, DisableCopyProp); + + return TargetID; +} + /// Add a pass to the PassManager if that pass is supposed to be run. If the /// Started/Stopped flags indicate either that the compilation should start at /// a later pass or that it should stop after an earlier pass, then do not add @@ -549,6 +533,15 @@ addPass(createVerifierPass()); } +void TargetPassConfig::addPostRASched() { + if (getOptLevel() != CodeGenOpt::None) { + if (MISchedPostRA) + addPass(&PostMachineSchedulerID); + else + addPass(&PostRASchedulerID); + } +} + /// Add the complete set of target-independent postISel code generator passes. /// /// This can be read as the standard order of major LLVM CodeGen stages. Stages @@ -636,15 +629,7 @@ addPass(&ImplicitNullChecksID); // Second pass scheduler. - // Let Target optionally insert this pass by itself at some other - // point. - if (getOptLevel() != CodeGenOpt::None && - !TM->targetSchedulesPostRAScheduling()) { - if (MISchedPostRA) - addPass(&PostMachineSchedulerID); - else - addPass(&PostRASchedulerID); - } + addPostRASched(); // GC if (addGCPasses()) { Index: lib/Target/PowerPC/PPCTargetMachine.cpp =================================================================== --- lib/Target/PowerPC/PPCTargetMachine.cpp +++ lib/Target/PowerPC/PPCTargetMachine.cpp @@ -26,8 +26,11 @@ #include "llvm/Support/TargetRegistry.h" #include "llvm/Target/TargetOptions.h" #include "llvm/Transforms/Scalar.h" + using namespace llvm; +extern cl::opt DisablePostRA; + static cl:: opt DisableCTRLoops("disable-ppc-ctrloops", cl::Hidden, cl::desc("Disable CTR loops for PPC")); @@ -295,6 +298,12 @@ void addPreRegAlloc() override; void addPreSched2() override; void addPreEmitPass() override; + void addPostRASched() override; + +protected: + IdentifyingPassPtr overridePass(AnalysisID StandardID, + IdentifyingPassPtr TargetID) const override; + }; } // namespace @@ -423,3 +432,32 @@ return TargetTransformInfo(PPCTTIImpl(this, F)); }); } + +void PPCPassConfig::addPostRASched() { + if (getOptLevel() != CodeGenOpt::None) { + if (!isPassSubstitutedOrOverridden(&llvm::PostMachineSchedulerID)) + addPass(llvm::createPostMachineScheduler([](const MachineFunction &MF) { + auto Direc = MF.getSubtarget().getDarwinDirective(); + return Direc == PPC::DIR_PWR9; + })); + + if (!isPassSubstitutedOrOverridden(&llvm::PostRASchedulerID)) + addPass(llvm::createPostRAScheduler([](const MachineFunction &MF) { + auto Direc = MF.getSubtarget().getDarwinDirective(); + return Direc != PPC::DIR_PWR9; + })); + } +} + +IdentifyingPassPtr +PPCPassConfig::overridePass(AnalysisID StandardID, + IdentifyingPassPtr TargetID) const { + // Since we have two different PostRA schedulers in PPC backend, we need this + // extra code here to make sure -diable-post-ra option turns off post ra + // scheduling fully even for some special circumstances. For example if user + // compiles the code with -mcpu=pwr9 but some functions have target-cpu=pwr8. + if (StandardID == &llvm::PostMachineSchedulerID) + return applyDisable(TargetID, DisablePostRA); + + return TargetPassConfig::overridePass(StandardID, TargetID); +} Index: lib/Target/SystemZ/SystemZTargetMachine.h =================================================================== --- lib/Target/SystemZ/SystemZTargetMachine.h +++ lib/Target/SystemZ/SystemZTargetMachine.h @@ -44,8 +44,6 @@ return TLOF.get(); } - bool targetSchedulesPostRAScheduling() const override { return true; }; - }; } // end namespace llvm Index: lib/Target/SystemZ/SystemZTargetMachine.cpp =================================================================== --- lib/Target/SystemZ/SystemZTargetMachine.cpp +++ lib/Target/SystemZ/SystemZTargetMachine.cpp @@ -124,6 +124,8 @@ bool addInstSelector() override; void addPreSched2() override; void addPreEmitPass() override; + // Overriding to empty function to schedule post-ra scheduler differently. + void addPostRASched() override {}; }; } // end anonymous namespace