Make DeleteDeadInstruction be a static function, move some code around.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@120471 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner
2010-11-30 21:58:14 +00:00
parent c563ded794
commit 7c80c15a8b

View File

@@ -66,8 +66,6 @@ namespace {
bool handleEndBlock(BasicBlock &BB); bool handleEndBlock(BasicBlock &BB);
void RemoveAccessedObjects(const AliasAnalysis::Location &LoadedLoc, void RemoveAccessedObjects(const AliasAnalysis::Location &LoadedLoc,
SmallPtrSet<Value*, 16> &DeadStackObjects); SmallPtrSet<Value*, 16> &DeadStackObjects);
void DeleteDeadInstruction(Instruction *I,
SmallPtrSet<Value*, 16> *deadPointers = 0);
// getAnalysisUsage - We require post dominance frontiers (aka Control // getAnalysisUsage - We require post dominance frontiers (aka Control
@@ -93,6 +91,53 @@ INITIALIZE_PASS_END(DSE, "dse", "Dead Store Elimination", false, false)
FunctionPass *llvm::createDeadStoreEliminationPass() { return new DSE(); } FunctionPass *llvm::createDeadStoreEliminationPass() { return new DSE(); }
//===----------------------------------------------------------------------===//
// Helper functions
//===----------------------------------------------------------------------===//
/// DeleteDeadInstruction - Delete this instruction. Before we do, go through
/// and zero out all the operands of this instruction. If any of them become
/// dead, delete them and the computation tree that feeds them.
///
/// If ValueSet is non-null, remove any deleted instructions from it as well.
///
static void DeleteDeadInstruction(Instruction *I,
MemoryDependenceAnalysis &MD,
SmallPtrSet<Value*, 16> *ValueSet = 0) {
SmallVector<Instruction*, 32> NowDeadInsts;
NowDeadInsts.push_back(I);
--NumFastOther;
// Before we touch this instruction, remove it from memdep!
do {
Instruction *DeadInst = NowDeadInsts.pop_back_val();
++NumFastOther;
// This instruction is dead, zap it, in stages. Start by removing it from
// MemDep, which needs to know the operands and needs it to be in the
// function.
MD.removeInstruction(DeadInst);
for (unsigned op = 0, e = DeadInst->getNumOperands(); op != e; ++op) {
Value *Op = DeadInst->getOperand(op);
DeadInst->setOperand(op, 0);
// If this operand just became dead, add it to the NowDeadInsts list.
if (!Op->use_empty()) continue;
if (Instruction *OpI = dyn_cast<Instruction>(Op))
if (isInstructionTriviallyDead(OpI))
NowDeadInsts.push_back(OpI);
}
DeadInst->eraseFromParent();
if (ValueSet) ValueSet->erase(DeadInst);
} while (!NowDeadInsts.empty());
}
/// hasMemoryWrite - Does this instruction write some memory? This only returns /// hasMemoryWrite - Does this instruction write some memory? This only returns
/// true for things that we can analyze with other helpers below. /// true for things that we can analyze with other helpers below.
static bool hasMemoryWrite(Instruction *I) { static bool hasMemoryWrite(Instruction *I) {
@@ -177,21 +222,18 @@ static bool isRemovable(Instruction *I) {
} }
} }
/// getPointerOperand - Return the pointer that is being written to. /// getStoredPointerOperand - Return the pointer that is being written to.
static Value *getPointerOperand(Instruction *I) { static Value *getStoredPointerOperand(Instruction *I) {
assert(hasMemoryWrite(I));
if (StoreInst *SI = dyn_cast<StoreInst>(I)) if (StoreInst *SI = dyn_cast<StoreInst>(I))
return SI->getPointerOperand(); return SI->getPointerOperand();
if (MemIntrinsic *MI = dyn_cast<MemIntrinsic>(I)) if (MemIntrinsic *MI = dyn_cast<MemIntrinsic>(I))
return MI->getArgOperand(0); return MI->getDest();
IntrinsicInst *II = cast<IntrinsicInst>(I); IntrinsicInst *II = cast<IntrinsicInst>(I);
switch (II->getIntrinsicID()) { switch (II->getIntrinsicID()) {
default: assert(false && "Unexpected intrinsic!"); default: assert(false && "Unexpected intrinsic!");
case Intrinsic::init_trampoline: case Intrinsic::init_trampoline:
return II->getArgOperand(0); return II->getArgOperand(0);
case Intrinsic::lifetime_end:
return II->getArgOperand(1);
} }
} }
@@ -243,6 +285,11 @@ static bool isCompleteOverwrite(const AliasAnalysis::Location &Later,
return true; return true;
} }
//===----------------------------------------------------------------------===//
// DSE Pass
//===----------------------------------------------------------------------===//
bool DSE::runOnBasicBlock(BasicBlock &BB) { bool DSE::runOnBasicBlock(BasicBlock &BB) {
bool MadeChange = false; bool MadeChange = false;
@@ -280,7 +327,7 @@ bool DSE::runOnBasicBlock(BasicBlock &BB) {
// in case we need it. // in case we need it.
WeakVH NextInst(BBI); WeakVH NextInst(BBI);
DeleteDeadInstruction(SI); DeleteDeadInstruction(SI, *MD);
if (NextInst == 0) // Next instruction deleted. if (NextInst == 0) // Next instruction deleted.
BBI = BB.begin(); BBI = BB.begin();
@@ -318,7 +365,7 @@ bool DSE::runOnBasicBlock(BasicBlock &BB) {
// store to 'Loc' then we can remove it. // store to 'Loc' then we can remove it.
if (isRemovable(DepWrite) && isCompleteOverwrite(Loc, DepLoc, *AA)) { if (isRemovable(DepWrite) && isCompleteOverwrite(Loc, DepLoc, *AA)) {
// Delete the store and now-dead instructions that feed it. // Delete the store and now-dead instructions that feed it.
DeleteDeadInstruction(DepWrite); DeleteDeadInstruction(DepWrite, *MD);
++NumFastStores; ++NumFastStores;
MadeChange = true; MadeChange = true;
@@ -367,7 +414,8 @@ bool DSE::HandleFree(CallInst *F) {
if (!hasMemoryWrite(Dependency) || !isRemovable(Dependency)) if (!hasMemoryWrite(Dependency) || !isRemovable(Dependency))
return false; return false;
Value *DepPointer = getPointerOperand(Dependency)->getUnderlyingObject(); Value *DepPointer =
getStoredPointerOperand(Dependency)->getUnderlyingObject();
// Check for aliasing. // Check for aliasing.
if (AA->alias(F->getArgOperand(0), 1, DepPointer, 1) != if (AA->alias(F->getArgOperand(0), 1, DepPointer, 1) !=
@@ -375,7 +423,7 @@ bool DSE::HandleFree(CallInst *F) {
return false; return false;
// DCE instructions only used to calculate that store // DCE instructions only used to calculate that store
DeleteDeadInstruction(Dependency); DeleteDeadInstruction(Dependency, *MD);
++NumFastStores; ++NumFastStores;
// Inst's old Dependency is now deleted. Compute the next dependency, // Inst's old Dependency is now deleted. Compute the next dependency,
@@ -422,14 +470,13 @@ 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 = getPointerOperand(BBI)->getUnderlyingObject(); Value *Pointer = getStoredPointerOperand(BBI)->getUnderlyingObject();
// Alloca'd pointers or byval arguments (which are functionally like // Stores to stack values are valid candidates for removal.
// alloca's) are valid candidates for removal.
if (DeadStackObjects.count(Pointer)) { if (DeadStackObjects.count(Pointer)) {
// DCE instructions only used to calculate that store. // DCE instructions only used to calculate that store.
Instruction *Dead = BBI++; Instruction *Dead = BBI++;
DeleteDeadInstruction(Dead, &DeadStackObjects); DeleteDeadInstruction(Dead, *MD, &DeadStackObjects);
++NumFastStores; ++NumFastStores;
MadeChange = true; MadeChange = true;
continue; continue;
@@ -439,7 +486,7 @@ bool DSE::handleEndBlock(BasicBlock &BB) {
// Remove any dead non-memory-mutating instructions. // Remove any dead non-memory-mutating instructions.
if (isInstructionTriviallyDead(BBI)) { if (isInstructionTriviallyDead(BBI)) {
Instruction *Inst = BBI++; Instruction *Inst = BBI++;
DeleteDeadInstruction(Inst, &DeadStackObjects); DeleteDeadInstruction(Inst, *MD, &DeadStackObjects);
++NumFastOther; ++NumFastOther;
MadeChange = true; MadeChange = true;
continue; continue;
@@ -553,45 +600,3 @@ void DSE::RemoveAccessedObjects(const AliasAnalysis::Location &LoadedLoc,
DeadStackObjects.erase(*I); DeadStackObjects.erase(*I);
} }
/// DeleteDeadInstruction - Delete this instruction. Before we do, go through
/// and zero out all the operands of this instruction. If any of them become
/// dead, delete them and the computation tree that feeds them.
///
/// If ValueSet is non-null, remove any deleted instructions from it as well.
///
void DSE::DeleteDeadInstruction(Instruction *I,
SmallPtrSet<Value*, 16> *ValueSet) {
SmallVector<Instruction*, 32> NowDeadInsts;
NowDeadInsts.push_back(I);
--NumFastOther;
// Before we touch this instruction, remove it from memdep!
do {
Instruction *DeadInst = NowDeadInsts.pop_back_val();
++NumFastOther;
// This instruction is dead, zap it, in stages. Start by removing it from
// MemDep, which needs to know the operands and needs it to be in the
// function.
MD->removeInstruction(DeadInst);
for (unsigned op = 0, e = DeadInst->getNumOperands(); op != e; ++op) {
Value *Op = DeadInst->getOperand(op);
DeadInst->setOperand(op, 0);
// If this operand just became dead, add it to the NowDeadInsts list.
if (!Op->use_empty()) continue;
if (Instruction *OpI = dyn_cast<Instruction>(Op))
if (isInstructionTriviallyDead(OpI))
NowDeadInsts.push_back(OpI);
}
DeadInst->eraseFromParent();
if (ValueSet) ValueSet->erase(DeadInst);
} while (!NowDeadInsts.empty());
}