Index: include/llvm/Transforms/Utils/Local.h =================================================================== --- include/llvm/Transforms/Utils/Local.h +++ include/llvm/Transforms/Utils/Local.h @@ -52,6 +52,7 @@ class LazyValueInfo; class LoadInst; class MDNode; +class MemorySSAUpdater; class PHINode; class StoreInst; class TargetLibraryInfo; @@ -141,8 +142,9 @@ /// If the specified value is a trivially dead instruction, delete it. /// If that makes any of its operands trivially dead, delete them too, /// recursively. Return true if any instructions were deleted. -bool RecursivelyDeleteTriviallyDeadInstructions(Value *V, - const TargetLibraryInfo *TLI = nullptr); +bool RecursivelyDeleteTriviallyDeadInstructions( + Value *V, const TargetLibraryInfo *TLI = nullptr, + MemorySSAUpdater *MSSAU = nullptr); /// Delete all of the instructions in `DeadInsts`, and all other instructions /// that deleting these in turn causes to be trivially dead. @@ -154,7 +156,7 @@ /// empty afterward. void RecursivelyDeleteTriviallyDeadInstructions( SmallVectorImpl &DeadInsts, - const TargetLibraryInfo *TLI = nullptr); + const TargetLibraryInfo *TLI = nullptr, MemorySSAUpdater *MSSAU = nullptr); /// If the specified value is an effectively dead PHI node, due to being a /// def-use chain of single-use nodes that either forms a cycle or is terminated @@ -380,7 +382,8 @@ /// /// Returns true if any basic block was removed. bool removeUnreachableBlocks(Function &F, LazyValueInfo *LVI = nullptr, - DomTreeUpdater *DTU = nullptr); + DomTreeUpdater *DTU = nullptr, + MemorySSAUpdater *MSSAU = nullptr); /// Combine the metadata of two instructions so that K can replace J. Some /// metadata kinds can only be kept if K does not move, meaning it dominated Index: lib/Transforms/Utils/Local.cpp =================================================================== --- lib/Transforms/Utils/Local.cpp +++ lib/Transforms/Utils/Local.cpp @@ -31,6 +31,7 @@ #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/LazyValueInfo.h" #include "llvm/Analysis/MemoryBuiltins.h" +#include "llvm/Analysis/MemorySSAUpdater.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/BinaryFormat/Dwarf.h" @@ -426,22 +427,22 @@ /// trivially dead instruction, delete it. If that makes any of its operands /// trivially dead, delete them too, recursively. Return true if any /// instructions were deleted. -bool -llvm::RecursivelyDeleteTriviallyDeadInstructions(Value *V, - const TargetLibraryInfo *TLI) { +bool llvm::RecursivelyDeleteTriviallyDeadInstructions( + Value *V, const TargetLibraryInfo *TLI, MemorySSAUpdater *MSSAU) { Instruction *I = dyn_cast(V); if (!I || !I->use_empty() || !isInstructionTriviallyDead(I, TLI)) return false; SmallVector DeadInsts; DeadInsts.push_back(I); - RecursivelyDeleteTriviallyDeadInstructions(DeadInsts, TLI); + RecursivelyDeleteTriviallyDeadInstructions(DeadInsts, TLI, MSSAU); return true; } void llvm::RecursivelyDeleteTriviallyDeadInstructions( - SmallVectorImpl &DeadInsts, const TargetLibraryInfo *TLI) { + SmallVectorImpl &DeadInsts, const TargetLibraryInfo *TLI, + MemorySSAUpdater *MSSAU) { // Process the dead instruction list until empty. while (!DeadInsts.empty()) { Instruction &I = *DeadInsts.pop_back_val(); @@ -468,6 +469,8 @@ if (isInstructionTriviallyDead(OpI, TLI)) DeadInsts.push_back(OpI); } + if (MSSAU) + MSSAU->removeMemoryAccess(&I); I.eraseFromParent(); } @@ -655,7 +658,7 @@ } /// MergeBasicBlockIntoOnlyPred - DestBB is a block with one predecessor and its -/// predecessor is known to have one successor (DestBB!). Eliminate the edge +/// predecessor is known to have one successor (DestBB!). Eliminate the edge /// between them, moving the instructions in the predecessor into DestBB and /// deleting the predecessor block. void llvm::MergeBasicBlockIntoOnlyPred(BasicBlock *DestBB, @@ -2213,7 +2216,8 @@ /// otherwise. If `LVI` is passed, this function preserves LazyValueInfo /// after modifying the CFG. bool llvm::removeUnreachableBlocks(Function &F, LazyValueInfo *LVI, - DomTreeUpdater *DTU) { + DomTreeUpdater *DTU, + MemorySSAUpdater *MSSAU) { SmallPtrSet Reachable; bool Changed = markAliveBlocks(F, Reachable, DTU); @@ -2224,6 +2228,18 @@ assert(Reachable.size() < F.size()); NumRemoved += F.size()-Reachable.size(); + // FIXME: May reuse this set below if deletion order does not matter. + SmallPtrSet DeadBlockSet; + for (Function::iterator I = ++F.begin(), E = F.end(); I != E; ++I) { + auto *BB = &*I; + if (Reachable.count(BB)) + continue; + DeadBlockSet.insert(BB); + } + + if (MSSAU) + MSSAU->removeBlocks(DeadBlockSet); + // Loop over all of the basic blocks that are not reachable, dropping all of // their internal references. Update DTU and LVI if available. std::vector Updates;