Index: include/llvm/CodeGen/MachineFunctionPass.h =================================================================== --- include/llvm/CodeGen/MachineFunctionPass.h +++ include/llvm/CodeGen/MachineFunctionPass.h @@ -30,6 +30,9 @@ /// override runOnMachineFunction. class MachineFunctionPass : public FunctionPass { public: + + static char ID; + bool doInitialization(Module&) override { // Cache the properties info at module-init time so we don't have to // construct them for every function. @@ -64,6 +67,12 @@ return MachineFunctionProperties(); } + virtual char &getPassID() const { + return MachineFunctionPass::ID; + } + + using FunctionPass::skipFunction; + bool skipFunction(const MachineFunction &F) const; private: MachineFunctionProperties RequiredProperties; MachineFunctionProperties SetProperties; Index: include/llvm/CodeGen/Passes.h =================================================================== --- include/llvm/CodeGen/Passes.h +++ include/llvm/CodeGen/Passes.h @@ -73,6 +73,10 @@ /// MachineLoopInfo - This pass is a loop analysis pass. extern char &MachineLoopInfoID; + /// MachineFunctionPassID - This is a MachineFunctionPassID and we do not have + /// any more information about it. + extern char &MachineFunctionPassID; + /// MachineDominators - This pass is a machine dominators analysis pass. extern char &MachineDominatorsID; Index: include/llvm/CodeGen/TargetPassConfig.h =================================================================== --- include/llvm/CodeGen/TargetPassConfig.h +++ include/llvm/CodeGen/TargetPassConfig.h @@ -248,6 +248,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. @@ -397,6 +401,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/Target/TargetSubtargetInfo.h =================================================================== --- include/llvm/Target/TargetSubtargetInfo.h +++ include/llvm/Target/TargetSubtargetInfo.h @@ -221,6 +221,12 @@ /// 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 CPUs 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. + virtual bool runPass(char &PassID) const {return true;} }; } // End llvm namespace Index: lib/CodeGen/MachineFunctionPass.cpp =================================================================== --- lib/CodeGen/MachineFunctionPass.cpp +++ lib/CodeGen/MachineFunctionPass.cpp @@ -27,9 +27,14 @@ #include "llvm/CodeGen/StackProtector.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/Function.h" +#include "llvm/Target/TargetSubtargetInfo.h" using namespace llvm; +char MachineFunctionPass::ID = 0; + +char &llvm::MachineFunctionPassID = MachineFunctionPass::ID; + Pass *MachineFunctionPass::createPrinterPass(raw_ostream &O, const std::string &Banner) const { return createMachineFunctionPrinterPass(O, Banner); @@ -89,3 +94,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 @@ -148,6 +148,9 @@ protected: ScheduleDAGInstrs *createPostMachineScheduler(); + char &getPassID() const override { + return PostMachineScheduler::ID; + } }; } // namespace @@ -359,7 +362,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 @@ -103,6 +103,11 @@ bool runOnMachineFunction(MachineFunction &Fn) override; + protected: + char &getPassID() const override { + return PostRAScheduler::ID; + } + private: bool enablePostRAScheduler( const TargetSubtargetInfo &ST, CodeGenOpt::Level OptLevel, @@ -280,7 +285,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 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")); @@ -132,72 +132,7 @@ "Enable both variants of CFL-AA"), clEnumValEnd)); -/// 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 @@ -327,6 +262,7 @@ IdentifyingPassPtr TargetPassConfig::getPassSubstitution(AnalysisID ID) const { DenseMap::const_iterator I = Impl->TargetPasses.find(ID); + if (I == Impl->TargetPasses.end()) return ID; return I->second; @@ -339,6 +275,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 +552,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 +652,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 @@ -313,6 +313,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(char &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,15 @@ bool PPCSubtarget::isELFv2ABI() const { return TM.isELFv2ABI(); } bool PPCSubtarget::isPPC64() const { return TM.isPPC64(); } + +bool PPCSubtarget::runPass(char &PassID) const { + + switch (DarwinDirective) { + default: + return &PassID != &llvm::PostMachineSchedulerID; + case PPC::DIR_PWR9: + return &PassID != &llvm::PostRASchedulerID; + } + + llvm_unreachable("Unknown reason!"); +} 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 DisablePostRA; + static cl:: opt DisableCTRLoops("disable-ppc-ctrloops", cl::Hidden, cl::desc("Disable CTR loops for PPC")); @@ -312,6 +314,12 @@ void addPreRegAlloc() override; void addPreSched2() override; void addPreEmitPass() override; + void addPostRASchedPass() override; + +protected: + IdentifyingPassPtr overridePass(AnalysisID StandardID, + IdentifyingPassPtr TargetID) const override; + }; } // namespace @@ -440,3 +448,19 @@ 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{ + if (StandardID == &llvm::PostMachineSchedulerID) + return applyDisable(TargetID, DisablePostRA); + + return TargetPassConfig::overridePass(StandardID, TargetID); +}