mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-04 07:32:13 +00:00
Teach DeadStoreElimination to eliminate exit-block stores with phi addresses.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@156558 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
fe65d98dad
commit
b401e3bd16
@ -151,6 +151,14 @@ namespace llvm {
|
|||||||
return GetUnderlyingObject(const_cast<Value *>(V), TD, MaxLookup);
|
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
|
/// onlyUsedByLifetimeMarkers - Return true if the only users of this pointer
|
||||||
/// are lifetime markers.
|
/// are lifetime markers.
|
||||||
bool onlyUsedByLifetimeMarkers(const Value *V);
|
bool onlyUsedByLifetimeMarkers(const Value *V);
|
||||||
|
@ -1796,6 +1796,37 @@ llvm::GetUnderlyingObject(Value *V, const TargetData *TD, unsigned MaxLookup) {
|
|||||||
return V;
|
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
|
/// onlyUsedByLifetimeMarkers - Return true if the only users of this pointer
|
||||||
/// are lifetime markers.
|
/// 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 we find a store, check to see if it points into a dead stack value.
|
||||||
if (hasMemoryWrite(BBI) && isRemovable(BBI)) {
|
if (hasMemoryWrite(BBI) && isRemovable(BBI)) {
|
||||||
// See through pointer-to-pointer bitcasts
|
// 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.
|
// 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++;
|
Instruction *Dead = BBI++;
|
||||||
|
|
||||||
DEBUG(dbgs() << "DSE: Dead Store at End of Block:\n DEAD: "
|
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.
|
// DCE instructions only used to calculate that store.
|
||||||
DeleteDeadInstruction(Dead, *MD, &DeadStackObjects);
|
DeleteDeadInstruction(Dead, *MD, &DeadStackObjects);
|
||||||
|
@ -266,3 +266,13 @@ define void @test21() {
|
|||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
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…
x
Reference in New Issue
Block a user