#define LLVM_IR_PASS_MANAGER_H
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/polymorphic_ptr.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 {
template <typename IRUnitT, typename AnalysisManagerT> struct PassConcept {
// Boiler plate necessary for the container of derived classes.
virtual ~PassConcept() {}
- virtual PassConcept *clone() = 0;
/// \brief The polymorphic API which runs the pass over a given IR entity.
///
struct PassModel<IRUnitT, AnalysisManagerT, PassT,
true> : PassConcept<IRUnitT, AnalysisManagerT> {
PassModel(PassT Pass) : Pass(std::move(Pass)) {}
- PassModel *clone() override { return new PassModel(Pass); }
PreservedAnalyses run(IRUnitT IR, AnalysisManagerT *AM) override {
return Pass.run(IR, AM);
}
struct PassModel<IRUnitT, AnalysisManagerT, PassT,
false> : PassConcept<IRUnitT, AnalysisManagerT> {
PassModel(PassT Pass) : Pass(std::move(Pass)) {}
- PassModel *clone() override { return new PassModel(Pass); }
PreservedAnalyses run(IRUnitT IR, AnalysisManagerT *AM) override {
return Pass.run(IR);
}
/// to.
template <typename IRUnitT> struct AnalysisResultConcept {
virtual ~AnalysisResultConcept() {}
- virtual AnalysisResultConcept *clone() = 0;
/// \brief Method to try and mark a result as invalid.
///
struct AnalysisResultModel<IRUnitT, PassT, ResultT,
false> : AnalysisResultConcept<IRUnitT> {
AnalysisResultModel(ResultT Result) : Result(std::move(Result)) {}
- AnalysisResultModel *clone() override {
- return new AnalysisResultModel(Result);
- }
/// \brief The model bases invalidation solely on being in the preserved set.
//
struct AnalysisResultModel<IRUnitT, PassT, ResultT,
true> : AnalysisResultConcept<IRUnitT> {
AnalysisResultModel(ResultT Result) : Result(std::move(Result)) {}
- AnalysisResultModel *clone() override {
- return new AnalysisResultModel(Result);
- }
/// \brief The model delegates to the \c ResultT method.
bool invalidate(IRUnitT IR, const PreservedAnalyses &PA) override {
template <typename IRUnitT, typename AnalysisManagerT>
struct AnalysisPassConcept {
virtual ~AnalysisPassConcept() {}
- virtual AnalysisPassConcept *clone() = 0;
/// \brief Method to run this analysis over a unit of IR.
- /// \returns The analysis result object to be queried by users, the caller
- /// takes ownership.
- virtual AnalysisResultConcept<IRUnitT> *run(IRUnitT IR,
- AnalysisManagerT *AM) = 0;
+ /// \returns A unique_ptr to the analysis result object to be queried by
+ /// users.
+ virtual std::unique_ptr<AnalysisResultConcept<IRUnitT>>
+ run(IRUnitT IR, AnalysisManagerT *AM) = 0;
};
/// \brief Wrapper to model the analysis pass concept.
true> : AnalysisPassConcept<IRUnitT,
AnalysisManagerT> {
AnalysisPassModel(PassT Pass) : Pass(std::move(Pass)) {}
- virtual AnalysisPassModel *clone() { return new AnalysisPassModel(Pass); }
// FIXME: Replace PassT::Result with type traits when we use C++11.
typedef AnalysisResultModel<IRUnitT, PassT, typename PassT::Result>
/// \brief The model delegates to the \c PassT::run method.
///
/// The return is wrapped in an \c AnalysisResultModel.
- virtual ResultModelT *run(IRUnitT IR, AnalysisManagerT *AM) {
- return new ResultModelT(Pass.run(IR, AM));
+ std::unique_ptr<AnalysisResultConcept<IRUnitT>>
+ run(IRUnitT IR, AnalysisManagerT *AM) override {
+ return make_unique<ResultModelT>(Pass.run(IR, AM));
}
PassT Pass;
false> : AnalysisPassConcept<IRUnitT,
AnalysisManagerT> {
AnalysisPassModel(PassT Pass) : Pass(std::move(Pass)) {}
- AnalysisPassModel *clone() override { return new AnalysisPassModel(Pass); }
// FIXME: Replace PassT::Result with type traits when we use C++11.
typedef AnalysisResultModel<IRUnitT, PassT, typename PassT::Result>
/// \brief The model delegates to the \c PassT::run method.
///
/// The return is wrapped in an \c AnalysisResultModel.
- ResultModelT *run(IRUnitT IR, AnalysisManagerT *) override {
- return new ResultModelT(Pass.run(IR));
+ std::unique_ptr<AnalysisResultConcept<IRUnitT>>
+ run(IRUnitT IR, AnalysisManagerT *) override {
+ return make_unique<ResultModelT>(Pass.run(IR));
}
PassT Pass;
class ModulePassManager {
public:
- explicit ModulePassManager() {}
-
/// \brief Run all of the module passes in this module pass manager over
/// a module.
///
PreservedAnalyses run(Module *M, ModuleAnalysisManager *AM = 0);
template <typename ModulePassT> void addPass(ModulePassT Pass) {
- Passes.push_back(new ModulePassModel<ModulePassT>(std::move(Pass)));
+ Passes.emplace_back(new ModulePassModel<ModulePassT>(std::move(Pass)));
}
static StringRef name() { return "ModulePassManager"; }
struct ModulePassModel
: detail::PassModel<Module *, ModuleAnalysisManager, PassT> {
ModulePassModel(PassT Pass)
- : detail::PassModel<Module *, ModuleAnalysisManager, PassT>(Pass) {}
+ : detail::PassModel<Module *, ModuleAnalysisManager, PassT>(
+ std::move(Pass)) {}
};
- std::vector<polymorphic_ptr<ModulePassConcept> > Passes;
+ std::vector<std::unique_ptr<ModulePassConcept>> Passes;
};
class FunctionAnalysisManager;
class FunctionPassManager {
public:
- explicit FunctionPassManager() {}
-
template <typename FunctionPassT> void addPass(FunctionPassT Pass) {
- Passes.push_back(new FunctionPassModel<FunctionPassT>(std::move(Pass)));
+ Passes.emplace_back(new FunctionPassModel<FunctionPassT>(std::move(Pass)));
}
PreservedAnalyses run(Function *F, FunctionAnalysisManager *AM = 0);
struct FunctionPassModel
: detail::PassModel<Function *, FunctionAnalysisManager, PassT> {
FunctionPassModel(PassT Pass)
- : detail::PassModel<Function *, FunctionAnalysisManager, PassT>(Pass) {}
+ : detail::PassModel<Function *, FunctionAnalysisManager, PassT>(
+ std::move(Pass)) {}
};
- std::vector<polymorphic_ptr<FunctionPassConcept> > Passes;
+ std::vector<std::unique_ptr<FunctionPassConcept>> Passes;
};
namespace detail {
assert(!AnalysisPasses.count(PassT::ID()) &&
"Registered the same analysis pass twice!");
typedef detail::AnalysisPassModel<IRUnitT, DerivedT, PassT> PassModelT;
- AnalysisPasses[PassT::ID()] = new PassModelT(std::move(Pass));
+ AnalysisPasses[PassT::ID()].reset(new PassModelT(std::move(Pass)));
}
/// \brief Invalidate a specific analysis pass for an IR module.
private:
/// \brief Map type from module analysis pass ID to pass concept pointer.
- typedef DenseMap<void *, polymorphic_ptr<PassConceptT> > AnalysisPassMapT;
+ typedef DenseMap<void *, std::unique_ptr<PassConceptT>> AnalysisPassMapT;
/// \brief Collection of module analysis passes, indexed by ID.
AnalysisPassMapT AnalysisPasses;
/// \brief Map type from module analysis pass ID to pass result concept pointer.
typedef DenseMap<void *,
- polymorphic_ptr<detail::AnalysisResultConcept<Module *> > >
+ std::unique_ptr<detail::AnalysisResultConcept<Module *>>>
ModuleAnalysisResultMapT;
/// \brief Cache of computed module analysis results for this module.
/// erases. Provides both the pass ID and concept pointer such that it is
/// half of a bijection and provides storage for the actual result concept.
typedef std::list<std::pair<
- void *, polymorphic_ptr<detail::AnalysisResultConcept<Function *> > > >
- FunctionAnalysisResultListT;
+ void *, std::unique_ptr<detail::AnalysisResultConcept<Function *>>>>
+ FunctionAnalysisResultListT;
/// \brief Map type from function pointer to our custom list type.
typedef DenseMap<Function *, FunctionAnalysisResultListT>
template <typename FunctionPassT>
ModuleToFunctionPassAdaptor<FunctionPassT>
createModuleToFunctionPassAdaptor(FunctionPassT Pass) {
- return ModuleToFunctionPassAdaptor<FunctionPassT>(std::move(Pass));
+ return std::move(ModuleToFunctionPassAdaptor<FunctionPassT>(std::move(Pass)));
}
}
ModulePassManager MPM;
// Count the runs over a Function.
- FunctionPassManager FPM1;
int FunctionPassRunCount1 = 0;
int AnalyzedInstrCount1 = 0;
int AnalyzedFunctionCount1 = 0;
- FPM1.addPass(TestFunctionPass(FunctionPassRunCount1, AnalyzedInstrCount1,
- AnalyzedFunctionCount1));
- MPM.addPass(createModuleToFunctionPassAdaptor(FPM1));
+ {
+ FunctionPassManager FPM;
+ FPM.addPass(TestFunctionPass(FunctionPassRunCount1, AnalyzedInstrCount1,
+ AnalyzedFunctionCount1));
+ MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
+ }
// Count the runs over a module.
int ModulePassRunCount = 0;
MPM.addPass(TestModulePass(ModulePassRunCount));
// Count the runs over a Function in a separate manager.
- FunctionPassManager FPM2;
int FunctionPassRunCount2 = 0;
int AnalyzedInstrCount2 = 0;
int AnalyzedFunctionCount2 = 0;
- FPM2.addPass(TestFunctionPass(FunctionPassRunCount2, AnalyzedInstrCount2,
- AnalyzedFunctionCount2));
- MPM.addPass(createModuleToFunctionPassAdaptor(FPM2));
+ {
+ FunctionPassManager FPM;
+ FPM.addPass(TestFunctionPass(FunctionPassRunCount2, AnalyzedInstrCount2,
+ AnalyzedFunctionCount2));
+ MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
+ }
// A third function pass manager but with only preserving intervening passes
// and with a function pass that invalidates exactly one analysis.
MPM.addPass(TestPreservingModulePass());
- FunctionPassManager FPM3;
int FunctionPassRunCount3 = 0;
int AnalyzedInstrCount3 = 0;
int AnalyzedFunctionCount3 = 0;
- FPM3.addPass(TestFunctionPass(FunctionPassRunCount3, AnalyzedInstrCount3,
- AnalyzedFunctionCount3));
- FPM3.addPass(TestInvalidationFunctionPass("f"));
- MPM.addPass(createModuleToFunctionPassAdaptor(FPM3));
+ {
+ FunctionPassManager FPM;
+ FPM.addPass(TestFunctionPass(FunctionPassRunCount3, AnalyzedInstrCount3,
+ AnalyzedFunctionCount3));
+ FPM.addPass(TestInvalidationFunctionPass("f"));
+ MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
+ }
// A fourth function pass manager but with a minimal intervening passes.
MPM.addPass(TestMinPreservingModulePass());
- FunctionPassManager FPM4;
int FunctionPassRunCount4 = 0;
int AnalyzedInstrCount4 = 0;
int AnalyzedFunctionCount4 = 0;
- FPM4.addPass(TestFunctionPass(FunctionPassRunCount4, AnalyzedInstrCount4,
- AnalyzedFunctionCount4));
- MPM.addPass(createModuleToFunctionPassAdaptor(FPM4));
+ {
+ FunctionPassManager FPM;
+ FPM.addPass(TestFunctionPass(FunctionPassRunCount4, AnalyzedInstrCount4,
+ AnalyzedFunctionCount4));
+ MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
+ }
// A fifth function pass manager but which uses only cached results.
- FunctionPassManager FPM5;
int FunctionPassRunCount5 = 0;
int AnalyzedInstrCount5 = 0;
int AnalyzedFunctionCount5 = 0;
- FPM5.addPass(TestInvalidationFunctionPass("f"));
- FPM5.addPass(TestFunctionPass(FunctionPassRunCount5, AnalyzedInstrCount5,
- AnalyzedFunctionCount5,
- /*OnlyUseCachedResults=*/true));
- MPM.addPass(createModuleToFunctionPassAdaptor(FPM5));
+ {
+ FunctionPassManager FPM;
+ FPM.addPass(TestInvalidationFunctionPass("f"));
+ FPM.addPass(TestFunctionPass(FunctionPassRunCount5, AnalyzedInstrCount5,
+ AnalyzedFunctionCount5,
+ /*OnlyUseCachedResults=*/true));
+ MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
+ }
MPM.run(M.get(), &MAM);