diff options
Diffstat (limited to 'lib/Transforms/Scalar/DeadStoreElimination.cpp')
-rw-r--r-- | lib/Transforms/Scalar/DeadStoreElimination.cpp | 67 |
1 files changed, 40 insertions, 27 deletions
diff --git a/lib/Transforms/Scalar/DeadStoreElimination.cpp b/lib/Transforms/Scalar/DeadStoreElimination.cpp index b923c92bd3007..a7b3e7524fa2b 100644 --- a/lib/Transforms/Scalar/DeadStoreElimination.cpp +++ b/lib/Transforms/Scalar/DeadStoreElimination.cpp @@ -29,14 +29,15 @@ #include "llvm/Analysis/MemoryDependenceAnalysis.h" #include "llvm/Target/TargetData.h" #include "llvm/Transforms/Utils/Local.h" -#include "llvm/Support/Compiler.h" using namespace llvm; STATISTIC(NumFastStores, "Number of stores deleted"); STATISTIC(NumFastOther , "Number of other instrs removed"); namespace { - struct VISIBILITY_HIDDEN DSE : public FunctionPass { + struct DSE : public FunctionPass { + TargetData *TD; + static char ID; // Pass identification, replacement for typeid DSE() : FunctionPass(&ID) {} @@ -62,7 +63,6 @@ namespace { virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); AU.addRequired<DominatorTree>(); - AU.addRequired<TargetData>(); AU.addRequired<AliasAnalysis>(); AU.addRequired<MemoryDependenceAnalysis>(); AU.addPreserved<DominatorTree>(); @@ -79,15 +79,15 @@ FunctionPass *llvm::createDeadStoreEliminationPass() { return new DSE(); } bool DSE::runOnBasicBlock(BasicBlock &BB) { MemoryDependenceAnalysis& MD = getAnalysis<MemoryDependenceAnalysis>(); - TargetData &TD = getAnalysis<TargetData>(); + TD = getAnalysisIfAvailable<TargetData>(); bool MadeChange = false; - // Do a top-down walk on the BB + // Do a top-down walk on the BB. for (BasicBlock::iterator BBI = BB.begin(), BBE = BB.end(); BBI != BBE; ) { Instruction *Inst = BBI++; - // If we find a store or a free, get it's memory dependence. + // If we find a store or a free, get its memory dependence. if (!isa<StoreInst>(Inst) && !isa<FreeInst>(Inst)) continue; @@ -117,13 +117,17 @@ bool DSE::runOnBasicBlock(BasicBlock &BB) { // If this is a store-store dependence, then the previous store is dead so // long as this store is at least as big as it. if (StoreInst *DepStore = dyn_cast<StoreInst>(InstDep.getInst())) - if (TD.getTypeStoreSize(DepStore->getOperand(0)->getType()) <= - TD.getTypeStoreSize(SI->getOperand(0)->getType())) { + if (TD && + TD->getTypeStoreSize(DepStore->getOperand(0)->getType()) <= + TD->getTypeStoreSize(SI->getOperand(0)->getType())) { // Delete the store and now-dead instructions that feed it. DeleteDeadInstruction(DepStore); NumFastStores++; MadeChange = true; - + + // DeleteDeadInstruction can delete the current instruction in loop + // cases, reset BBI. + BBI = Inst; if (BBI != BB.begin()) --BBI; continue; @@ -134,8 +138,15 @@ bool DSE::runOnBasicBlock(BasicBlock &BB) { if (LoadInst *DepLoad = dyn_cast<LoadInst>(InstDep.getInst())) { if (SI->getPointerOperand() == DepLoad->getPointerOperand() && SI->getOperand(0) == DepLoad) { + // DeleteDeadInstruction can delete the current instruction. Save BBI + // in case we need it. + WeakVH NextInst(BBI); + DeleteDeadInstruction(SI); - if (BBI != BB.begin()) + + if (NextInst == 0) // Next instruction deleted. + BBI = BB.begin(); + else if (BBI != BB.begin()) // Revisit this instruction if possible. --BBI; NumFastStores++; MadeChange = true; @@ -181,7 +192,6 @@ bool DSE::handleFreeWithNonTrivialDependency(FreeInst *F, MemDepResult Dep) { /// store i32 1, i32* %A /// ret void bool DSE::handleEndBlock(BasicBlock &BB) { - TargetData &TD = getAnalysis<TargetData>(); AliasAnalysis &AA = getAnalysis<AliasAnalysis>(); bool MadeChange = false; @@ -302,14 +312,16 @@ bool DSE::handleEndBlock(BasicBlock &BB) { // Get size information for the alloca unsigned pointerSize = ~0U; - if (AllocaInst* A = dyn_cast<AllocaInst>(*I)) { - if (ConstantInt* C = dyn_cast<ConstantInt>(A->getArraySize())) - pointerSize = C->getZExtValue() * - TD.getTypeAllocSize(A->getAllocatedType()); - } else { - const PointerType* PT = cast<PointerType>( - cast<Argument>(*I)->getType()); - pointerSize = TD.getTypeAllocSize(PT->getElementType()); + if (TD) { + if (AllocaInst* A = dyn_cast<AllocaInst>(*I)) { + if (ConstantInt* C = dyn_cast<ConstantInt>(A->getArraySize())) + pointerSize = C->getZExtValue() * + TD->getTypeAllocSize(A->getAllocatedType()); + } else { + const PointerType* PT = cast<PointerType>( + cast<Argument>(*I)->getType()); + pointerSize = TD->getTypeAllocSize(PT->getElementType()); + } } // See if the call site touches it @@ -357,7 +369,6 @@ bool DSE::handleEndBlock(BasicBlock &BB) { bool DSE::RemoveUndeadPointers(Value* killPointer, uint64_t killPointerSize, BasicBlock::iterator &BBI, SmallPtrSet<Value*, 64>& deadPointers) { - TargetData &TD = getAnalysis<TargetData>(); AliasAnalysis &AA = getAnalysis<AliasAnalysis>(); // If the kill pointer can be easily reduced to an alloca, @@ -379,13 +390,15 @@ bool DSE::RemoveUndeadPointers(Value* killPointer, uint64_t killPointerSize, E = deadPointers.end(); I != E; ++I) { // Get size information for the alloca. unsigned pointerSize = ~0U; - if (AllocaInst* A = dyn_cast<AllocaInst>(*I)) { - if (ConstantInt* C = dyn_cast<ConstantInt>(A->getArraySize())) - pointerSize = C->getZExtValue() * - TD.getTypeAllocSize(A->getAllocatedType()); - } else { - const PointerType* PT = cast<PointerType>(cast<Argument>(*I)->getType()); - pointerSize = TD.getTypeAllocSize(PT->getElementType()); + if (TD) { + if (AllocaInst* A = dyn_cast<AllocaInst>(*I)) { + if (ConstantInt* C = dyn_cast<ConstantInt>(A->getArraySize())) + pointerSize = C->getZExtValue() * + TD->getTypeAllocSize(A->getAllocatedType()); + } else { + const PointerType* PT = cast<PointerType>(cast<Argument>(*I)->getType()); + pointerSize = TD->getTypeAllocSize(PT->getElementType()); + } } // See if this pointer could alias it |