diff --git a/llvm/include/llvm/Analysis/CGSCCPassManager.h b/llvm/include/llvm/Analysis/CGSCCPassManager.h --- a/llvm/include/llvm/Analysis/CGSCCPassManager.h +++ b/llvm/include/llvm/Analysis/CGSCCPassManager.h @@ -327,7 +327,8 @@ /// within this run safely. template class ModuleToPostOrderCGSCCPassAdaptor - : public PassInfoMixin> { + : public RequiredPassInfoMixin< + ModuleToPostOrderCGSCCPassAdaptor> { public: explicit ModuleToPostOrderCGSCCPassAdaptor(CGSCCPassT Pass) : Pass(std::move(Pass)) {} @@ -444,7 +445,7 @@ /// within this run safely. template class CGSCCToFunctionPassAdaptor - : public PassInfoMixin> { + : public RequiredPassInfoMixin> { public: explicit CGSCCToFunctionPassAdaptor(FunctionPassT Pass) : Pass(std::move(Pass)) {} diff --git a/llvm/include/llvm/IR/PassManager.h b/llvm/include/llvm/IR/PassManager.h --- a/llvm/include/llvm/IR/PassManager.h +++ b/llvm/include/llvm/IR/PassManager.h @@ -370,6 +370,7 @@ /// passes. /// /// This provides some boilerplate for types that are passes. +/// Use this for optional (usually optimization) passes. template struct PassInfoMixin { /// Gets the name of the pass we are mixed into. static StringRef name() { @@ -380,6 +381,20 @@ Name = Name.drop_front(strlen("llvm::")); return Name; } + + /// This pass is not required to produce a valid executable. + /// Use RequiredPassInfoMixin for required passes. + static bool isRequired() { return false; } +}; + +/// A CRTP mix-in to automatically provide informational APIs needed for +/// passes. +/// +/// Use this for passes required to produce a valid executable. +template +struct RequiredPassInfoMixin : PassInfoMixin { + /// This pass is required to produce a valid executable. + static bool isRequired() { return true; } }; /// A CRTP mix-in that provides informational APIs needed for analysis passes. @@ -462,7 +477,7 @@ template , typename... ExtraArgTs> -class PassManager : public PassInfoMixin< +class PassManager : public RequiredPassInfoMixin< PassManager> { public: /// Construct a pass manager. @@ -1207,7 +1222,7 @@ /// may be stale. Function analyses will not be stale. template class ModuleToFunctionPassAdaptor - : public PassInfoMixin> { + : public RequiredPassInfoMixin> { public: explicit ModuleToFunctionPassAdaptor(FunctionPassT Pass) : Pass(std::move(Pass)) {} diff --git a/llvm/include/llvm/IR/PassManagerInternal.h b/llvm/include/llvm/IR/PassManagerInternal.h --- a/llvm/include/llvm/IR/PassManagerInternal.h +++ b/llvm/include/llvm/IR/PassManagerInternal.h @@ -48,6 +48,11 @@ /// Polymorphic method to access the name of a pass. virtual StringRef name() const = 0; + + /// Whether or not this pass is required to create executable code. + /// + /// Used for optnone and opt-bisect. + virtual bool isRequired() const = 0; }; /// A template wrapper used to implement the polymorphic API. @@ -81,6 +86,8 @@ StringRef name() const override { return PassT::name(); } + bool isRequired() const override { return PassT::isRequired(); } + PassT Pass; }; diff --git a/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h b/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h --- a/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h +++ b/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h @@ -229,7 +229,7 @@ /// LoopAnalysisManager to be used within this run safely. template class FunctionToLoopPassAdaptor - : public PassInfoMixin> { + : public RequiredPassInfoMixin> { public: explicit FunctionToLoopPassAdaptor(LoopPassT Pass, bool UseMemorySSA = false, bool DebugLogging = false) diff --git a/polly/include/polly/ScopPass.h b/polly/include/polly/ScopPass.h --- a/polly/include/polly/ScopPass.h +++ b/polly/include/polly/ScopPass.h @@ -204,7 +204,7 @@ template class FunctionToScopPassAdaptor - : public PassInfoMixin> { + : public RequiredPassInfoMixin> { public: explicit FunctionToScopPassAdaptor(ScopPassT Pass) : Pass(std::move(Pass)) {}