Index: include/llvm/Analysis/MemorySSA.h =================================================================== --- include/llvm/Analysis/MemorySSA.h +++ include/llvm/Analysis/MemorySSA.h @@ -703,6 +703,7 @@ ~MemorySSA(); MemorySSAWalker *getWalker(); + MemorySSAWalker *getTransformWalker(); /// 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 TransformWalker; unsigned NextID; }; Index: lib/Analysis/MemorySSA.cpp =================================================================== --- lib/Analysis/MemorySSA.cpp +++ lib/Analysis/MemorySSA.cpp @@ -997,6 +997,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, @@ -1132,7 +1157,7 @@ MemorySSA::MemorySSA(Function &Func, AliasAnalysis *AA, DominatorTree *DT) : AA(AA), DT(DT), F(Func), LiveOnEntryDef(nullptr), Walker(nullptr), - NextID(0) { + TransformWalker(nullptr), NextID(0) { buildMemorySSA(); } @@ -1470,6 +1495,18 @@ return Walker.get(); } +MemorySSAWalker *MemorySSA::getTransformWalker() { + if (TransformWalker) + return TransformWalker.get(); + + if (!WalkerBase) + WalkerBase = llvm::make_unique(this, AA, DT); + + TransformWalker = llvm::make_unique(this, WalkerBase.get()); + return TransformWalker.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. @@ -2300,6 +2337,17 @@ return Walker->getClobberingMemoryAccessBase(MA, Loc); } +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))