[MemorySSA] Ensure address stability of MemorySSA object.
authorGeoff Berry <gberry@codeaurora.org>
Mon, 8 Aug 2016 17:52:01 +0000 (17:52 +0000)
committerGeoff Berry <gberry@codeaurora.org>
Mon, 8 Aug 2016 17:52:01 +0000 (17:52 +0000)
Summary:
Ensure that the MemorySSA object never changes address when using the
new pass manager since the walkers contained by MemorySSA cache pointers
to it at construction time.  This is achieved by wrapping the
MemorySSAAnalysis result in a unique_ptr.  Also add some asserts that
check for this bug.

Reviewers: george.burgess.iv, dberlin

Subscribers: mcrosier, hfinkel, chandlerc, silvas, llvm-commits

Differential Revision: https://reviews.llvm.org/D23171

llvm-svn: 278028

llvm/include/llvm/Transforms/Utils/MemorySSA.h
llvm/lib/Transforms/Utils/MemorySSA.cpp

index ef42b79..b356e8a 100644 (file)
@@ -494,7 +494,6 @@ class MemorySSAWalker;
 class MemorySSA {
 public:
   MemorySSA(Function &, AliasAnalysis *, DominatorTree *);
-  MemorySSA(MemorySSA &&);
   ~MemorySSA();
 
   MemorySSAWalker *getWalker();
@@ -676,9 +675,9 @@ class MemorySSAAnalysis : public AnalysisInfoMixin<MemorySSAAnalysis> {
   static char PassID;
 
 public:
-  typedef MemorySSA Result;
+  typedef std::unique_ptr<MemorySSA> Result;
 
-  MemorySSA run(Function &F, AnalysisManager<Function> &AM);
+  Result run(Function &F, AnalysisManager<Function> &AM);
 };
 
 /// \brief Printer pass for \c MemorySSA.
@@ -786,6 +785,8 @@ public:
   /// the walker it uses or returns.
   virtual void invalidateInfo(MemoryAccess *) {}
 
+  virtual void verify(const MemorySSA *MSSA) { assert(MSSA == this->MSSA); }
+
 protected:
   friend class MemorySSA; // For updating MSSA pointer in MemorySSA move
                           // constructor.
index 234d1af..f349958 100644 (file)
@@ -1025,6 +1025,8 @@ public:
 #endif
     return Result;
   }
+
+  void verify(const MemorySSA *MSSA) { assert(MSSA == &this->MSSA); }
 };
 
 struct RenamePassData {
@@ -1104,6 +1106,11 @@ public:
   /// earliest-MemoryAccess-we-can-optimize-to". This is necessary if we're
   /// going to have DT updates, if we remove MemoryAccesses, etc.
   void resetClobberWalker() { Walker.reset(); }
+
+  void verify(const MemorySSA *MSSA) override {
+    MemorySSAWalker::verify(MSSA);
+    Walker.verify(MSSA);
+  }
 };
 
 /// \brief Rename a single basic block into MemorySSA form.
@@ -1231,19 +1238,6 @@ MemorySSA::MemorySSA(Function &Func, AliasAnalysis *AA, DominatorTree *DT)
   buildMemorySSA();
 }
 
-MemorySSA::MemorySSA(MemorySSA &&MSSA)
-    : AA(MSSA.AA), DT(MSSA.DT), F(MSSA.F),
-      ValueToMemoryAccess(std::move(MSSA.ValueToMemoryAccess)),
-      PerBlockAccesses(std::move(MSSA.PerBlockAccesses)),
-      LiveOnEntryDef(std::move(MSSA.LiveOnEntryDef)),
-      BlockNumberingValid(std::move(MSSA.BlockNumberingValid)),
-      BlockNumbering(std::move(MSSA.BlockNumbering)),
-      Walker(std::move(MSSA.Walker)), NextID(MSSA.NextID) {
-  // Update the Walker MSSA pointer so it doesn't point to the moved-from MSSA
-  // object any more.
-  Walker->MSSA = this;
-}
-
 MemorySSA::~MemorySSA() {
   // Drop all our references
   for (const auto &Pair : PerBlockAccesses)
@@ -1818,6 +1812,7 @@ void MemorySSA::verifyMemorySSA() const {
   verifyDefUses(F);
   verifyDomination(F);
   verifyOrdering(F);
+  Walker->verify(this);
 }
 
 /// \brief Verify that the order and existence of MemoryAccesses matches the
@@ -2083,23 +2078,24 @@ bool MemorySSAPrinterLegacyPass::runOnFunction(Function &F) {
 
 char MemorySSAAnalysis::PassID;
 
-MemorySSA MemorySSAAnalysis::run(Function &F, AnalysisManager<Function> &AM) {
+std::unique_ptr<MemorySSA>
+MemorySSAAnalysis::run(Function &F, AnalysisManager<Function> &AM) {
   auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
   auto &AA = AM.getResult<AAManager>(F);
-  return MemorySSA(F, &AA, &DT);
+  return make_unique<MemorySSA>(F, &AA, &DT);
 }
 
 PreservedAnalyses MemorySSAPrinterPass::run(Function &F,
                                             FunctionAnalysisManager &AM) {
   OS << "MemorySSA for function: " << F.getName() << "\n";
-  AM.getResult<MemorySSAAnalysis>(F).print(OS);
+  AM.getResult<MemorySSAAnalysis>(F)->print(OS);
 
   return PreservedAnalyses::all();
 }
 
 PreservedAnalyses MemorySSAVerifierPass::run(Function &F,
                                              FunctionAnalysisManager &AM) {
-  AM.getResult<MemorySSAAnalysis>(F).verifyMemorySSA();
+  AM.getResult<MemorySSAAnalysis>(F)->verifyMemorySSA();
 
   return PreservedAnalyses::all();
 }