[MemorySSA] Ensure address stability of MemorySSA object.

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
This commit is contained in:
Geoff Berry 2016-08-08 17:52:01 +00:00
parent 3ee803a895
commit cdf5333f6f
2 changed files with 17 additions and 20 deletions

View 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.

View 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();
}