/// 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.
}
}
-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
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.
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);
}
}
// 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(