[PM] Switch new pass manager from polymorphic_ptr to unique_ptr now that
authorChandler Carruth <chandlerc@gmail.com>
Sun, 9 Mar 2014 11:49:53 +0000 (11:49 +0000)
committerChandler Carruth <chandlerc@gmail.com>
Sun, 9 Mar 2014 11:49:53 +0000 (11:49 +0000)
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
lib/IR/PassManager.cpp
tools/opt/Passes.cpp
unittests/IR/PassManagerTest.cpp

index e4260ba77d383d74c16ad07cc2141f04eafd2935..6e2a01fbb2cb2b2b2589d5805a0a8f7b15cf5914 100644 (file)
 #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 {
@@ -158,7 +159,6 @@ namespace detail {
 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.
   ///
@@ -205,7 +205,6 @@ template <typename IRUnitT, typename AnalysisManagerT, typename PassT>
 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);
   }
@@ -219,7 +218,6 @@ template <typename IRUnitT, typename AnalysisManagerT, typename PassT>
 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);
   }
@@ -233,7 +231,6 @@ struct PassModel<IRUnitT, AnalysisManagerT, PassT,
 /// to.
 template <typename IRUnitT> struct AnalysisResultConcept {
   virtual ~AnalysisResultConcept() {}
-  virtual AnalysisResultConcept *clone() = 0;
 
   /// \brief Method to try and mark a result as invalid.
   ///
@@ -281,9 +278,6 @@ template <typename IRUnitT, typename PassT, typename ResultT>
 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.
   //
@@ -303,9 +297,6 @@ template <typename IRUnitT, typename PassT, typename ResultT>
 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 {
@@ -322,13 +313,12 @@ struct AnalysisResultModel<IRUnitT, PassT, ResultT,
 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.
@@ -348,7 +338,6 @@ struct AnalysisPassModel<IRUnitT, AnalysisManagerT, PassT,
                          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>
@@ -357,8 +346,9 @@ struct AnalysisPassModel<IRUnitT, AnalysisManagerT, PassT,
   /// \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;
@@ -371,7 +361,6 @@ struct AnalysisPassModel<IRUnitT, AnalysisManagerT, PassT,
                          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>
@@ -380,8 +369,9 @@ struct AnalysisPassModel<IRUnitT, AnalysisManagerT, PassT,
   /// \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;
@@ -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 <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"; }
@@ -415,20 +403,19 @@ private:
   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);
@@ -443,10 +430,11 @@ private:
   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 {
@@ -519,7 +507,7 @@ public:
     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.
@@ -558,7 +546,7 @@ protected:
 
 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;
@@ -593,7 +581,7 @@ private:
 
   /// \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.
@@ -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<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>
@@ -826,7 +814,7 @@ private:
 template <typename FunctionPassT>
 ModuleToFunctionPassAdaptor<FunctionPassT>
 createModuleToFunctionPassAdaptor(FunctionPassT Pass) {
-  return ModuleToFunctionPassAdaptor<FunctionPassT>(std::move(Pass));
+  return std::move(ModuleToFunctionPassAdaptor<FunctionPassT>(std::move(Pass)));
 }
 
 }
index 288940b2923afc5cfda7a8e91ca16e0e4e0751ed..8d0044e7f96e535ea188e2a8555876731a0a6c34 100644 (file)
@@ -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<detail::AnalysisResultConcept<Module *> >()));
+      PassID, std::unique_ptr<detail::AnalysisResultConcept<Module *>>()));
 
   // 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());
   }
 
index ca143042f602c0ae44c846735fbc9117efe6c7ab..ffdf9bfec1ffa3dc14b81f806d55e49ceb2d9377 100644 (file)
@@ -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;
   }
 
index 75ba02b3a40c961c87323cd6896ce074f38f5507..157c881ea59b8eabea2779b2c80297dda2b7fd35 100644 (file)
@@ -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);