summaryrefslogtreecommitdiffstats
path: root/llvm/include
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/include')
-rw-r--r--llvm/include/llvm/IR/PassManager.h34
-rw-r--r--llvm/include/llvm/Passes/PassBuilder.h28
2 files changed, 52 insertions, 10 deletions
diff --git a/llvm/include/llvm/IR/PassManager.h b/llvm/include/llvm/IR/PassManager.h
index 2ceb53d21b7..9b0301b4a66 100644
--- a/llvm/include/llvm/IR/PassManager.h
+++ b/llvm/include/llvm/IR/PassManager.h
@@ -342,14 +342,34 @@ public:
/// \brief Register an analysis pass with the manager.
///
- /// This provides an initialized and set-up analysis pass to the analysis
- /// manager. Whomever is setting up analysis passes must use this to populate
- /// the manager with all of the analysis passes available.
- template <typename PassT> void registerPass(PassT Pass) {
- assert(!AnalysisPasses.count(PassT::ID()) &&
- "Registered the same analysis pass twice!");
+ /// The argument is a callable whose result is a pass. This allows passing in
+ /// a lambda to construct the pass.
+ ///
+ /// The pass type registered is the result type of calling the argument. If
+ /// that pass has already been registered, then the argument will not be
+ /// called and this function will return false. Otherwise, the pass type
+ /// becomes registered, with the instance provided by calling the argument
+ /// once, and this function returns true.
+ ///
+ /// While this returns whether or not the pass type was already registered,
+ /// there in't an independent way to query that as that would be prone to
+ /// risky use when *querying* the analysis manager. Instead, the only
+ /// supported use case is avoiding duplicate registry of an analysis. This
+ /// interface also lends itself to minimizing the number of times we have to
+ /// do lookups for analyses or construct complex passes only to throw them
+ /// away.
+ template <typename PassBuilderT> bool registerPass(PassBuilderT PassBuilder) {
+ typedef decltype(PassBuilder()) PassT;
typedef detail::AnalysisPassModel<IRUnitT, PassT> PassModelT;
- AnalysisPasses[PassT::ID()].reset(new PassModelT(std::move(Pass)));
+
+ auto &PassPtr = AnalysisPasses[PassT::ID()];
+ if (PassPtr)
+ // Already registered this pass type!
+ return false;
+
+ // Construct a new model around the instance returned by the builder.
+ PassPtr.reset(new PassModelT(PassBuilder()));
+ return true;
}
/// \brief Invalidate a specific analysis pass for an IR module.
diff --git a/llvm/include/llvm/Passes/PassBuilder.h b/llvm/include/llvm/Passes/PassBuilder.h
index 1e605e37417..8b182e1955e 100644
--- a/llvm/include/llvm/Passes/PassBuilder.h
+++ b/llvm/include/llvm/Passes/PassBuilder.h
@@ -21,6 +21,7 @@
#include "llvm/IR/PassManager.h"
namespace llvm {
+class AAManager;
class TargetMachine;
/// \brief This class provides access to building LLVM's passes.
@@ -39,21 +40,24 @@ public:
///
/// This is an interface that can be used to populate a \c
/// ModuleAnalysisManager with all registered module analyses. Callers can
- /// still manually register any additional analyses.
+ /// still manually register any additional analyses. Callers can also
+ /// pre-register analyses and this will not override those.
void registerModuleAnalyses(ModuleAnalysisManager &MAM);
/// \brief Registers all available CGSCC analysis passes.
///
/// This is an interface that can be used to populate a \c CGSCCAnalysisManager
/// with all registered CGSCC analyses. Callers can still manually register any
- /// additional analyses.
+ /// additional analyses. Callers can also pre-register analyses and this will
+ /// not override those.
void registerCGSCCAnalyses(CGSCCAnalysisManager &CGAM);
/// \brief Registers all available function analysis passes.
///
/// This is an interface that can be used to populate a \c
/// FunctionAnalysisManager with all registered function analyses. Callers can
- /// still manually register any additional analyses.
+ /// still manually register any additional analyses. Callers can also
+ /// pre-register analyses and this will not override those.
void registerFunctionAnalyses(FunctionAnalysisManager &FAM);
/// \brief Parse a textual pass pipeline description into a \c ModulePassManager.
@@ -87,10 +91,28 @@ public:
bool parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText,
bool VerifyEachPass = true, bool DebugLogging = false);
+ /// Parse a textual alias analysis pipeline into the provided AA manager.
+ ///
+ /// The format of the textual AA pipeline is a comma separated list of AA
+ /// pass names:
+ ///
+ /// basic-aa,globals-aa,...
+ ///
+ /// The AA manager is set up such that the provided alias analyses are tried
+ /// in the order specified. See the \c AAManaager documentation for details
+ /// about the logic used. This routine just provides the textual mapping
+ /// between AA names and the analyses to register with the manager.
+ ///
+ /// Returns false if the text cannot be parsed cleanly. The specific state of
+ /// the \p AA manager is unspecified if such an error is encountered and this
+ /// returns false.
+ bool parseAAPipeline(AAManager &AA, StringRef PipelineText);
+
private:
bool parseModulePassName(ModulePassManager &MPM, StringRef Name);
bool parseCGSCCPassName(CGSCCPassManager &CGPM, StringRef Name);
bool parseFunctionPassName(FunctionPassManager &FPM, StringRef Name);
+ bool parseAAPassName(AAManager &AA, StringRef Name);
bool parseFunctionPassPipeline(FunctionPassManager &FPM,
StringRef &PipelineText, bool VerifyEachPass,
bool DebugLogging);
OpenPOWER on IntegriCloud