From 15903b7dc5cc31c529010b659eab326fd7565671 Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Sun, 9 Mar 2014 11:49:53 +0000 Subject: [PATCH] [PM] Switch new pass manager from polymorphic_ptr to unique_ptr now that it is available. Also make the move semantics sufficiently correct to tolerate move-only passes, as the PassManagers *are* move-only passes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@203391 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/IR/PassManager.h | 64 +++++++++++++------------------- lib/IR/PassManager.cpp | 6 +-- tools/opt/Passes.cpp | 10 ++--- unittests/IR/PassManagerTest.cpp | 56 ++++++++++++++++------------ 4 files changed, 67 insertions(+), 69 deletions(-) diff --git a/include/llvm/IR/PassManager.h b/include/llvm/IR/PassManager.h index e4260ba77d3..6e2a01fbb2c 100644 --- a/include/llvm/IR/PassManager.h +++ b/include/llvm/IR/PassManager.h @@ -39,12 +39,13 @@ #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 +#include #include namespace llvm { @@ -158,7 +159,6 @@ namespace detail { template 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. /// @@ -205,7 +205,6 @@ template struct PassModel : PassConcept { 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); } @@ -219,7 +218,6 @@ template struct PassModel : PassConcept { 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); } @@ -233,7 +231,6 @@ struct PassModel struct AnalysisResultConcept { virtual ~AnalysisResultConcept() {} - virtual AnalysisResultConcept *clone() = 0; /// \brief Method to try and mark a result as invalid. /// @@ -281,9 +278,6 @@ template struct AnalysisResultModel : AnalysisResultConcept { 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. // @@ -303,9 +297,6 @@ template struct AnalysisResultModel : AnalysisResultConcept { 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 { @@ -322,13 +313,12 @@ struct AnalysisResultModel 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 *run(IRUnitT IR, - AnalysisManagerT *AM) = 0; + /// \returns A unique_ptr to the analysis result object to be queried by + /// users. + virtual std::unique_ptr> + run(IRUnitT IR, AnalysisManagerT *AM) = 0; }; /// \brief Wrapper to model the analysis pass concept. @@ -348,7 +338,6 @@ struct AnalysisPassModel : AnalysisPassConcept { 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 @@ -357,8 +346,9 @@ struct AnalysisPassModel> + run(IRUnitT IR, AnalysisManagerT *AM) override { + return make_unique(Pass.run(IR, AM)); } PassT Pass; @@ -371,7 +361,6 @@ struct AnalysisPassModel : AnalysisPassConcept { 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 @@ -380,8 +369,9 @@ struct AnalysisPassModel> + run(IRUnitT IR, AnalysisManagerT *) override { + return make_unique(Pass.run(IR)); } PassT Pass; @@ -393,8 +383,6 @@ class ModuleAnalysisManager; class ModulePassManager { public: - explicit ModulePassManager() {} - /// \brief Run all of the module passes in this module pass manager over /// a module. /// @@ -403,7 +391,7 @@ public: PreservedAnalyses run(Module *M, ModuleAnalysisManager *AM = 0); template void addPass(ModulePassT Pass) { - Passes.push_back(new ModulePassModel(std::move(Pass))); + Passes.emplace_back(new ModulePassModel(std::move(Pass))); } static StringRef name() { return "ModulePassManager"; } @@ -415,20 +403,19 @@ private: struct ModulePassModel : detail::PassModel { ModulePassModel(PassT Pass) - : detail::PassModel(Pass) {} + : detail::PassModel( + std::move(Pass)) {} }; - std::vector > Passes; + std::vector> Passes; }; class FunctionAnalysisManager; class FunctionPassManager { public: - explicit FunctionPassManager() {} - template void addPass(FunctionPassT Pass) { - Passes.push_back(new FunctionPassModel(std::move(Pass))); + Passes.emplace_back(new FunctionPassModel(std::move(Pass))); } PreservedAnalyses run(Function *F, FunctionAnalysisManager *AM = 0); @@ -443,10 +430,11 @@ private: struct FunctionPassModel : detail::PassModel { FunctionPassModel(PassT Pass) - : detail::PassModel(Pass) {} + : detail::PassModel( + std::move(Pass)) {} }; - std::vector > Passes; + std::vector> Passes; }; namespace detail { @@ -519,7 +507,7 @@ public: assert(!AnalysisPasses.count(PassT::ID()) && "Registered the same analysis pass twice!"); typedef detail::AnalysisPassModel 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. @@ -558,7 +546,7 @@ protected: private: /// \brief Map type from module analysis pass ID to pass concept pointer. - typedef DenseMap > AnalysisPassMapT; + typedef DenseMap> AnalysisPassMapT; /// \brief Collection of module analysis passes, indexed by ID. AnalysisPassMapT AnalysisPasses; @@ -593,7 +581,7 @@ private: /// \brief Map type from module analysis pass ID to pass result concept pointer. typedef DenseMap > > + std::unique_ptr>> ModuleAnalysisResultMapT; /// \brief Cache of computed module analysis results for this module. @@ -642,8 +630,8 @@ private: /// 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 > > > - FunctionAnalysisResultListT; + void *, std::unique_ptr>>> + FunctionAnalysisResultListT; /// \brief Map type from function pointer to our custom list type. typedef DenseMap @@ -826,7 +814,7 @@ private: template ModuleToFunctionPassAdaptor createModuleToFunctionPassAdaptor(FunctionPassT Pass) { - return ModuleToFunctionPassAdaptor(std::move(Pass)); + return std::move(ModuleToFunctionPassAdaptor(std::move(Pass))); } } diff --git a/lib/IR/PassManager.cpp b/lib/IR/PassManager.cpp index 288940b2923..8d0044e7f96 100644 --- a/lib/IR/PassManager.cpp +++ b/lib/IR/PassManager.cpp @@ -45,12 +45,12 @@ ModuleAnalysisManager::getResultImpl(void *PassID, Module *M) { ModuleAnalysisResultMapT::iterator RI; bool Inserted; std::tie(RI, Inserted) = ModuleAnalysisResults.insert(std::make_pair( - PassID, polymorphic_ptr >())); + PassID, std::unique_ptr>())); // If we don't have a cached result for this module, look up the pass and run // it to produce a result, which we then add to the cache. if (Inserted) - RI->second = lookupPass(PassID).run(M, this); + RI->second = std::move(lookupPass(PassID).run(M, this)); return *RI->second; } @@ -122,7 +122,7 @@ FunctionAnalysisManager::getResultImpl(void *PassID, Function *F) { // run it to produce a result, which we then add to the cache. if (Inserted) { FunctionAnalysisResultListT &ResultList = FunctionAnalysisResultLists[F]; - ResultList.push_back(std::make_pair(PassID, lookupPass(PassID).run(F, this))); + ResultList.emplace_back(PassID, lookupPass(PassID).run(F, this)); RI->second = std::prev(ResultList.end()); } diff --git a/tools/opt/Passes.cpp b/tools/opt/Passes.cpp index ca143042f60..ffdf9bfec1f 100644 --- a/tools/opt/Passes.cpp +++ b/tools/opt/Passes.cpp @@ -101,7 +101,7 @@ static bool parseFunctionPassPipeline(FunctionPassManager &FPM, PipelineText = PipelineText.substr(1); // Add the nested pass manager with the appropriate adaptor. - FPM.addPass(NestedFPM); + FPM.addPass(std::move(NestedFPM)); } else { // Otherwise try to parse a pass name. size_t End = PipelineText.find_first_of(",)"); @@ -138,7 +138,7 @@ static bool parseModulePassPipeline(ModulePassManager &MPM, PipelineText = PipelineText.substr(1); // Now add the nested manager as a module pass. - MPM.addPass(NestedMPM); + MPM.addPass(std::move(NestedMPM)); } else if (PipelineText.startswith("function(")) { FunctionPassManager NestedFPM; @@ -151,7 +151,7 @@ static bool parseModulePassPipeline(ModulePassManager &MPM, PipelineText = PipelineText.substr(1); // Add the nested pass manager with the appropriate adaptor. - MPM.addPass(createModuleToFunctionPassAdaptor(NestedFPM)); + MPM.addPass(createModuleToFunctionPassAdaptor(std::move(NestedFPM))); } else { // Otherwise try to parse a pass name. size_t End = PipelineText.find_first_of(",)"); @@ -185,7 +185,7 @@ bool llvm::parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText, if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass) || !PipelineText.empty()) return false; - MPM.addPass(createModuleToFunctionPassAdaptor(FPM)); + MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM))); return true; } @@ -201,7 +201,7 @@ bool llvm::parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText, if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass) || !PipelineText.empty()) return false; - MPM.addPass(createModuleToFunctionPassAdaptor(FPM)); + MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM))); return true; } diff --git a/unittests/IR/PassManagerTest.cpp b/unittests/IR/PassManagerTest.cpp index 75ba02b3a40..157c881ea59 100644 --- a/unittests/IR/PassManagerTest.cpp +++ b/unittests/IR/PassManagerTest.cpp @@ -207,59 +207,69 @@ TEST_F(PassManagerTest, Basic) { 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);