Index: llvm/trunk/include/llvm/Analysis/MemorySSA.h =================================================================== --- llvm/trunk/include/llvm/Analysis/MemorySSA.h +++ llvm/trunk/include/llvm/Analysis/MemorySSA.h @@ -703,6 +703,7 @@ ~MemorySSA(); MemorySSAWalker *getWalker(); + MemorySSAWalker *getSkipSelfWalker(); /// Given a memory Mod/Ref'ing instruction, get the MemorySSA /// access associated with it. If passed a basic block gets the memory phi @@ -830,6 +831,7 @@ private: class ClobberWalkerBase; class CachingWalker; + class SkipSelfWalker; class OptimizeUses; CachingWalker *getWalkerImpl(); @@ -885,6 +887,7 @@ // Memory SSA building info std::unique_ptr WalkerBase; std::unique_ptr Walker; + std::unique_ptr SkipWalker; unsigned NextID; }; Index: llvm/trunk/lib/Analysis/MemorySSA.cpp =================================================================== --- llvm/trunk/lib/Analysis/MemorySSA.cpp +++ llvm/trunk/lib/Analysis/MemorySSA.cpp @@ -994,6 +994,31 @@ } }; +class MemorySSA::SkipSelfWalker final : public MemorySSAWalker { + ClobberWalkerBase *Walker; + +public: + SkipSelfWalker(MemorySSA *M, ClobberWalkerBase *W) + : MemorySSAWalker(M), Walker(W) {} + ~SkipSelfWalker() override = default; + + using MemorySSAWalker::getClobberingMemoryAccess; + + MemoryAccess *getClobberingMemoryAccess(MemoryAccess *MA) override; + MemoryAccess *getClobberingMemoryAccess(MemoryAccess *MA, + const MemoryLocation &Loc) override; + + void invalidateInfo(MemoryAccess *MA) override { + if (auto *MUD = dyn_cast(MA)) + MUD->resetOptimized(); + } + + void verify(const MemorySSA *MSSA) override { + MemorySSAWalker::verify(MSSA); + Walker->verify(MSSA); + } +}; + } // end namespace llvm void MemorySSA::renameSuccessorPhis(BasicBlock *BB, MemoryAccess *IncomingVal, @@ -1129,7 +1154,7 @@ MemorySSA::MemorySSA(Function &Func, AliasAnalysis *AA, DominatorTree *DT) : AA(AA), DT(DT), F(Func), LiveOnEntryDef(nullptr), Walker(nullptr), - NextID(0) { + SkipWalker(nullptr), NextID(0) { buildMemorySSA(); } @@ -1467,6 +1492,18 @@ return Walker.get(); } +MemorySSAWalker *MemorySSA::getSkipSelfWalker() { + if (SkipWalker) + return SkipWalker.get(); + + if (!WalkerBase) + WalkerBase = llvm::make_unique(this, AA, DT); + + SkipWalker = llvm::make_unique(this, WalkerBase.get()); + return SkipWalker.get(); + } + + // This is a helper function used by the creation routines. It places NewAccess // into the access and defs lists for a given basic block, at the given // insertion point. @@ -2298,6 +2335,17 @@ } MemoryAccess * +MemorySSA::SkipSelfWalker::getClobberingMemoryAccess(MemoryAccess *MA) { + return Walker->getClobberingMemoryAccessBase(MA, true); +} + +MemoryAccess * +MemorySSA::SkipSelfWalker::getClobberingMemoryAccess(MemoryAccess *MA, + const MemoryLocation &Loc) { + return Walker->getClobberingMemoryAccessBase(MA, Loc); +} + +MemoryAccess * DoNothingMemorySSAWalker::getClobberingMemoryAccess(MemoryAccess *MA) { if (auto *Use = dyn_cast(MA)) return Use->getDefiningAccess();