forked from OSchip/llvm-project
Teach DeadStoreElimination to eliminate exit-block stores with phi addresses.
llvm-svn: 156558
This commit is contained in:
parent
671ce47d60
commit
ed7c24e2d9
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
///
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue