Index: llvm/trunk/include/llvm/Transforms/Utils/Local.h =================================================================== --- llvm/trunk/include/llvm/Transforms/Utils/Local.h +++ llvm/trunk/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: llvm/trunk/lib/Transforms/Utils/Local.cpp =================================================================== --- llvm/trunk/lib/Transforms/Utils/Local.cpp +++ llvm/trunk/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,15 +2228,23 @@ assert(Reachable.size() < F.size()); NumRemoved += F.size()-Reachable.size(); - // 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; + 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; + for (auto *BB : DeadBlockSet) { for (BasicBlock *Successor : successors(BB)) { - if (Reachable.count(Successor)) + if (!DeadBlockSet.count(Successor)) Successor->removePredecessor(BB); if (DTU) Updates.push_back({DominatorTree::Delete, BB, Successor}); @@ -2241,7 +2253,6 @@ LVI->eraseBlock(BB); BB->dropAllReferences(); } - SmallVector ToDeleteBBs; for (Function::iterator I = ++F.begin(); I != F.end();) { auto *BB = &*I; if (Reachable.count(BB)) { @@ -2249,8 +2260,6 @@ continue; } if (DTU) { - ToDeleteBBs.push_back(BB); - // Remove the TerminatorInst of BB to clear the successor list of BB. if (BB->getTerminator()) BB->getInstList().pop_back(); @@ -2266,7 +2275,7 @@ if (DTU) { DTU->applyUpdates(Updates, /*ForceRemoveDuplicates*/ true); bool Deleted = false; - for (auto *BB : ToDeleteBBs) { + for (auto *BB : DeadBlockSet) { if (DTU->isBBPendingDeletion(BB)) --NumRemoved; else