Teach DeadStoreElimination to eliminate exit-block stores with phi addresses.

llvm-svn: 156558
This commit is contained in:
Dan Gohman 2012-05-10 18:57:38 +00:00
parent 671ce47d60
commit ed7c24e2d9
4 changed files with 68 additions and 3 deletions

View File

@ -151,6 +151,14 @@ namespace llvm {
return GetUnderlyingObject(const_cast<Value *>(V), TD, MaxLookup);
}
/// GetUnderlyingObjects - This method is similar to GetUnderlyingObject
/// except that it can look through phi and select instructions and return
/// multiple objects.
void GetUnderlyingObjects(Value *V,
SmallVectorImpl<Value *> &Objects,
const TargetData *TD = 0,
unsigned MaxLookup = 6);
/// onlyUsedByLifetimeMarkers - Return true if the only users of this pointer
/// are lifetime markers.
bool onlyUsedByLifetimeMarkers(const Value *V);

View File

@ -1796,6 +1796,37 @@ llvm::GetUnderlyingObject(Value *V, const TargetData *TD, unsigned MaxLookup) {
return V;
}
void
llvm::GetUnderlyingObjects(Value *V,
SmallVectorImpl<Value *> &Objects,
const TargetData *TD,
unsigned MaxLookup) {
SmallPtrSet<Value *, 4> Visited;
SmallVector<Value *, 4> Worklist;
Worklist.push_back(V);
do {
Value *P = Worklist.pop_back_val();
P = GetUnderlyingObject(P, TD, MaxLookup);
if (!Visited.insert(P))
continue;
if (SelectInst *SI = dyn_cast<SelectInst>(P)) {
Worklist.push_back(SI->getTrueValue());
Worklist.push_back(SI->getFalseValue());
continue;
}
if (PHINode *PN = dyn_cast<PHINode>(P)) {
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
Worklist.push_back(PN->getIncomingValue(i));
continue;
}
Objects.push_back(P);
} while (!Worklist.empty());
}
/// onlyUsedByLifetimeMarkers - Return true if the only users of this pointer
/// are lifetime markers.
///

View File

@ -731,14 +731,30 @@ bool DSE::handleEndBlock(BasicBlock &BB) {
// If we find a store, check to see if it points into a dead stack value.
if (hasMemoryWrite(BBI) && isRemovable(BBI)) {
// See through pointer-to-pointer bitcasts
Value *Pointer = GetUnderlyingObject(getStoredPointerOperand(BBI));
SmallVector<Value *, 4> Pointers;
GetUnderlyingObjects(getStoredPointerOperand(BBI), Pointers);
// Stores to stack values are valid candidates for removal.
if (DeadStackObjects.count(Pointer)) {
bool AllDead = true;
for (SmallVectorImpl<Value *>::iterator I = Pointers.begin(),
E = Pointers.end(); I != E; ++I)
if (!DeadStackObjects.count(*I)) {
AllDead = false;
break;
}
if (AllDead) {
Instruction *Dead = BBI++;
DEBUG(dbgs() << "DSE: Dead Store at End of Block:\n DEAD: "
<< *Dead << "\n Object: " << *Pointer << '\n');
<< *Dead << "\n Objects: ";
for (SmallVectorImpl<Value *>::iterator I = Pointers.begin(),
E = Pointers.end(); I != E; ++I) {
dbgs() << **I;
if (llvm::next(I) != E)
dbgs() << ", ";
}
dbgs() << '\n');
// DCE instructions only used to calculate that store.
DeleteDeadInstruction(Dead, *MD, &DeadStackObjects);

View File

@ -266,3 +266,13 @@ define void @test21() {
; CHECK-NEXT: ret void
ret void
}
; CHECK: @test22(
define void @test22(i1 %i, i32 %k, i32 %m) nounwind {
%k.addr = alloca i32
%m.addr = alloca i32
%k.addr.m.addr = select i1 %i, i32* %k.addr, i32* %m.addr
store i32 0, i32* %k.addr.m.addr, align 4
; CHECK-NEXT: ret void
ret void
}