Index: llvm/trunk/include/llvm/IR/LLVMContext.h =================================================================== --- llvm/trunk/include/llvm/IR/LLVMContext.h +++ llvm/trunk/include/llvm/IR/LLVMContext.h @@ -31,7 +31,7 @@ class Instruction; class LLVMContextImpl; class Module; -class OptBisect; +class OptPassGate; template class SmallVectorImpl; class SMDiagnostic; class StringRef; @@ -317,7 +317,8 @@ /// \brief Access the object which manages optimization bisection for failure /// analysis. - OptBisect &getOptBisect(); + OptPassGate &getOptPassGate(); + private: // Module needs access to the add/removeModule methods. friend class Module; Index: llvm/trunk/include/llvm/IR/OptBisect.h =================================================================== --- llvm/trunk/include/llvm/IR/OptBisect.h +++ llvm/trunk/include/llvm/IR/OptBisect.h @@ -20,12 +20,32 @@ namespace llvm { class Pass; +class Module; +class Function; +class BasicBlock; +class Region; +class Loop; +class CallGraphSCC; + +/// Extensions to this class implement mechanisms to disable passes and +/// individual optimizations at compile time. +class OptPassGate { +public: + virtual ~OptPassGate() = default; + + virtual bool shouldRunPass(const Pass *P, const Module &U) { return true; } + virtual bool shouldRunPass(const Pass *P, const Function &U) {return true; } + virtual bool shouldRunPass(const Pass *P, const BasicBlock &U) { return true; } + virtual bool shouldRunPass(const Pass *P, const Region &U) { return true; } + virtual bool shouldRunPass(const Pass *P, const Loop &U) { return true; } + virtual bool shouldRunPass(const Pass *P, const CallGraphSCC &U) { return true; } +}; /// This class implements a mechanism to disable passes and individual /// optimizations at compile time based on a command line option /// (-opt-bisect-limit) in order to perform a bisecting search for /// optimization-related problems. -class OptBisect { +class OptBisect : public OptPassGate { public: /// \brief Default constructor, initializes the OptBisect state based on the /// -opt-bisect-limit command line argument. @@ -36,20 +56,26 @@ /// through LLVMContext. OptBisect(); + virtual ~OptBisect() = default; + /// Checks the bisect limit to determine if the specified pass should run. /// - /// This function will immediate return true if bisection is disabled. If the - /// bisect limit is set to -1, the function will print a message describing + /// These functions immediately return true if bisection is disabled. If the + /// bisect limit is set to -1, the functions print a message describing /// the pass and the bisect number assigned to it and return true. Otherwise, - /// the function will print a message with the bisect number assigned to the + /// the functions print a message with the bisect number assigned to the /// pass and indicating whether or not the pass will be run and return true if - /// the bisect limit has not yet been exceded or false if it has. + /// the bisect limit has not yet been exceeded or false if it has. /// - /// Most passes should not call this routine directly. Instead, it is called - /// through a helper routine provided by the pass base class. For instance, - /// function passes should call FunctionPass::skipFunction(). - template - bool shouldRunPass(const Pass *P, const UnitT &U); + /// Most passes should not call these routines directly. Instead, they are + /// called through helper routines provided by the pass base classes. For + /// instance, function passes should call FunctionPass::skipFunction(). + bool shouldRunPass(const Pass *P, const Module &U) override; + bool shouldRunPass(const Pass *P, const Function &U) override; + bool shouldRunPass(const Pass *P, const BasicBlock &U) override; + bool shouldRunPass(const Pass *P, const Region &U) override; + bool shouldRunPass(const Pass *P, const Loop &U) override; + bool shouldRunPass(const Pass *P, const CallGraphSCC &U) override; private: bool checkPass(const StringRef PassName, const StringRef TargetDesc); Index: llvm/trunk/lib/Analysis/CallGraphSCCPass.cpp =================================================================== --- llvm/trunk/lib/Analysis/CallGraphSCCPass.cpp +++ llvm/trunk/lib/Analysis/CallGraphSCCPass.cpp @@ -648,7 +648,7 @@ bool CallGraphSCCPass::skipSCC(CallGraphSCC &SCC) const { return !SCC.getCallGraph().getModule() .getContext() - .getOptBisect() + .getOptPassGate() .shouldRunPass(this, SCC); } Index: llvm/trunk/lib/Analysis/LoopPass.cpp =================================================================== --- llvm/trunk/lib/Analysis/LoopPass.cpp +++ llvm/trunk/lib/Analysis/LoopPass.cpp @@ -357,7 +357,7 @@ return false; // Check the opt bisect limit. LLVMContext &Context = F->getContext(); - if (!Context.getOptBisect().shouldRunPass(this, *L)) + if (!Context.getOptPassGate().shouldRunPass(this, *L)) return true; // Check for the OptimizeNone attribute. if (F->hasFnAttribute(Attribute::OptimizeNone)) { Index: llvm/trunk/lib/Analysis/RegionPass.cpp =================================================================== --- llvm/trunk/lib/Analysis/RegionPass.cpp +++ llvm/trunk/lib/Analysis/RegionPass.cpp @@ -283,7 +283,7 @@ bool RegionPass::skipRegion(Region &R) const { Function &F = *R.getEntry()->getParent(); - if (!F.getContext().getOptBisect().shouldRunPass(this, R)) + if (!F.getContext().getOptPassGate().shouldRunPass(this, R)) return true; if (F.hasFnAttribute(Attribute::OptimizeNone)) { Index: llvm/trunk/lib/IR/LLVMContext.cpp =================================================================== --- llvm/trunk/lib/IR/LLVMContext.cpp +++ llvm/trunk/lib/IR/LLVMContext.cpp @@ -332,8 +332,8 @@ pImpl->DiscardValueNames = Discard; } -OptBisect &LLVMContext::getOptBisect() { - return pImpl->getOptBisect(); +OptPassGate &LLVMContext::getOptPassGate() { + return pImpl->getOptPassGate(); } const DiagnosticHandler *LLVMContext::getDiagHandlerPtr() const { Index: llvm/trunk/lib/IR/LLVMContextImpl.h =================================================================== --- llvm/trunk/lib/IR/LLVMContextImpl.h +++ llvm/trunk/lib/IR/LLVMContextImpl.h @@ -1357,7 +1357,7 @@ /// \brief Access the object which manages optimization bisection for failure /// analysis. - OptBisect &getOptBisect(); + OptPassGate &getOptPassGate(); }; } // end namespace llvm Index: llvm/trunk/lib/IR/LLVMContextImpl.cpp =================================================================== --- llvm/trunk/lib/IR/LLVMContextImpl.cpp +++ llvm/trunk/lib/IR/LLVMContextImpl.cpp @@ -222,8 +222,8 @@ /// Singleton instance of the OptBisect class. /// -/// This singleton is accessed via the LLVMContext::getOptBisect() function. It -/// provides a mechanism to disable passes and individual optimizations at +/// This singleton is accessed via the LLVMContext::getOptPassGate() function. +/// It provides a mechanism to disable passes and individual optimizations at /// compile time based on a command line option (-opt-bisect-limit) in order to /// perform a bisecting search for optimization-related problems. /// @@ -233,6 +233,6 @@ /// enabled in order to enable a consistent bisect count. static ManagedStatic OptBisector; -OptBisect &LLVMContextImpl::getOptBisect() { +OptPassGate &LLVMContextImpl::getOptPassGate() { return *OptBisector; } Index: llvm/trunk/lib/IR/OptBisect.cpp =================================================================== --- llvm/trunk/lib/IR/OptBisect.cpp +++ llvm/trunk/lib/IR/OptBisect.cpp @@ -36,7 +36,7 @@ cl::Optional, cl::desc("Maximum optimization to perform")); -OptBisect::OptBisect() { +OptBisect::OptBisect() : OptPassGate() { BisectEnabled = OptBisectLimit != std::numeric_limits::max(); } @@ -92,19 +92,28 @@ return Desc; } -// Force instantiations. -template bool OptBisect::shouldRunPass(const Pass *, const Module &); -template bool OptBisect::shouldRunPass(const Pass *, const Function &); -template bool OptBisect::shouldRunPass(const Pass *, const BasicBlock &); -template bool OptBisect::shouldRunPass(const Pass *, const Loop &); -template bool OptBisect::shouldRunPass(const Pass *, const CallGraphSCC &); -template bool OptBisect::shouldRunPass(const Pass *, const Region &); - -template -bool OptBisect::shouldRunPass(const Pass *P, const UnitT &U) { - if (!BisectEnabled) - return true; - return checkPass(P->getPassName(), getDescription(U)); +bool OptBisect::shouldRunPass(const Pass *P, const Module &U) { + return !BisectEnabled || checkPass(P->getPassName(), getDescription(U)); +} + +bool OptBisect::shouldRunPass(const Pass *P, const Function &U) { + return !BisectEnabled || checkPass(P->getPassName(), getDescription(U)); +} + +bool OptBisect::shouldRunPass(const Pass *P, const BasicBlock &U) { + return !BisectEnabled || checkPass(P->getPassName(), getDescription(U)); +} + +bool OptBisect::shouldRunPass(const Pass *P, const Region &U) { + return !BisectEnabled || checkPass(P->getPassName(), getDescription(U)); +} + +bool OptBisect::shouldRunPass(const Pass *P, const Loop &U) { + return !BisectEnabled || checkPass(P->getPassName(), getDescription(U)); +} + +bool OptBisect::shouldRunPass(const Pass *P, const CallGraphSCC &U) { + return !BisectEnabled || checkPass(P->getPassName(), getDescription(U)); } bool OptBisect::checkPass(const StringRef PassName, Index: llvm/trunk/lib/IR/Pass.cpp =================================================================== --- llvm/trunk/lib/IR/Pass.cpp +++ llvm/trunk/lib/IR/Pass.cpp @@ -56,7 +56,7 @@ } bool ModulePass::skipModule(Module &M) const { - return !M.getContext().getOptBisect().shouldRunPass(this, M); + return !M.getContext().getOptPassGate().shouldRunPass(this, M); } bool Pass::mustPreserveAnalysisID(char &AID) const { @@ -155,7 +155,7 @@ } bool FunctionPass::skipFunction(const Function &F) const { - if (!F.getContext().getOptBisect().shouldRunPass(this, F)) + if (!F.getContext().getOptPassGate().shouldRunPass(this, F)) return true; if (F.hasFnAttribute(Attribute::OptimizeNone)) { @@ -189,7 +189,7 @@ const Function *F = BB.getParent(); if (!F) return false; - if (!F->getContext().getOptBisect().shouldRunPass(this, BB)) + if (!F->getContext().getOptPassGate().shouldRunPass(this, BB)) return true; if (F->hasFnAttribute(Attribute::OptimizeNone)) { // Report this only once per function.