Index: llvm/trunk/include/llvm/Transforms/Utils/MemorySSA.h =================================================================== --- llvm/trunk/include/llvm/Transforms/Utils/MemorySSA.h +++ llvm/trunk/include/llvm/Transforms/Utils/MemorySSA.h @@ -246,6 +246,16 @@ return MA->getValueID() == MemoryUseVal || MA->getValueID() == MemoryDefVal; } + // Sadly, these have to be public because they are needed in some of the iterators. + virtual bool isOptimized() const = 0; + virtual MemoryAccess *getOptimized() const = 0; + virtual void setOptimized(MemoryAccess *) = 0; + + /// \brief Reset the ID of what this MemoryUse was optimized to, causing it to + /// be rewalked by the walker if necessary. + /// This really should only be called by tests. + virtual void resetOptimized() = 0; + protected: friend class MemorySSA; friend class MemorySSAUpdater; @@ -254,8 +264,12 @@ : MemoryAccess(C, Vty, BB, 1), MemoryInst(MI) { setDefiningAccess(DMA); } - - void setDefiningAccess(MemoryAccess *DMA) { setOperand(0, DMA); } + void setDefiningAccess(MemoryAccess *DMA, bool Optimized = false) { + setOperand(0, DMA); + if (!Optimized) + return; + setOptimized(DMA); + } private: Instruction *MemoryInst; @@ -288,20 +302,18 @@ void print(raw_ostream &OS) const override; - void setDefiningAccess(MemoryAccess *DMA, bool Optimized = false) { - if (Optimized) - OptimizedID = DMA->getID(); - MemoryUseOrDef::setDefiningAccess(DMA); + virtual void setOptimized(MemoryAccess *DMA) override { + OptimizedID = DMA->getID(); } - bool isOptimized() const { + virtual bool isOptimized() const override { return getDefiningAccess() && OptimizedID == getDefiningAccess()->getID(); } - /// \brief Reset the ID of what this MemoryUse was optimized to, causing it to - /// be rewalked by the walker if necessary. - /// This really should only be called by tests. - void resetOptimized() { OptimizedID = INVALID_MEMORYACCESS_ID; } + virtual MemoryAccess *getOptimized() const override { + return getDefiningAccess(); + } + virtual void resetOptimized() override { OptimizedID = INVALID_MEMORYACCESS_ID; } protected: friend class MemorySSA; @@ -333,7 +345,8 @@ MemoryDef(LLVMContext &C, MemoryAccess *DMA, Instruction *MI, BasicBlock *BB, unsigned Ver) - : MemoryUseOrDef(C, DMA, MemoryDefVal, MI, BB), ID(Ver) {} + : MemoryUseOrDef(C, DMA, MemoryDefVal, MI, BB), ID(Ver), + Optimized(nullptr), OptimizedID(INVALID_MEMORYACCESS_ID) {} // allocate space for exactly one operand void *operator new(size_t s) { return User::operator new(s, 1); } @@ -343,6 +356,17 @@ return MA->getValueID() == MemoryDefVal; } + virtual void setOptimized(MemoryAccess *MA) override { + Optimized = MA; + OptimizedID = getDefiningAccess()->getID(); + } + virtual MemoryAccess *getOptimized() const override { return Optimized; } + virtual bool isOptimized() const override { + return getOptimized() && OptimizedID == getDefiningAccess()->getID(); + } + virtual void resetOptimized() override { OptimizedID = INVALID_MEMORYACCESS_ID; } + + void print(raw_ostream &OS) const override; protected: @@ -352,6 +376,8 @@ private: const unsigned ID; + MemoryAccess *Optimized; + unsigned int OptimizedID; }; template <> @@ -1075,10 +1101,15 @@ def_chain_iterator &operator++() { // N.B. liveOnEntry has a null defining access. - if (auto *MUD = dyn_cast(MA)) - MA = MUD->getDefiningAccess(); - else + if (auto *MUD = dyn_cast(MA)) { + if (MUD->isOptimized()) + MA = MUD->getOptimized(); + else + MA = MUD->getDefiningAccess(); + } else { MA = nullptr; + } + return *this; } Index: llvm/trunk/lib/Transforms/Utils/MemorySSA.cpp =================================================================== --- llvm/trunk/lib/Transforms/Utils/MemorySSA.cpp +++ llvm/trunk/lib/Transforms/Utils/MemorySSA.cpp @@ -2181,9 +2181,9 @@ // If this is an already optimized use or def, return the optimized result. // Note: Currently, we do not store the optimized def result because we'd need // a separate field, since we can't use it as the defining access. - if (MemoryUse *MU = dyn_cast(StartingAccess)) - if (MU->isOptimized()) - return MU->getDefiningAccess(); + if (auto *MUD = dyn_cast(StartingAccess)) + if (MUD->isOptimized()) + return MUD->getOptimized(); const Instruction *I = StartingAccess->getMemoryInst(); UpwardsMemoryQuery Q(I, StartingAccess); @@ -2199,8 +2199,8 @@ if (isUseTriviallyOptimizableToLiveOnEntry(*MSSA->AA, I)) { MemoryAccess *LiveOnEntry = MSSA->getLiveOnEntryDef(); Cache.insert(StartingAccess, LiveOnEntry, Q.StartingLoc, Q.IsCall); - if (MemoryUse *MU = dyn_cast(StartingAccess)) - MU->setDefiningAccess(LiveOnEntry, true); + if (auto *MUD = dyn_cast(StartingAccess)) + MUD->setDefiningAccess(LiveOnEntry, true); return LiveOnEntry; } @@ -2217,8 +2217,8 @@ DEBUG(dbgs() << *DefiningAccess << "\n"); DEBUG(dbgs() << "Final Memory SSA clobber for " << *I << " is "); DEBUG(dbgs() << *Result << "\n"); - if (MemoryUse *MU = dyn_cast(StartingAccess)) - MU->setDefiningAccess(Result, true); + if (auto *MUD = dyn_cast(StartingAccess)) + MUD->setDefiningAccess(Result, true); return Result; } Index: llvm/trunk/lib/Transforms/Utils/MemorySSAUpdater.cpp =================================================================== --- llvm/trunk/lib/Transforms/Utils/MemorySSAUpdater.cpp +++ llvm/trunk/lib/Transforms/Utils/MemorySSAUpdater.cpp @@ -451,8 +451,8 @@ while (!MA->use_empty()) { Use &U = *MA->use_begin(); - if (MemoryUse *MU = dyn_cast(U.getUser())) - MU->resetOptimized(); + if (auto *MUD = dyn_cast(U.getUser())) + MUD->resetOptimized(); U.set(NewDefTarget); } }