mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 10:42:39 +01:00
[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 llvm-svn: 336015
This commit is contained in:
parent
eb18816b59
commit
c96b36e0c5
@ -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;
|
||||
}
|
||||
|
@ -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; }
|
||||
|
||||
|
@ -1597,10 +1597,11 @@ void MemorySSA::removeFromLookups(MemoryAccess *MA) {
|
||||
/// 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(MemoryAccess *MA, bool ShouldDelete) {
|
||||
|
||||
// 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 {
|
||||
|
@ -492,6 +492,39 @@ void MemorySSAUpdater::removeMemoryAccess(MemoryAccess *MA) {
|
||||
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) {
|
||||
|
Loading…
Reference in New Issue
Block a user