Index: include/llvm/CodeGen/MachineFunctionPass.h =================================================================== --- include/llvm/CodeGen/MachineFunctionPass.h +++ include/llvm/CodeGen/MachineFunctionPass.h @@ -64,6 +64,10 @@ return MachineFunctionProperties(); } + // This overloads skipFunction and looks at MachineFunction Instead of + // Function. In particular this calls a subtarget callback. + using FunctionPass::skipFunction; + bool skipFunction(const MachineFunction &F) const; private: MachineFunctionProperties RequiredProperties; MachineFunctionProperties SetProperties; Index: include/llvm/CodeGen/TargetPassConfig.h =================================================================== --- include/llvm/CodeGen/TargetPassConfig.h +++ include/llvm/CodeGen/TargetPassConfig.h @@ -253,6 +253,10 @@ /// Fully developed targets will not generally override this. virtual void addMachinePasses(); + // Targets that require specialized method for adding PostRA + // scheduling can override this. + virtual void addPostRASchedPass(); + /// 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 +406,12 @@ /// addMachinePasses helper to create the target-selected or overriden /// regalloc pass. FunctionPass *createRegAllocPass(bool Optimized); + + virtual IdentifyingPassPtr overridePass(AnalysisID StandardID, + IdentifyingPassPtr TargetID) const; + + IdentifyingPassPtr applyDisable(IdentifyingPassPtr PassID, + bool Override) const; }; } // end namespace llvm Index: include/llvm/Pass.h =================================================================== --- include/llvm/Pass.h +++ include/llvm/Pass.h @@ -317,6 +317,8 @@ /// Optional passes call this function to check whether the pass should be /// skipped. This is the case when Attribute::OptimizeNone is set or when /// optimization bisect is over the limit. + /// Note that this function has an overload in MachineFunctionPass that + /// takes a MachineFunction parameter. bool skipFunction(const Function &F) const; }; Index: include/llvm/Target/TargetSubtargetInfo.h =================================================================== --- include/llvm/Target/TargetSubtargetInfo.h +++ include/llvm/Target/TargetSubtargetInfo.h @@ -221,6 +221,13 @@ /// Please use MachineRegisterInfo::subRegLivenessEnabled() instead where /// possible. virtual bool enableSubRegLiveness() const { return false; } + + /// Allows to check whether a pass should run on this subtarget or not. + /// For example different PPC subtargets use different PostRA schedulers and + /// each function can override its target-cpu. So each of the PostRASched + /// passes should ask the function's subtarget whether they should run or not. + /// This is called from MachineFunctionPass' overload of skipFunction. + virtual bool runPass(const AnalysisID) const { return true; } }; } // End llvm namespace Index: lib/CodeGen/MachineFunctionPass.cpp =================================================================== --- lib/CodeGen/MachineFunctionPass.cpp +++ lib/CodeGen/MachineFunctionPass.cpp @@ -27,6 +27,7 @@ #include "llvm/CodeGen/StackProtector.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/Function.h" +#include "llvm/Target/TargetSubtargetInfo.h" using namespace llvm; @@ -89,3 +90,11 @@ FunctionPass::getAnalysisUsage(AU); } + +bool MachineFunctionPass::skipFunction(const MachineFunction &MF) const { + if (!MF.getSubtarget().runPass(this->getPassID())) + return true; + + return FunctionPass::skipFunction(*MF.getFunction()); +} + Index: lib/CodeGen/MachineScheduler.cpp =================================================================== --- lib/CodeGen/MachineScheduler.cpp +++ lib/CodeGen/MachineScheduler.cpp @@ -359,7 +359,8 @@ } bool PostMachineScheduler::runOnMachineFunction(MachineFunction &mf) { - if (skipFunction(*mf.getFunction())) + + if (skipFunction(mf)) return false; if (EnablePostRAMachineSched.getNumOccurrences()) { Index: lib/CodeGen/PostRASchedulerList.cpp =================================================================== --- lib/CodeGen/PostRASchedulerList.cpp +++ lib/CodeGen/PostRASchedulerList.cpp @@ -280,7 +280,7 @@ } bool PostRAScheduler::runOnMachineFunction(MachineFunction &Fn) { - if (skipFunction(*Fn.getFunction())) + if (skipFunction(Fn)) return false; TII = Fn.getSubtarget().getInstrInfo(); Index: lib/CodeGen/TargetPassConfig.cpp =================================================================== --- lib/CodeGen/TargetPassConfig.cpp +++ lib/CodeGen/TargetPassConfig.cpp @@ -38,7 +38,7 @@ using namespace llvm; -static cl::opt<bool> DisablePostRA("disable-post-ra", cl::Hidden, +cl::opt<bool> DisablePostRA("disable-post-ra", cl::Hidden, cl::desc("Disable Post Regalloc")); static cl::opt<bool> DisableBranchFold("disable-branch-fold", cl::Hidden, cl::desc("Disable branch folding")); @@ -131,72 +131,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 +272,73 @@ FinalPtr.getID() != ID; } +/// 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 TargetPassConfig::applyDisable(IdentifyingPassPtr PassID, + bool Override) const { + 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. +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 +551,20 @@ addPass(createVerifierPass()); } +void TargetPassConfig::addPostRASchedPass() { + // 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); + } +} + /// 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 @@ -635,17 +651,7 @@ if (EnableImplicitNullChecks) 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); - } - + addPostRASchedPass(); // GC if (addGCPasses()) { if (PrintGCInfo) Index: lib/Target/PowerPC/PPCSubtarget.h =================================================================== --- lib/Target/PowerPC/PPCSubtarget.h +++ lib/Target/PowerPC/PPCSubtarget.h @@ -316,6 +316,8 @@ /// classifyGlobalReference - Classify a global variable reference for the /// current subtarget accourding to how we should reference it. unsigned char classifyGlobalReference(const GlobalValue *GV) const; + + bool runPass(const AnalysisID PassID) const override; }; } // End llvm namespace Index: lib/Target/PowerPC/PPCSubtarget.cpp =================================================================== --- lib/Target/PowerPC/PPCSubtarget.cpp +++ lib/Target/PowerPC/PPCSubtarget.cpp @@ -250,3 +250,13 @@ bool PPCSubtarget::isELFv2ABI() const { return TM.isELFv2ABI(); } bool PPCSubtarget::isPPC64() const { return TM.isPPC64(); } + +bool PPCSubtarget::runPass(const AnalysisID PassID) const { + + switch (DarwinDirective) { + default: + return PassID != &llvm::PostMachineSchedulerID; + case PPC::DIR_PWR9: + return PassID != &llvm::PostRASchedulerID; + } +} Index: lib/Target/PowerPC/PPCTargetMachine.cpp =================================================================== --- lib/Target/PowerPC/PPCTargetMachine.cpp +++ lib/Target/PowerPC/PPCTargetMachine.cpp @@ -28,6 +28,8 @@ #include "llvm/Transforms/Scalar.h" using namespace llvm; +extern cl::opt<bool> DisablePostRA; + static cl:: opt<bool> DisableCTRLoops("disable-ppc-ctrloops", cl::Hidden, cl::desc("Disable CTR loops for PPC")); @@ -295,6 +297,12 @@ void addPreRegAlloc() override; void addPreSched2() override; void addPreEmitPass() override; + void addPostRASchedPass() override; + +protected: + IdentifyingPassPtr overridePass(AnalysisID StandardID, + IdentifyingPassPtr TargetID) const override; + }; } // namespace @@ -423,3 +431,24 @@ return TargetTransformInfo(PPCTTIImpl(this, F)); }); } + +void PPCPassConfig::addPostRASchedPass() { + if (getOptLevel() != CodeGenOpt::None && + !TM->targetSchedulesPostRAScheduling()) { + addPass(&PostMachineSchedulerID); + addPass(&PostRASchedulerID); + } +} + +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); +}