summaryrefslogtreecommitdiff
path: root/include/llvm/IR/PassManager.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/IR/PassManager.h')
-rw-r--r--include/llvm/IR/PassManager.h364
1 files changed, 230 insertions, 134 deletions
diff --git a/include/llvm/IR/PassManager.h b/include/llvm/IR/PassManager.h
index 2ceb53d21b7a9..402d04a54a412 100644
--- a/include/llvm/IR/PassManager.h
+++ b/include/llvm/IR/PassManager.h
@@ -44,8 +44,8 @@
#include "llvm/IR/Function.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PassManagerInternal.h"
-#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/TypeName.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/type_traits.h"
#include <list>
@@ -54,9 +54,6 @@
namespace llvm {
-class Module;
-class Function;
-
/// \brief An abstract set of preserved analyses following a transformation pass
/// run.
///
@@ -147,6 +144,16 @@ public:
PreservedPassIDs.count(PassID);
}
+ /// \brief Query whether all of the analyses in the set are preserved.
+ bool preserved(PreservedAnalyses Arg) {
+ if (Arg.areAllPreserved())
+ return areAllPreserved();
+ for (void *P : Arg.PreservedPassIDs)
+ if (!preserved(P))
+ return false;
+ return true;
+ }
+
/// \brief Test whether all passes are preserved.
///
/// This is used primarily to optimize for the case of no changes which will
@@ -166,6 +173,44 @@ private:
// Forward declare the analysis manager template.
template <typename IRUnitT> class AnalysisManager;
+/// A CRTP mix-in to automatically provide informational APIs needed for
+/// passes.
+///
+/// This provides some boiler plate for types that are passes.
+template <typename DerivedT> struct PassInfoMixin {
+ /// Returns the name of the derived pass type.
+ static StringRef name() {
+ StringRef Name = getTypeName<DerivedT>();
+ if (Name.startswith("llvm::"))
+ Name = Name.drop_front(strlen("llvm::"));
+ return Name;
+ }
+};
+
+/// A CRTP mix-in to automatically provide informational APIs needed for
+/// analysis passes.
+///
+/// This provides some boiler plate for types that are analysis passes. It
+/// automatically mixes in \c PassInfoMixin and adds informational APIs
+/// specifically used for analyses.
+template <typename DerivedT>
+struct AnalysisInfoMixin : PassInfoMixin<DerivedT> {
+ /// Returns an opaque, unique ID for this pass type.
+ ///
+ /// Note that this requires the derived type provide a static member whose
+ /// address can be converted to a void pointer.
+ ///
+ /// FIXME: The only reason the derived type needs to provide this rather than
+ /// this mixin providing it is due to broken implementations which cannot
+ /// correctly unique a templated static so that they have the same addresses
+ /// for each instantiation and are definitively emitted once for each
+ /// instantiation. The only currently known platform with this limitation are
+ /// Windows DLL builds, specifically building each part of LLVM as a DLL. If
+ /// we ever remove that build configuration, this mixin can provide the
+ /// static PassID as well.
+ static void *ID() { return (void *)&DerivedT::PassID; }
+};
+
/// \brief Manages a sequence of passes over units of IR.
///
/// A pass manager contains a sequence of passes to run over units of IR. It is
@@ -177,7 +222,8 @@ template <typename IRUnitT> class AnalysisManager;
/// that analysis manager to each pass it runs, as well as calling the analysis
/// manager's invalidation routine with the PreservedAnalyses of each pass it
/// runs.
-template <typename IRUnitT> class PassManager {
+template <typename IRUnitT>
+class PassManager : public PassInfoMixin<PassManager<IRUnitT>> {
public:
/// \brief Construct a pass manager.
///
@@ -195,11 +241,11 @@ public:
}
/// \brief Run all of the passes in this manager over the IR.
- PreservedAnalyses run(IRUnitT &IR, AnalysisManager<IRUnitT> *AM = nullptr) {
+ PreservedAnalyses run(IRUnitT &IR, AnalysisManager<IRUnitT> &AM) {
PreservedAnalyses PA = PreservedAnalyses::all();
if (DebugLogging)
- dbgs() << "Starting pass manager run.\n";
+ dbgs() << "Starting " << getTypeName<IRUnitT>() << " pass manager run.\n";
for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) {
if (DebugLogging)
@@ -208,13 +254,11 @@ public:
PreservedAnalyses PassPA = Passes[Idx]->run(IR, AM);
- // If we have an active analysis manager at this level we want to ensure
- // we update it as each pass runs and potentially invalidates analyses.
- // We also update the preserved set of analyses based on what analyses we
- // have already handled the invalidation for here and don't need to
- // invalidate when finished.
- if (AM)
- PassPA = AM->invalidate(IR, std::move(PassPA));
+ // Update the analysis manager as each pass runs and potentially
+ // invalidates analyses. We also update the preserved set of analyses
+ // based on what analyses we have already handled the invalidation for
+ // here and don't need to invalidate when finished.
+ PassPA = AM.invalidate(IR, std::move(PassPA));
// Finally, we intersect the final preserved analyses to compute the
// aggregate preserved set for this pass manager.
@@ -228,7 +272,7 @@ public:
}
if (DebugLogging)
- dbgs() << "Finished pass manager run.\n";
+ dbgs() << "Finished " << getTypeName<IRUnitT>() << " pass manager run.\n";
return PA;
}
@@ -238,8 +282,6 @@ public:
Passes.emplace_back(new PassModelT(std::move(Pass)));
}
- static StringRef name() { return "PassManager"; }
-
private:
typedef detail::PassConcept<IRUnitT> PassConceptT;
@@ -252,9 +294,11 @@ private:
bool DebugLogging;
};
+extern template class PassManager<Module>;
/// \brief Convenience typedef for a pass manager over modules.
typedef PassManager<Module> ModulePassManager;
+extern template class PassManager<Function>;
/// \brief Convenience typedef for a pass manager over functions.
typedef PassManager<Function> FunctionPassManager;
@@ -284,8 +328,7 @@ template <typename DerivedT, typename IRUnitT> class AnalysisManagerBase {
}
AnalysisManagerBase(const AnalysisManagerBase &) = delete;
- AnalysisManagerBase &
- operator=(const AnalysisManagerBase &) = delete;
+ AnalysisManagerBase &operator=(const AnalysisManagerBase &) = delete;
protected:
typedef detail::AnalysisResultConcept<IRUnitT> ResultConceptT;
@@ -342,14 +385,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.
@@ -472,7 +535,7 @@ private:
if (DebugLogging)
dbgs() << "Running analysis: " << P.name() << "\n";
AnalysisResultListT &ResultList = AnalysisResultLists[&IR];
- ResultList.emplace_back(PassID, P.run(IR, this));
+ ResultList.emplace_back(PassID, P.run(IR, *this));
// P.run may have inserted elements into AnalysisResults and invalidated
// RI.
@@ -513,8 +576,8 @@ private:
return PA;
if (DebugLogging)
- dbgs() << "Invalidating all non-preserved analyses for: "
- << IR.getName() << "\n";
+ dbgs() << "Invalidating all non-preserved analyses for: " << IR.getName()
+ << "\n";
// Clear all the invalidated results associated specifically with this
// function.
@@ -574,7 +637,8 @@ private:
/// \brief Map type from a pair of analysis ID and function pointer to an
/// iterator into a particular result list.
typedef DenseMap<std::pair<void *, IRUnitT *>,
- typename AnalysisResultListT::iterator> AnalysisResultMapT;
+ typename AnalysisResultListT::iterator>
+ AnalysisResultMapT;
/// \brief Map from an analysis ID and function to a particular cached
/// analysis result.
@@ -584,9 +648,11 @@ private:
bool DebugLogging;
};
+extern template class AnalysisManager<Module>;
/// \brief Convenience typedef for the Module analysis manager.
typedef AnalysisManager<Module> ModuleAnalysisManager;
+extern template class AnalysisManager<Function>;
/// \brief Convenience typedef for the Function analysis manager.
typedef AnalysisManager<Function> FunctionAnalysisManager;
@@ -598,26 +664,80 @@ typedef AnalysisManager<Function> FunctionAnalysisManager;
/// never use a function analysis manager from within (transitively) a module
/// pass manager unless your parent module pass has received a proxy result
/// object for it.
-class FunctionAnalysisManagerModuleProxy {
+///
+/// Note that the proxy's result is a move-only object and represents ownership
+/// of the validity of the analyses in the \c FunctionAnalysisManager it
+/// provides.
+template <typename AnalysisManagerT, typename IRUnitT>
+class InnerAnalysisManagerProxy
+ : public AnalysisInfoMixin<
+ InnerAnalysisManagerProxy<AnalysisManagerT, IRUnitT>> {
public:
- class Result;
+ class Result {
+ public:
+ explicit Result(AnalysisManagerT &AM) : AM(&AM) {}
+ Result(Result &&Arg) : AM(std::move(Arg.AM)) {
+ // We have to null out the analysis manager in the moved-from state
+ // because we are taking ownership of the responsibilty to clear the
+ // analysis state.
+ Arg.AM = nullptr;
+ }
+ Result &operator=(Result &&RHS) {
+ AM = RHS.AM;
+ // We have to null out the analysis manager in the moved-from state
+ // because we are taking ownership of the responsibilty to clear the
+ // analysis state.
+ RHS.AM = nullptr;
+ return *this;
+ }
+ ~Result() {
+ // AM is cleared in a moved from state where there is nothing to do.
+ if (!AM)
+ return;
+
+ // Clear out the analysis manager if we're being destroyed -- it means we
+ // didn't even see an invalidate call when we got invalidated.
+ AM->clear();
+ }
- static void *ID() { return (void *)&PassID; }
+ /// \brief Accessor for the analysis manager.
+ AnalysisManagerT &getManager() { return *AM; }
+
+ /// \brief Handler for invalidation of the module.
+ ///
+ /// If this analysis itself is preserved, then we assume that the set of \c
+ /// Function objects in the \c Module hasn't changed and thus we don't need
+ /// to invalidate *all* cached data associated with a \c Function* in the \c
+ /// FunctionAnalysisManager.
+ ///
+ /// Regardless of whether this analysis is marked as preserved, all of the
+ /// analyses in the \c FunctionAnalysisManager are potentially invalidated
+ /// based on the set of preserved analyses.
+ bool invalidate(IRUnitT &IR, const PreservedAnalyses &PA) {
+ // If this proxy isn't marked as preserved, then we can't even invalidate
+ // individual function analyses, there may be an invalid set of Function
+ // objects in the cache making it impossible to incrementally preserve
+ // them. Just clear the entire manager.
+ if (!PA.preserved(InnerAnalysisManagerProxy::ID()))
+ AM->clear();
+
+ // Return false to indicate that this result is still a valid proxy.
+ return false;
+ }
- static StringRef name() { return "FunctionAnalysisManagerModuleProxy"; }
+ private:
+ AnalysisManagerT *AM;
+ };
- explicit FunctionAnalysisManagerModuleProxy(FunctionAnalysisManager &FAM)
- : FAM(&FAM) {}
+ explicit InnerAnalysisManagerProxy(AnalysisManagerT &AM) : AM(&AM) {}
// We have to explicitly define all the special member functions because MSVC
// refuses to generate them.
- FunctionAnalysisManagerModuleProxy(
- const FunctionAnalysisManagerModuleProxy &Arg)
- : FAM(Arg.FAM) {}
- FunctionAnalysisManagerModuleProxy(FunctionAnalysisManagerModuleProxy &&Arg)
- : FAM(std::move(Arg.FAM)) {}
- FunctionAnalysisManagerModuleProxy &
- operator=(FunctionAnalysisManagerModuleProxy RHS) {
- std::swap(FAM, RHS.FAM);
+ InnerAnalysisManagerProxy(const InnerAnalysisManagerProxy &Arg)
+ : AM(Arg.AM) {}
+ InnerAnalysisManagerProxy(InnerAnalysisManagerProxy &&Arg)
+ : AM(std::move(Arg.AM)) {}
+ InnerAnalysisManagerProxy &operator=(InnerAnalysisManagerProxy RHS) {
+ std::swap(AM, RHS.AM);
return *this;
}
@@ -630,49 +750,24 @@ public:
/// In debug builds, it will also assert that the analysis manager is empty
/// as no queries should arrive at the function analysis manager prior to
/// this analysis being requested.
- Result run(Module &M);
+ Result run(IRUnitT &IR, AnalysisManager<IRUnitT> &) { return Result(*AM); }
private:
+ friend AnalysisInfoMixin<
+ InnerAnalysisManagerProxy<AnalysisManagerT, IRUnitT>>;
static char PassID;
- FunctionAnalysisManager *FAM;
+ AnalysisManagerT *AM;
};
-/// \brief The result proxy object for the
-/// \c FunctionAnalysisManagerModuleProxy.
-///
-/// See its documentation for more information.
-class FunctionAnalysisManagerModuleProxy::Result {
-public:
- explicit Result(FunctionAnalysisManager &FAM) : FAM(&FAM) {}
- // We have to explicitly define all the special member functions because MSVC
- // refuses to generate them.
- Result(const Result &Arg) : FAM(Arg.FAM) {}
- Result(Result &&Arg) : FAM(std::move(Arg.FAM)) {}
- Result &operator=(Result RHS) {
- std::swap(FAM, RHS.FAM);
- return *this;
- }
- ~Result();
-
- /// \brief Accessor for the \c FunctionAnalysisManager.
- FunctionAnalysisManager &getManager() { return *FAM; }
-
- /// \brief Handler for invalidation of the module.
- ///
- /// If this analysis itself is preserved, then we assume that the set of \c
- /// Function objects in the \c Module hasn't changed and thus we don't need
- /// to invalidate *all* cached data associated with a \c Function* in the \c
- /// FunctionAnalysisManager.
- ///
- /// Regardless of whether this analysis is marked as preserved, all of the
- /// analyses in the \c FunctionAnalysisManager are potentially invalidated
- /// based on the set of preserved analyses.
- bool invalidate(Module &M, const PreservedAnalyses &PA);
+template <typename AnalysisManagerT, typename IRUnitT>
+char InnerAnalysisManagerProxy<AnalysisManagerT, IRUnitT>::PassID;
-private:
- FunctionAnalysisManager *FAM;
-};
+extern template class InnerAnalysisManagerProxy<FunctionAnalysisManager,
+ Module>;
+/// Provide the \c FunctionAnalysisManager to \c Module proxy.
+typedef InnerAnalysisManagerProxy<FunctionAnalysisManager, Module>
+ FunctionAnalysisManagerModuleProxy;
/// \brief A function analysis which acts as a proxy for a module analysis
/// manager.
@@ -686,60 +781,67 @@ private:
/// This proxy *doesn't* manage the invalidation in any way. That is handled by
/// the recursive return path of each layer of the pass manager and the
/// returned PreservedAnalysis set.
-class ModuleAnalysisManagerFunctionProxy {
+template <typename AnalysisManagerT, typename IRUnitT>
+class OuterAnalysisManagerProxy
+ : public AnalysisInfoMixin<
+ OuterAnalysisManagerProxy<AnalysisManagerT, IRUnitT>> {
public:
- /// \brief Result proxy object for \c ModuleAnalysisManagerFunctionProxy.
+ /// \brief Result proxy object for \c OuterAnalysisManagerProxy.
class Result {
public:
- explicit Result(const ModuleAnalysisManager &MAM) : MAM(&MAM) {}
+ explicit Result(const AnalysisManagerT &AM) : AM(&AM) {}
// We have to explicitly define all the special member functions because
// MSVC refuses to generate them.
- Result(const Result &Arg) : MAM(Arg.MAM) {}
- Result(Result &&Arg) : MAM(std::move(Arg.MAM)) {}
+ Result(const Result &Arg) : AM(Arg.AM) {}
+ Result(Result &&Arg) : AM(std::move(Arg.AM)) {}
Result &operator=(Result RHS) {
- std::swap(MAM, RHS.MAM);
+ std::swap(AM, RHS.AM);
return *this;
}
- const ModuleAnalysisManager &getManager() const { return *MAM; }
+ const AnalysisManagerT &getManager() const { return *AM; }
/// \brief Handle invalidation by ignoring it, this pass is immutable.
- bool invalidate(Function &) { return false; }
+ bool invalidate(IRUnitT &) { return false; }
private:
- const ModuleAnalysisManager *MAM;
+ const AnalysisManagerT *AM;
};
- static void *ID() { return (void *)&PassID; }
-
- static StringRef name() { return "ModuleAnalysisManagerFunctionProxy"; }
-
- ModuleAnalysisManagerFunctionProxy(const ModuleAnalysisManager &MAM)
- : MAM(&MAM) {}
+ OuterAnalysisManagerProxy(const AnalysisManagerT &AM) : AM(&AM) {}
// We have to explicitly define all the special member functions because MSVC
// refuses to generate them.
- ModuleAnalysisManagerFunctionProxy(
- const ModuleAnalysisManagerFunctionProxy &Arg)
- : MAM(Arg.MAM) {}
- ModuleAnalysisManagerFunctionProxy(ModuleAnalysisManagerFunctionProxy &&Arg)
- : MAM(std::move(Arg.MAM)) {}
- ModuleAnalysisManagerFunctionProxy &
- operator=(ModuleAnalysisManagerFunctionProxy RHS) {
- std::swap(MAM, RHS.MAM);
+ OuterAnalysisManagerProxy(const OuterAnalysisManagerProxy &Arg)
+ : AM(Arg.AM) {}
+ OuterAnalysisManagerProxy(OuterAnalysisManagerProxy &&Arg)
+ : AM(std::move(Arg.AM)) {}
+ OuterAnalysisManagerProxy &operator=(OuterAnalysisManagerProxy RHS) {
+ std::swap(AM, RHS.AM);
return *this;
}
/// \brief Run the analysis pass and create our proxy result object.
- /// Nothing to see here, it just forwards the \c MAM reference into the
+ /// Nothing to see here, it just forwards the \c AM reference into the
/// result.
- Result run(Function &) { return Result(*MAM); }
+ Result run(IRUnitT &, AnalysisManager<IRUnitT> &) { return Result(*AM); }
private:
+ friend AnalysisInfoMixin<
+ OuterAnalysisManagerProxy<AnalysisManagerT, IRUnitT>>;
static char PassID;
- const ModuleAnalysisManager *MAM;
+ const AnalysisManagerT *AM;
};
+template <typename AnalysisManagerT, typename IRUnitT>
+char OuterAnalysisManagerProxy<AnalysisManagerT, IRUnitT>::PassID;
+
+extern template class OuterAnalysisManagerProxy<ModuleAnalysisManager,
+ Function>;
+/// Provide the \c ModuleAnalysisManager to \c Fucntion proxy.
+typedef OuterAnalysisManagerProxy<ModuleAnalysisManager, Function>
+ ModuleAnalysisManagerFunctionProxy;
+
/// \brief Trivial adaptor that maps from a module to its functions.
///
/// Designed to allow composition of a FunctionPass(Manager) and
@@ -762,7 +864,9 @@ private:
/// module.
/// FIXME: Make the above true for all of LLVM's actual passes, some still
/// violate this principle.
-template <typename FunctionPassT> class ModuleToFunctionPassAdaptor {
+template <typename FunctionPassT>
+class ModuleToFunctionPassAdaptor
+ : public PassInfoMixin<ModuleToFunctionPassAdaptor<FunctionPassT>> {
public:
explicit ModuleToFunctionPassAdaptor(FunctionPassT Pass)
: Pass(std::move(Pass)) {}
@@ -783,11 +887,10 @@ public:
}
/// \brief Runs the function pass across every function in the module.
- PreservedAnalyses run(Module &M, ModuleAnalysisManager *AM) {
- FunctionAnalysisManager *FAM = nullptr;
- if (AM)
- // Setup the function analysis manager from its proxy.
- FAM = &AM->getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM) {
+ // Setup the function analysis manager from its proxy.
+ FunctionAnalysisManager &FAM =
+ AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
PreservedAnalyses PA = PreservedAnalyses::all();
for (Function &F : M) {
@@ -801,8 +904,7 @@ public:
// directly handle the function analysis manager's invalidation here and
// update our preserved set to reflect that these have already been
// handled.
- if (FAM)
- PassPA = FAM->invalidate(F, std::move(PassPA));
+ PassPA = FAM.invalidate(F, std::move(PassPA));
// Then intersect the preserved set so that invalidation of module
// analyses will eventually occur when the module pass completes.
@@ -817,8 +919,6 @@ public:
return PA;
}
- static StringRef name() { return "ModuleToFunctionPassAdaptor"; }
-
private:
FunctionPassT Pass;
};
@@ -835,7 +935,8 @@ createModuleToFunctionPassAdaptor(FunctionPassT Pass) {
///
/// This is a no-op pass which simply forces a specific analysis pass's result
/// to be available when it is run.
-template <typename AnalysisT> struct RequireAnalysisPass {
+template <typename AnalysisT>
+struct RequireAnalysisPass : PassInfoMixin<RequireAnalysisPass<AnalysisT>> {
/// \brief Run this pass over some unit of IR.
///
/// This pass can be run over any unit of IR and use any analysis manager
@@ -843,14 +944,11 @@ template <typename AnalysisT> struct RequireAnalysisPass {
/// created, these methods can be instantiated to satisfy whatever the
/// context requires.
template <typename IRUnitT>
- PreservedAnalyses run(IRUnitT &Arg, AnalysisManager<IRUnitT> *AM) {
- if (AM)
- (void)AM->template getResult<AnalysisT>(Arg);
+ PreservedAnalyses run(IRUnitT &Arg, AnalysisManager<IRUnitT> &AM) {
+ (void)AM.template getResult<AnalysisT>(Arg);
return PreservedAnalyses::all();
}
-
- static StringRef name() { return "RequireAnalysisPass"; }
};
/// \brief A template utility pass to force an analysis result to be
@@ -858,7 +956,9 @@ template <typename AnalysisT> struct RequireAnalysisPass {
///
/// This is a no-op pass which simply forces a specific analysis result to be
/// invalidated when it is run.
-template <typename AnalysisT> struct InvalidateAnalysisPass {
+template <typename AnalysisT>
+struct InvalidateAnalysisPass
+ : PassInfoMixin<InvalidateAnalysisPass<AnalysisT>> {
/// \brief Run this pass over some unit of IR.
///
/// This pass can be run over any unit of IR and use any analysis manager
@@ -866,29 +966,25 @@ template <typename AnalysisT> struct InvalidateAnalysisPass {
/// created, these methods can be instantiated to satisfy whatever the
/// context requires.
template <typename IRUnitT>
- PreservedAnalyses run(IRUnitT &Arg, AnalysisManager<IRUnitT> *AM) {
- if (AM)
- // We have to directly invalidate the analysis result as we can't
- // enumerate all other analyses and use the preserved set to control it.
- (void)AM->template invalidate<AnalysisT>(Arg);
+ PreservedAnalyses run(IRUnitT &Arg, AnalysisManager<IRUnitT> &AM) {
+ // We have to directly invalidate the analysis result as we can't
+ // enumerate all other analyses and use the preserved set to control it.
+ AM.template invalidate<AnalysisT>(Arg);
return PreservedAnalyses::all();
}
-
- static StringRef name() { return "InvalidateAnalysisPass"; }
};
/// \brief A utility pass that does nothing but preserves no analyses.
///
/// As a consequence fo not preserving any analyses, this pass will force all
/// analysis passes to be re-run to produce fresh results if any are needed.
-struct InvalidateAllAnalysesPass {
+struct InvalidateAllAnalysesPass : PassInfoMixin<InvalidateAllAnalysesPass> {
/// \brief Run this pass over some unit of IR.
- template <typename IRUnitT> PreservedAnalyses run(IRUnitT &Arg) {
+ template <typename IRUnitT>
+ PreservedAnalyses run(IRUnitT &, AnalysisManager<IRUnitT> &) {
return PreservedAnalyses::none();
}
-
- static StringRef name() { return "InvalidateAllAnalysesPass"; }
};
}