PassManagerInternal.h [plain text]
#ifndef LLVM_IR_PASSMANAGERINTERNAL_H
#define LLVM_IR_PASSMANAGERINTERNAL_H
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/STLExtras.h"
namespace llvm {
template <typename IRUnitT> class AnalysisManager;
class PreservedAnalyses;
namespace detail {
template <typename IRUnitT> struct PassConcept {
virtual ~PassConcept() {}
virtual PreservedAnalyses run(IRUnitT &IR, AnalysisManager<IRUnitT> *AM) = 0;
virtual StringRef name() = 0;
};
template <typename IRUnitT, typename PassT, typename ResultT>
class PassRunAcceptsAnalysisManager {
typedef char SmallType;
struct BigType {
char a, b;
};
template <typename T, ResultT (T::*)(IRUnitT &, AnalysisManager<IRUnitT> *)>
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 PassT,
typename PreservedAnalysesT = PreservedAnalyses,
bool AcceptsAnalysisManager = PassRunAcceptsAnalysisManager<
IRUnitT, PassT, PreservedAnalysesT>::Value>
struct PassModel;
template <typename IRUnitT, typename PassT, typename PreservedAnalysesT>
struct PassModel<IRUnitT, PassT, PreservedAnalysesT, true>
: PassConcept<IRUnitT> {
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;
}
PreservedAnalysesT run(IRUnitT &IR, AnalysisManager<IRUnitT> *AM) override {
return Pass.run(IR, AM);
}
StringRef name() override { return PassT::name(); }
PassT Pass;
};
template <typename IRUnitT, typename PassT, typename PreservedAnalysesT>
struct PassModel<IRUnitT, PassT, PreservedAnalysesT, false>
: PassConcept<IRUnitT> {
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;
}
PreservedAnalysesT run(IRUnitT &IR, AnalysisManager<IRUnitT> *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,
typename PreservedAnalysesT = PreservedAnalyses,
bool HasInvalidateHandler =
ResultHasInvalidateMethod<IRUnitT, ResultT>::Value>
struct AnalysisResultModel;
template <typename IRUnitT, typename PassT, typename ResultT,
typename PreservedAnalysesT>
struct AnalysisResultModel<IRUnitT, PassT, ResultT, PreservedAnalysesT, 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 PreservedAnalysesT &PA) override {
return !PA.preserved(PassT::ID());
}
ResultT Result;
};
template <typename IRUnitT, typename PassT, typename ResultT,
typename PreservedAnalysesT>
struct AnalysisResultModel<IRUnitT, PassT, ResultT, PreservedAnalysesT, 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 PreservedAnalysesT &PA) override {
return Result.invalidate(IR, PA);
}
ResultT Result;
};
template <typename IRUnitT> struct AnalysisPassConcept {
virtual ~AnalysisPassConcept() {}
virtual std::unique_ptr<AnalysisResultConcept<IRUnitT>>
run(IRUnitT &IR, AnalysisManager<IRUnitT> *AM) = 0;
virtual StringRef name() = 0;
};
template <typename IRUnitT, typename PassT,
bool AcceptsAnalysisManager = PassRunAcceptsAnalysisManager<
IRUnitT, PassT, typename PassT::Result>::Value>
struct AnalysisPassModel;
template <typename IRUnitT, typename PassT>
struct AnalysisPassModel<IRUnitT, PassT, true> : AnalysisPassConcept<IRUnitT> {
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, AnalysisManager<IRUnitT> *AM) override {
return make_unique<ResultModelT>(Pass.run(IR, AM));
}
StringRef name() override { return PassT::name(); }
PassT Pass;
};
template <typename IRUnitT, typename PassT>
struct AnalysisPassModel<IRUnitT, PassT, false> : AnalysisPassConcept<IRUnitT> {
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, AnalysisManager<IRUnitT> *) override {
return make_unique<ResultModelT>(Pass.run(IR));
}
StringRef name() override { return PassT::name(); }
PassT Pass;
};
} }
#endif