#ifndef LLVM_IR_PASSMANAGER_H
#define LLVM_IR_PASSMANAGER_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/type_traits.h"
#include <list>
#include <memory>
#include <vector>
namespace llvm {
class Module;
class Function;
class PreservedAnalyses {
public:
PreservedAnalyses() {}
PreservedAnalyses(const PreservedAnalyses &Arg)
: PreservedPassIDs(Arg.PreservedPassIDs) {}
PreservedAnalyses(PreservedAnalyses &&Arg)
: PreservedPassIDs(std::move(Arg.PreservedPassIDs)) {}
friend void swap(PreservedAnalyses &LHS, PreservedAnalyses &RHS) {
using std::swap;
swap(LHS.PreservedPassIDs, RHS.PreservedPassIDs);
}
PreservedAnalyses &operator=(PreservedAnalyses RHS) {
swap(*this, RHS);
return *this;
}
static PreservedAnalyses none() { return PreservedAnalyses(); }
static PreservedAnalyses all() {
PreservedAnalyses PA;
PA.PreservedPassIDs.insert((void *)AllPassesID);
return PA;
}
template <typename PassT> void preserve() {
if (!areAllPreserved())
PreservedPassIDs.insert(PassT::ID());
}
void intersect(const PreservedAnalyses &Arg) {
if (Arg.areAllPreserved())
return;
if (areAllPreserved()) {
PreservedPassIDs = Arg.PreservedPassIDs;
return;
}
for (SmallPtrSet<void *, 2>::const_iterator I = PreservedPassIDs.begin(),
E = PreservedPassIDs.end();
I != E; ++I)
if (!Arg.PreservedPassIDs.count(*I))
PreservedPassIDs.erase(*I);
}
void intersect(PreservedAnalyses &&Arg) {
if (Arg.areAllPreserved())
return;
if (areAllPreserved()) {
PreservedPassIDs = std::move(Arg.PreservedPassIDs);
return;
}
for (SmallPtrSet<void *, 2>::const_iterator I = PreservedPassIDs.begin(),
E = PreservedPassIDs.end();
I != E; ++I)
if (!Arg.PreservedPassIDs.count(*I))
PreservedPassIDs.erase(*I);
}
template <typename PassT> bool preserved() const {
return preserved(PassT::ID());
}
bool preserved(void *PassID) const {
return PreservedPassIDs.count((void *)AllPassesID) ||
PreservedPassIDs.count(PassID);
}
private:
static const uintptr_t AllPassesID = (intptr_t)(-3);
bool areAllPreserved() const {
return PreservedPassIDs.count((void *)AllPassesID);
}
SmallPtrSet<void *, 2> PreservedPassIDs;
};
namespace detail {
template <typename IRUnitT, typename AnalysisManagerT> struct PassConcept {
virtual ~PassConcept() {}
virtual PreservedAnalyses run(IRUnitT IR, AnalysisManagerT *AM) = 0;
virtual StringRef name() = 0;
};
template <typename IRUnitT, typename AnalysisManagerT, typename PassT,
typename ResultT>
class PassRunAcceptsAnalysisManager {
typedef char SmallType;
struct BigType {
char a, b;
};
template <typename T, ResultT (T::*)(IRUnitT, AnalysisManagerT *)>
struct Checker;
template <typename T> static SmallType f(Checker<T, &T::run> *);
template <typename T> static BigType f(...);
public:
enum { Value = sizeof(f<PassT>(nullptr)) == sizeof(SmallType) };
};
template <typename IRUnitT, typename AnalysisManagerT, typename PassT,
bool AcceptsAnalysisManager = PassRunAcceptsAnalysisManager<
IRUnitT, AnalysisManagerT, PassT, PreservedAnalyses>::Value>
struct PassModel;
template <typename IRUnitT, typename AnalysisManagerT, typename PassT>
struct PassModel<IRUnitT, AnalysisManagerT, PassT, true>
: PassConcept<IRUnitT, AnalysisManagerT> {
explicit PassModel(PassT Pass) : Pass(std::move(Pass)) {}
PassModel(const PassModel &Arg) : Pass(Arg.Pass) {}
PassModel(PassModel &&Arg) : Pass(std::move(Arg.Pass)) {}
friend void swap(PassModel &LHS, PassModel &RHS) {
using std::swap;
swap(LHS.Pass, RHS.Pass);
}
PassModel &operator=(PassModel RHS) {
swap(*this, RHS);
return *this;
}
PreservedAnalyses run(IRUnitT IR, AnalysisManagerT *AM) override {
return Pass.run(IR, AM);
}
StringRef name() override { return PassT::name(); }
PassT Pass;
};
template <typename IRUnitT, typename AnalysisManagerT, typename PassT>
struct PassModel<IRUnitT, AnalysisManagerT, PassT, false>
: PassConcept<IRUnitT, AnalysisManagerT> {
explicit PassModel(PassT Pass) : Pass(std::move(Pass)) {}
PassModel(const PassModel &Arg) : Pass(Arg.Pass) {}
PassModel(PassModel &&Arg) : Pass(std::move(Arg.Pass)) {}
friend void swap(PassModel &LHS, PassModel &RHS) {
using std::swap;
swap(LHS.Pass, RHS.Pass);
}
PassModel &operator=(PassModel RHS) {
swap(*this, RHS);
return *this;
}
PreservedAnalyses run(IRUnitT IR, AnalysisManagerT *AM) override {
return Pass.run(IR);
}
StringRef name() override { return PassT::name(); }
PassT Pass;
};
template <typename IRUnitT> struct AnalysisResultConcept {
virtual ~AnalysisResultConcept() {}
virtual bool invalidate(IRUnitT IR, const PreservedAnalyses &PA) = 0;
};
template <typename IRUnitT, typename ResultT> class ResultHasInvalidateMethod {
typedef char SmallType;
struct BigType {
char a, b;
};
template <typename T, bool (T::*)(IRUnitT, const PreservedAnalyses &)>
struct Checker;
template <typename T> static SmallType f(Checker<T, &T::invalidate> *);
template <typename T> static BigType f(...);
public:
enum { Value = sizeof(f<ResultT>(nullptr)) == sizeof(SmallType) };
};
template <typename IRUnitT, typename PassT, typename ResultT,
bool HasInvalidateHandler =
ResultHasInvalidateMethod<IRUnitT, ResultT>::Value>
struct AnalysisResultModel;
template <typename IRUnitT, typename PassT, typename ResultT>
struct AnalysisResultModel<IRUnitT, PassT, ResultT, false>
: AnalysisResultConcept<IRUnitT> {
explicit AnalysisResultModel(ResultT Result) : Result(std::move(Result)) {}
AnalysisResultModel(const AnalysisResultModel &Arg) : Result(Arg.Result) {}
AnalysisResultModel(AnalysisResultModel &&Arg)
: Result(std::move(Arg.Result)) {}
friend void swap(AnalysisResultModel &LHS, AnalysisResultModel &RHS) {
using std::swap;
swap(LHS.Result, RHS.Result);
}
AnalysisResultModel &operator=(AnalysisResultModel RHS) {
swap(*this, RHS);
return *this;
}
bool invalidate(IRUnitT, const PreservedAnalyses &PA) override {
return !PA.preserved(PassT::ID());
}
ResultT Result;
};
template <typename IRUnitT, typename PassT, typename ResultT>
struct AnalysisResultModel<IRUnitT, PassT, ResultT, true>
: AnalysisResultConcept<IRUnitT> {
explicit AnalysisResultModel(ResultT Result) : Result(std::move(Result)) {}
AnalysisResultModel(const AnalysisResultModel &Arg) : Result(Arg.Result) {}
AnalysisResultModel(AnalysisResultModel &&Arg)
: Result(std::move(Arg.Result)) {}
friend void swap(AnalysisResultModel &LHS, AnalysisResultModel &RHS) {
using std::swap;
swap(LHS.Result, RHS.Result);
}
AnalysisResultModel &operator=(AnalysisResultModel RHS) {
swap(*this, RHS);
return *this;
}
bool invalidate(IRUnitT IR, const PreservedAnalyses &PA) override {
return Result.invalidate(IR, PA);
}
ResultT Result;
};
template <typename IRUnitT, typename AnalysisManagerT>
struct AnalysisPassConcept {
virtual ~AnalysisPassConcept() {}
virtual std::unique_ptr<AnalysisResultConcept<IRUnitT>>
run(IRUnitT IR, AnalysisManagerT *AM) = 0;
};
template <typename IRUnitT, typename AnalysisManagerT, typename PassT,
bool AcceptsAnalysisManager = PassRunAcceptsAnalysisManager<
IRUnitT, AnalysisManagerT, PassT, typename PassT::Result>::Value>
struct AnalysisPassModel;
template <typename IRUnitT, typename AnalysisManagerT, typename PassT>
struct AnalysisPassModel<IRUnitT, AnalysisManagerT, PassT, true>
: AnalysisPassConcept<IRUnitT, AnalysisManagerT> {
explicit AnalysisPassModel(PassT Pass) : Pass(std::move(Pass)) {}
AnalysisPassModel(const AnalysisPassModel &Arg) : Pass(Arg.Pass) {}
AnalysisPassModel(AnalysisPassModel &&Arg) : Pass(std::move(Arg.Pass)) {}
friend void swap(AnalysisPassModel &LHS, AnalysisPassModel &RHS) {
using std::swap;
swap(LHS.Pass, RHS.Pass);
}
AnalysisPassModel &operator=(AnalysisPassModel RHS) {
swap(*this, RHS);
return *this;
}
typedef AnalysisResultModel<IRUnitT, PassT, typename PassT::Result>
ResultModelT;
std::unique_ptr<AnalysisResultConcept<IRUnitT>>
run(IRUnitT IR, AnalysisManagerT *AM) override {
return make_unique<ResultModelT>(Pass.run(IR, AM));
}
PassT Pass;
};
template <typename IRUnitT, typename AnalysisManagerT, typename PassT>
struct AnalysisPassModel<IRUnitT, AnalysisManagerT, PassT, false>
: AnalysisPassConcept<IRUnitT, AnalysisManagerT> {
explicit AnalysisPassModel(PassT Pass) : Pass(std::move(Pass)) {}
AnalysisPassModel(const AnalysisPassModel &Arg) : Pass(Arg.Pass) {}
AnalysisPassModel(AnalysisPassModel &&Arg) : Pass(std::move(Arg.Pass)) {}
friend void swap(AnalysisPassModel &LHS, AnalysisPassModel &RHS) {
using std::swap;
swap(LHS.Pass, RHS.Pass);
}
AnalysisPassModel &operator=(AnalysisPassModel RHS) {
swap(*this, RHS);
return *this;
}
typedef AnalysisResultModel<IRUnitT, PassT, typename PassT::Result>
ResultModelT;
std::unique_ptr<AnalysisResultConcept<IRUnitT>>
run(IRUnitT IR, AnalysisManagerT *) override {
return make_unique<ResultModelT>(Pass.run(IR));
}
PassT Pass;
};
}
class ModuleAnalysisManager;
class ModulePassManager {
public:
ModulePassManager() {}
ModulePassManager(ModulePassManager &&Arg) : Passes(std::move(Arg.Passes)) {}
ModulePassManager &operator=(ModulePassManager &&RHS) {
Passes = std::move(RHS.Passes);
return *this;
}
PreservedAnalyses run(Module *M, ModuleAnalysisManager *AM = nullptr);
template <typename ModulePassT> void addPass(ModulePassT Pass) {
Passes.emplace_back(new ModulePassModel<ModulePassT>(std::move(Pass)));
}
static StringRef name() { return "ModulePassManager"; }
private:
typedef detail::PassConcept<Module *, ModuleAnalysisManager>
ModulePassConcept;
template <typename PassT>
struct ModulePassModel
: detail::PassModel<Module *, ModuleAnalysisManager, PassT> {
ModulePassModel(PassT Pass)
: detail::PassModel<Module *, ModuleAnalysisManager, PassT>(
std::move(Pass)) {}
};
ModulePassManager(const ModulePassManager &) LLVM_DELETED_FUNCTION;
ModulePassManager &operator=(const ModulePassManager &) LLVM_DELETED_FUNCTION;
std::vector<std::unique_ptr<ModulePassConcept>> Passes;
};
class FunctionAnalysisManager;
class FunctionPassManager {
public:
FunctionPassManager() {}
FunctionPassManager(FunctionPassManager &&Arg)
: Passes(std::move(Arg.Passes)) {}
FunctionPassManager &operator=(FunctionPassManager &&RHS) {
Passes = std::move(RHS.Passes);
return *this;
}
template <typename FunctionPassT> void addPass(FunctionPassT Pass) {
Passes.emplace_back(new FunctionPassModel<FunctionPassT>(std::move(Pass)));
}
PreservedAnalyses run(Function *F, FunctionAnalysisManager *AM = nullptr);
static StringRef name() { return "FunctionPassManager"; }
private:
typedef detail::PassConcept<Function *, FunctionAnalysisManager>
FunctionPassConcept;
template <typename PassT>
struct FunctionPassModel
: detail::PassModel<Function *, FunctionAnalysisManager, PassT> {
FunctionPassModel(PassT Pass)
: detail::PassModel<Function *, FunctionAnalysisManager, PassT>(
std::move(Pass)) {}
};
FunctionPassManager(const FunctionPassManager &) LLVM_DELETED_FUNCTION;
FunctionPassManager &
operator=(const FunctionPassManager &) LLVM_DELETED_FUNCTION;
std::vector<std::unique_ptr<FunctionPassConcept>> Passes;
};
namespace detail {
template <typename DerivedT, typename IRUnitT> class AnalysisManagerBase {
DerivedT *derived_this() { return static_cast<DerivedT *>(this); }
const DerivedT *derived_this() const {
return static_cast<const DerivedT *>(this);
}
AnalysisManagerBase(const AnalysisManagerBase &) LLVM_DELETED_FUNCTION;
AnalysisManagerBase &
operator=(const AnalysisManagerBase &) LLVM_DELETED_FUNCTION;
protected:
typedef detail::AnalysisResultConcept<IRUnitT> ResultConceptT;
typedef detail::AnalysisPassConcept<IRUnitT, DerivedT> PassConceptT;
AnalysisManagerBase() {}
AnalysisManagerBase(AnalysisManagerBase &&Arg)
: AnalysisPasses(std::move(Arg.AnalysisPasses)) {}
AnalysisManagerBase &operator=(AnalysisManagerBase &&RHS) {
AnalysisPasses = std::move(RHS.AnalysisPasses);
return *this;
}
public:
template <typename PassT> typename PassT::Result &getResult(IRUnitT IR) {
assert(AnalysisPasses.count(PassT::ID()) &&
"This analysis pass was not registered prior to being queried");
ResultConceptT &ResultConcept =
derived_this()->getResultImpl(PassT::ID(), IR);
typedef detail::AnalysisResultModel<IRUnitT, PassT, typename PassT::Result>
ResultModelT;
return static_cast<ResultModelT &>(ResultConcept).Result;
}
template <typename PassT>
typename PassT::Result *getCachedResult(IRUnitT IR) const {
assert(AnalysisPasses.count(PassT::ID()) &&
"This analysis pass was not registered prior to being queried");
ResultConceptT *ResultConcept =
derived_this()->getCachedResultImpl(PassT::ID(), IR);
if (!ResultConcept)
return nullptr;
typedef detail::AnalysisResultModel<IRUnitT, PassT, typename PassT::Result>
ResultModelT;
return &static_cast<ResultModelT *>(ResultConcept)->Result;
}
template <typename PassT> void registerPass(PassT Pass) {
assert(!AnalysisPasses.count(PassT::ID()) &&
"Registered the same analysis pass twice!");
typedef detail::AnalysisPassModel<IRUnitT, DerivedT, PassT> PassModelT;
AnalysisPasses[PassT::ID()].reset(new PassModelT(std::move(Pass)));
}
template <typename PassT> void invalidate(Module *M) {
assert(AnalysisPasses.count(PassT::ID()) &&
"This analysis pass was not registered prior to being invalidated");
derived_this()->invalidateImpl(PassT::ID(), M);
}
void invalidate(IRUnitT IR, const PreservedAnalyses &PA) {
derived_this()->invalidateImpl(IR, PA);
}
protected:
PassConceptT &lookupPass(void *PassID) {
typename AnalysisPassMapT::iterator PI = AnalysisPasses.find(PassID);
assert(PI != AnalysisPasses.end() &&
"Analysis passes must be registered prior to being queried!");
return *PI->second;
}
const PassConceptT &lookupPass(void *PassID) const {
typename AnalysisPassMapT::const_iterator PI = AnalysisPasses.find(PassID);
assert(PI != AnalysisPasses.end() &&
"Analysis passes must be registered prior to being queried!");
return *PI->second;
}
private:
typedef DenseMap<void *, std::unique_ptr<PassConceptT>> AnalysisPassMapT;
AnalysisPassMapT AnalysisPasses;
};
}
class ModuleAnalysisManager
: public detail::AnalysisManagerBase<ModuleAnalysisManager, Module *> {
friend class detail::AnalysisManagerBase<ModuleAnalysisManager, Module *>;
typedef detail::AnalysisManagerBase<ModuleAnalysisManager, Module *> BaseT;
typedef BaseT::ResultConceptT ResultConceptT;
typedef BaseT::PassConceptT PassConceptT;
public:
ModuleAnalysisManager() {}
ModuleAnalysisManager(ModuleAnalysisManager &&Arg)
: BaseT(std::move(static_cast<BaseT &>(Arg))),
ModuleAnalysisResults(std::move(Arg.ModuleAnalysisResults)) {}
ModuleAnalysisManager &operator=(ModuleAnalysisManager &&RHS) {
BaseT::operator=(std::move(static_cast<BaseT &>(RHS)));
ModuleAnalysisResults = std::move(RHS.ModuleAnalysisResults);
return *this;
}
private:
ModuleAnalysisManager(const ModuleAnalysisManager &) LLVM_DELETED_FUNCTION;
ModuleAnalysisManager &
operator=(const ModuleAnalysisManager &) LLVM_DELETED_FUNCTION;
ResultConceptT &getResultImpl(void *PassID, Module *M);
ResultConceptT *getCachedResultImpl(void *PassID, Module *M) const;
void invalidateImpl(void *PassID, Module *M);
void invalidateImpl(Module *M, const PreservedAnalyses &PA);
typedef DenseMap<void *,
std::unique_ptr<detail::AnalysisResultConcept<Module *>>>
ModuleAnalysisResultMapT;
ModuleAnalysisResultMapT ModuleAnalysisResults;
};
class FunctionAnalysisManager
: public detail::AnalysisManagerBase<FunctionAnalysisManager, Function *> {
friend class detail::AnalysisManagerBase<FunctionAnalysisManager, Function *>;
typedef detail::AnalysisManagerBase<FunctionAnalysisManager, Function *>
BaseT;
typedef BaseT::ResultConceptT ResultConceptT;
typedef BaseT::PassConceptT PassConceptT;
public:
FunctionAnalysisManager() {}
FunctionAnalysisManager(FunctionAnalysisManager &&Arg)
: BaseT(std::move(static_cast<BaseT &>(Arg))),
FunctionAnalysisResults(std::move(Arg.FunctionAnalysisResults)) {}
FunctionAnalysisManager &operator=(FunctionAnalysisManager &&RHS) {
BaseT::operator=(std::move(static_cast<BaseT &>(RHS)));
FunctionAnalysisResults = std::move(RHS.FunctionAnalysisResults);
return *this;
}
bool empty() const;
void clear();
private:
FunctionAnalysisManager(const FunctionAnalysisManager &)
LLVM_DELETED_FUNCTION;
FunctionAnalysisManager &
operator=(const FunctionAnalysisManager &) LLVM_DELETED_FUNCTION;
ResultConceptT &getResultImpl(void *PassID, Function *F);
ResultConceptT *getCachedResultImpl(void *PassID, Function *F) const;
void invalidateImpl(void *PassID, Function *F);
void invalidateImpl(Function *F, const PreservedAnalyses &PA);
typedef std::list<std::pair<
void *, std::unique_ptr<detail::AnalysisResultConcept<Function *>>>>
FunctionAnalysisResultListT;
typedef DenseMap<Function *, FunctionAnalysisResultListT>
FunctionAnalysisResultListMapT;
FunctionAnalysisResultListMapT FunctionAnalysisResultLists;
typedef DenseMap<std::pair<void *, Function *>,
FunctionAnalysisResultListT::iterator>
FunctionAnalysisResultMapT;
FunctionAnalysisResultMapT FunctionAnalysisResults;
};
class FunctionAnalysisManagerModuleProxy {
public:
class Result;
static void *ID() { return (void *)&PassID; }
explicit FunctionAnalysisManagerModuleProxy(FunctionAnalysisManager &FAM)
: FAM(&FAM) {}
FunctionAnalysisManagerModuleProxy(
const FunctionAnalysisManagerModuleProxy &Arg)
: FAM(Arg.FAM) {}
FunctionAnalysisManagerModuleProxy(FunctionAnalysisManagerModuleProxy &&Arg)
: FAM(std::move(Arg.FAM)) {}
FunctionAnalysisManagerModuleProxy &
operator=(FunctionAnalysisManagerModuleProxy RHS) {
std::swap(FAM, RHS.FAM);
return *this;
}
Result run(Module *M);
private:
static char PassID;
FunctionAnalysisManager *FAM;
};
class FunctionAnalysisManagerModuleProxy::Result {
public:
explicit Result(FunctionAnalysisManager &FAM) : FAM(&FAM) {}
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();
FunctionAnalysisManager &getManager() { return *FAM; }
bool invalidate(Module *M, const PreservedAnalyses &PA);
private:
FunctionAnalysisManager *FAM;
};
class ModuleAnalysisManagerFunctionProxy {
public:
class Result {
public:
explicit Result(const ModuleAnalysisManager &MAM) : MAM(&MAM) {}
Result(const Result &Arg) : MAM(Arg.MAM) {}
Result(Result &&Arg) : MAM(std::move(Arg.MAM)) {}
Result &operator=(Result RHS) {
std::swap(MAM, RHS.MAM);
return *this;
}
const ModuleAnalysisManager &getManager() const { return *MAM; }
bool invalidate(Function *) { return false; }
private:
const ModuleAnalysisManager *MAM;
};
static void *ID() { return (void *)&PassID; }
ModuleAnalysisManagerFunctionProxy(const ModuleAnalysisManager &MAM)
: MAM(&MAM) {}
ModuleAnalysisManagerFunctionProxy(
const ModuleAnalysisManagerFunctionProxy &Arg)
: MAM(Arg.MAM) {}
ModuleAnalysisManagerFunctionProxy(ModuleAnalysisManagerFunctionProxy &&Arg)
: MAM(std::move(Arg.MAM)) {}
ModuleAnalysisManagerFunctionProxy &
operator=(ModuleAnalysisManagerFunctionProxy RHS) {
std::swap(MAM, RHS.MAM);
return *this;
}
Result run(Function *) { return Result(*MAM); }
private:
static char PassID;
const ModuleAnalysisManager *MAM;
};
template <typename FunctionPassT> class ModuleToFunctionPassAdaptor {
public:
explicit ModuleToFunctionPassAdaptor(FunctionPassT Pass)
: Pass(std::move(Pass)) {}
ModuleToFunctionPassAdaptor(const ModuleToFunctionPassAdaptor &Arg)
: Pass(Arg.Pass) {}
ModuleToFunctionPassAdaptor(ModuleToFunctionPassAdaptor &&Arg)
: Pass(std::move(Arg.Pass)) {}
friend void swap(ModuleToFunctionPassAdaptor &LHS, ModuleToFunctionPassAdaptor &RHS) {
using std::swap;
swap(LHS.Pass, RHS.Pass);
}
ModuleToFunctionPassAdaptor &operator=(ModuleToFunctionPassAdaptor RHS) {
swap(*this, RHS);
return *this;
}
PreservedAnalyses run(Module *M, ModuleAnalysisManager *AM) {
FunctionAnalysisManager *FAM = nullptr;
if (AM)
FAM = &AM->getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
PreservedAnalyses PA = PreservedAnalyses::all();
for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) {
PreservedAnalyses PassPA = Pass.run(I, FAM);
if (FAM)
FAM->invalidate(I, PassPA);
PA.intersect(std::move(PassPA));
}
PA.preserve<FunctionAnalysisManagerModuleProxy>();
return PA;
}
static StringRef name() { return "ModuleToFunctionPassAdaptor"; }
private:
FunctionPassT Pass;
};
template <typename FunctionPassT>
ModuleToFunctionPassAdaptor<FunctionPassT>
createModuleToFunctionPassAdaptor(FunctionPassT Pass) {
return std::move(ModuleToFunctionPassAdaptor<FunctionPassT>(std::move(Pass)));
}
}
#endif