summaryrefslogtreecommitdiffstats
path: root/lib/Transforms/Scalar/DeadStoreElimination.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Transforms/Scalar/DeadStoreElimination.cpp')
-rw-r--r--lib/Transforms/Scalar/DeadStoreElimination.cpp67
1 files changed, 40 insertions, 27 deletions
diff --git a/lib/Transforms/Scalar/DeadStoreElimination.cpp b/lib/Transforms/Scalar/DeadStoreElimination.cpp
index b923c92..a7b3e75 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
OpenPOWER on IntegriCloud