diff options
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/include/llvm/Analysis/MemorySSAUpdater.h | 6 | ||||
-rw-r--r-- | llvm/lib/Analysis/MemorySSAUpdater.cpp | 22 |
2 files changed, 24 insertions, 4 deletions
diff --git a/llvm/include/llvm/Analysis/MemorySSAUpdater.h b/llvm/include/llvm/Analysis/MemorySSAUpdater.h index b71f7358bff..58cf1cc6b5d 100644 --- a/llvm/include/llvm/Analysis/MemorySSAUpdater.h +++ b/llvm/include/llvm/Analysis/MemorySSAUpdater.h @@ -221,14 +221,14 @@ public: /// associated with it is erased from the program. For example, if a store or /// load is simply erased (not replaced), removeMemoryAccess should be called /// on the MemoryAccess for that store/load. - void removeMemoryAccess(MemoryAccess *); + void removeMemoryAccess(MemoryAccess *, bool OptimizePhis = false); /// Remove MemoryAccess for a given instruction, if a MemoryAccess exists. /// This should be called when an instruction (load/store) is deleted from /// the program. - void removeMemoryAccess(const Instruction *I) { + void removeMemoryAccess(const Instruction *I, bool OptimizePhis = false) { if (MemoryAccess *MA = MSSA->getMemoryAccess(I)) - removeMemoryAccess(MA); + removeMemoryAccess(MA, OptimizePhis); } /// Remove all MemoryAcceses in a set of BasicBlocks about to be deleted. diff --git a/llvm/lib/Analysis/MemorySSAUpdater.cpp b/llvm/lib/Analysis/MemorySSAUpdater.cpp index f42dbbf4348..54cd265aaa9 100644 --- a/llvm/lib/Analysis/MemorySSAUpdater.cpp +++ b/llvm/lib/Analysis/MemorySSAUpdater.cpp @@ -1051,7 +1051,7 @@ void MemorySSAUpdater::wireOldPredecessorsToNewImmediatePredecessor( } } -void MemorySSAUpdater::removeMemoryAccess(MemoryAccess *MA) { +void MemorySSAUpdater::removeMemoryAccess(MemoryAccess *MA, bool OptimizePhis) { assert(!MSSA->isLiveOnEntryDef(MA) && "Trying to remove the live on entry def"); // We can only delete phi nodes if they have no uses, or we can replace all @@ -1070,6 +1070,8 @@ void MemorySSAUpdater::removeMemoryAccess(MemoryAccess *MA) { NewDefTarget = cast<MemoryUseOrDef>(MA)->getDefiningAccess(); } + SmallSetVector<MemoryPhi *, 4> PhisToCheck; + // Re-point the uses at our defining access if (!isa<MemoryUse>(MA) && !MA->use_empty()) { // Reset optimized on users of this store, and reset the uses. @@ -1089,6 +1091,9 @@ void MemorySSAUpdater::removeMemoryAccess(MemoryAccess *MA) { Use &U = *MA->use_begin(); if (auto *MUD = dyn_cast<MemoryUseOrDef>(U.getUser())) MUD->resetOptimized(); + if (OptimizePhis) + if (MemoryPhi *MP = dyn_cast<MemoryPhi>(U.getUser())) + PhisToCheck.insert(MP); U.set(NewDefTarget); } } @@ -1097,6 +1102,21 @@ void MemorySSAUpdater::removeMemoryAccess(MemoryAccess *MA) { // are doing things here MSSA->removeFromLookups(MA); MSSA->removeFromLists(MA); + + // Optionally optimize Phi uses. This will recursively remove trivial phis. + if (!PhisToCheck.empty()) { + SmallVector<WeakVH, 16> PhisToOptimize{PhisToCheck.begin(), + PhisToCheck.end()}; + PhisToCheck.clear(); + + unsigned PhisSize = PhisToOptimize.size(); + while (PhisSize-- > 0) + if (MemoryPhi *MP = + cast_or_null<MemoryPhi>(PhisToOptimize.pop_back_val())) { + auto OperRange = MP->operands(); + tryRemoveTrivialPhi(MP, OperRange); + } + } } void MemorySSAUpdater::removeBlocks( |