[llvm] r336015 - [MemorySSA] Add APIs to MemoryPhis to delete incoming blocks/values, and an updater API to remove blocks.
Alina Sbirlea via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 29 13:46:16 PDT 2018
Author: asbirlea
Date: Fri Jun 29 13:46:16 2018
New Revision: 336015
URL: http://llvm.org/viewvc/llvm-project?rev=336015&view=rev
Log:
[MemorySSA] Add APIs to MemoryPhis to delete incoming blocks/values, and an updater API to remove blocks.
Summary:
MemoryPhis now have APIs analogous to BB Phis to remove an incoming value/block.
The MemorySSAUpdater uses the above APIs when updating MemorySSA given a set of dead blocks about to be deleted.
Reviewers: george.burgess.iv
Subscribers: sanjoy, jlebar, Prazek, llvm-commits
Differential Revision: https://reviews.llvm.org/D48396
Modified:
llvm/trunk/include/llvm/Analysis/MemorySSA.h
llvm/trunk/include/llvm/Analysis/MemorySSAUpdater.h
llvm/trunk/lib/Analysis/MemorySSA.cpp
llvm/trunk/lib/Analysis/MemorySSAUpdater.cpp
Modified: llvm/trunk/include/llvm/Analysis/MemorySSA.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemorySSA.h?rev=336015&r1=336014&r2=336015&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/MemorySSA.h (original)
+++ llvm/trunk/include/llvm/Analysis/MemorySSA.h Fri Jun 29 13:46:16 2018
@@ -563,6 +563,46 @@ public:
return getIncomingValue(Idx);
}
+ // After deleting incoming position I, the order of incoming may be changed.
+ void unorderedDeleteIncoming(unsigned I) {
+ unsigned E = getNumOperands();
+ assert(I < E && "Cannot remove out of bounds Phi entry.");
+ // MemoryPhi must have at least two incoming values, otherwise the MemoryPhi
+ // itself should be deleted.
+ assert(E >= 2 && "Cannot only remove incoming values in MemoryPhis with "
+ "at least 2 values.");
+ setIncomingValue(I, getIncomingValue(E - 1));
+ setIncomingBlock(I, block_begin()[E - 1]);
+ setOperand(E - 1, nullptr);
+ block_begin()[E - 1] = nullptr;
+ setNumHungOffUseOperands(getNumOperands() - 1);
+ }
+
+ // After deleting incoming block BB, the incoming blocks order may be changed.
+ void unorderedDeleteIncomingBlock(const BasicBlock *BB) {
+ for (unsigned I = 0, E = getNumOperands(); I != E; ++I)
+ if (block_begin()[I] == BB) {
+ unorderedDeleteIncoming(I);
+ E = getNumOperands();
+ --I;
+ }
+ assert(getNumOperands() >= 1 &&
+ "Cannot remove all incoming blocks in a MemoryPhi.");
+ }
+
+ // After deleting incoming memory access MA, the incoming accesses order may
+ // be changed.
+ void unorderedDeleteIncomingValue(const MemoryAccess *MA) {
+ for (unsigned I = 0, E = getNumOperands(); I != E; ++I)
+ if (getIncomingValue(I) == MA) {
+ unorderedDeleteIncoming(I);
+ E = getNumOperands();
+ --I;
+ }
+ assert(getNumOperands() >= 1 &&
+ "Cannot remove all incoming values in a MemoryPhi.");
+ }
+
static bool classof(const Value *V) {
return V->getValueID() == MemoryPhiVal;
}
Modified: llvm/trunk/include/llvm/Analysis/MemorySSAUpdater.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemorySSAUpdater.h?rev=336015&r1=336014&r2=336015&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/MemorySSAUpdater.h (original)
+++ llvm/trunk/include/llvm/Analysis/MemorySSAUpdater.h Fri Jun 29 13:46:16 2018
@@ -146,6 +146,15 @@ public:
removeMemoryAccess(MA);
}
+ /// Remove all MemoryAcceses in a set of BasicBlocks about to be deleted.
+ /// Assumption we make here: all uses of deleted defs and phi must either
+ /// occur in blocks about to be deleted (thus will be deleted as well), or
+ /// they occur in phis that will simply lose an incoming value.
+ /// Deleted blocks still have successor info, but their predecessor edges and
+ /// Phi nodes may already be updated. Instructions in DeadBlocks should be
+ /// deleted after this call.
+ void removeBlocks(const SmallPtrSetImpl<BasicBlock *> &DeadBlocks);
+
/// Get handle on MemorySSA.
MemorySSA* getMemorySSA() const { return MSSA; }
Modified: llvm/trunk/lib/Analysis/MemorySSA.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemorySSA.cpp?rev=336015&r1=336014&r2=336015&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/MemorySSA.cpp (original)
+++ llvm/trunk/lib/Analysis/MemorySSA.cpp Fri Jun 29 13:46:16 2018
@@ -1597,10 +1597,11 @@ void MemorySSA::removeFromLookups(Memory
/// ShouldDelete defaults to true, and will cause the memory access to also be
/// deleted, not just removed.
void MemorySSA::removeFromLists(MemoryAccess *MA, bool ShouldDelete) {
+ BasicBlock *BB = MA->getBlock();
// The access list owns the reference, so we erase it from the non-owning list
// first.
if (!isa<MemoryUse>(MA)) {
- auto DefsIt = PerBlockDefs.find(MA->getBlock());
+ auto DefsIt = PerBlockDefs.find(BB);
std::unique_ptr<DefsList> &Defs = DefsIt->second;
Defs->remove(*MA);
if (Defs->empty())
@@ -1609,15 +1610,17 @@ void MemorySSA::removeFromLists(MemoryAc
// The erase call here will delete it. If we don't want it deleted, we call
// remove instead.
- auto AccessIt = PerBlockAccesses.find(MA->getBlock());
+ auto AccessIt = PerBlockAccesses.find(BB);
std::unique_ptr<AccessList> &Accesses = AccessIt->second;
if (ShouldDelete)
Accesses->erase(MA);
else
Accesses->remove(MA);
- if (Accesses->empty())
+ if (Accesses->empty()) {
PerBlockAccesses.erase(AccessIt);
+ BlockNumberingValid.erase(BB);
+ }
}
void MemorySSA::print(raw_ostream &OS) const {
Modified: llvm/trunk/lib/Analysis/MemorySSAUpdater.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemorySSAUpdater.cpp?rev=336015&r1=336014&r2=336015&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/MemorySSAUpdater.cpp (original)
+++ llvm/trunk/lib/Analysis/MemorySSAUpdater.cpp Fri Jun 29 13:46:16 2018
@@ -492,6 +492,39 @@ void MemorySSAUpdater::removeMemoryAcces
MSSA->removeFromLists(MA);
}
+void MemorySSAUpdater::removeBlocks(
+ const SmallPtrSetImpl<BasicBlock *> &DeadBlocks) {
+ // First delete all uses of BB in MemoryPhis.
+ for (BasicBlock *BB : DeadBlocks) {
+ TerminatorInst *TI = BB->getTerminator();
+ assert(TI && "Basic block expected to have a terminator instruction");
+ for (BasicBlock *Succ : TI->successors())
+ if (!DeadBlocks.count(Succ))
+ if (MemoryPhi *MP = MSSA->getMemoryAccess(Succ)) {
+ MP->unorderedDeleteIncomingBlock(BB);
+ if (MP->getNumIncomingValues() == 1)
+ removeMemoryAccess(MP);
+ }
+ // Drop all references of all accesses in BB
+ if (MemorySSA::AccessList *Acc = MSSA->getWritableBlockAccesses(BB))
+ for (MemoryAccess &MA : *Acc)
+ MA.dropAllReferences();
+ }
+
+ // Next, delete all memory accesses in each block
+ for (BasicBlock *BB : DeadBlocks) {
+ MemorySSA::AccessList *Acc = MSSA->getWritableBlockAccesses(BB);
+ if (!Acc)
+ continue;
+ for (auto AB = Acc->begin(), AE = Acc->end(); AB != AE;) {
+ MemoryAccess *MA = &*AB;
+ ++AB;
+ MSSA->removeFromLookups(MA);
+ MSSA->removeFromLists(MA);
+ }
+ }
+}
+
MemoryAccess *MemorySSAUpdater::createMemoryAccessInBB(
Instruction *I, MemoryAccess *Definition, const BasicBlock *BB,
MemorySSA::InsertionPlace Point) {
More information about the llvm-commits
mailing list