diff options
author | Nick Lewycky <nicholas@mxc.ca> | 2011-10-22 21:59:35 +0000 |
---|---|---|
committer | Nick Lewycky <nicholas@mxc.ca> | 2011-10-22 21:59:35 +0000 |
commit | 32f8051d662808e3216913b33a664cebc99da7b0 (patch) | |
tree | 45da7825537817bab1ce5993caca18c1b497ea72 | |
parent | 02d5fe29ab46b52cda231b5d63e38dd153700357 (diff) | |
download | bcm5719-llvm-32f8051d662808e3216913b33a664cebc99da7b0.tar.gz bcm5719-llvm-32f8051d662808e3216913b33a664cebc99da7b0.zip |
A non-escaping malloc in the entry block is not unlike an alloca. Do dead-store
elimination on them too.
llvm-svn: 142735
-rw-r--r-- | llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp | 27 | ||||
-rw-r--r-- | llvm/test/Transforms/DeadStoreElimination/simple.ll | 8 |
2 files changed, 33 insertions, 2 deletions
diff --git a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp index a593d0f4463..c0738a951c4 100644 --- a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp +++ b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp @@ -24,6 +24,7 @@ #include "llvm/IntrinsicInst.h" #include "llvm/Pass.h" #include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/CaptureTracking.h" #include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/Analysis/MemoryDependenceAnalysis.h" @@ -255,6 +256,14 @@ static Value *getStoredPointerOperand(Instruction *I) { static uint64_t getPointerSize(Value *V, AliasAnalysis &AA) { const TargetData *TD = AA.getTargetData(); + + if (CallInst *CI = dyn_cast<CallInst>(V)) { + assert(isMalloc(CI) && "Expected Malloc call!"); + if (ConstantInt *C = dyn_cast<ConstantInt>(CI->getArgOperand(0))) + return C->getZExtValue(); + return AliasAnalysis::UnknownSize; + } + if (TD == 0) return AliasAnalysis::UnknownSize; @@ -265,7 +274,7 @@ static uint64_t getPointerSize(Value *V, AliasAnalysis &AA) { return AliasAnalysis::UnknownSize; } - assert(isa<Argument>(V) && "Expected AllocaInst or Argument!"); + assert(isa<Argument>(V) && "Expected AllocaInst, malloc call or Argument!"); PointerType *PT = cast<PointerType>(V->getType()); return TD->getTypeAllocSize(PT->getElementType()); } @@ -279,6 +288,8 @@ static bool isObjectPointerWithTrustworthySize(const Value *V) { return !GV->mayBeOverridden(); if (const Argument *A = dyn_cast<Argument>(V)) return A->hasByValAttr(); + if (isMalloc(V)) + return true; return false; } @@ -588,10 +599,17 @@ bool DSE::handleEndBlock(BasicBlock &BB) { // Find all of the alloca'd pointers in the entry block. BasicBlock *Entry = BB.getParent()->begin(); - for (BasicBlock::iterator I = Entry->begin(), E = Entry->end(); I != E; ++I) + for (BasicBlock::iterator I = Entry->begin(), E = Entry->end(); I != E; ++I) { if (AllocaInst *AI = dyn_cast<AllocaInst>(I)) DeadStackObjects.insert(AI); + // Okay, so these are dead heap objects, but if the pointer never escapes + // then it's leaked by this function anyways. + if (CallInst *CI = extractMallocCall(I)) + if (!PointerMayBeCaptured(CI, true, true)) + DeadStackObjects.insert(CI); + } + // Treat byval arguments the same, stores to them are dead at the end of the // function. for (Function::arg_iterator AI = BB.getParent()->arg_begin(), @@ -637,6 +655,11 @@ bool DSE::handleEndBlock(BasicBlock &BB) { continue; } + if (CallInst *CI = extractMallocCall(BBI)) { + DeadStackObjects.erase(CI); + continue; + } + if (CallSite CS = cast<Value>(BBI)) { // If this call does not access memory, it can't be loading any of our // pointers. diff --git a/llvm/test/Transforms/DeadStoreElimination/simple.ll b/llvm/test/Transforms/DeadStoreElimination/simple.ll index ec2f15737a3..1703ee961f5 100644 --- a/llvm/test/Transforms/DeadStoreElimination/simple.ll +++ b/llvm/test/Transforms/DeadStoreElimination/simple.ll @@ -251,3 +251,11 @@ bb: ; CHECK: call void @test19f } +define void @test20() { + %m = call i8* @malloc(i32 24) + store i8 0, i8* %m + ret void +} +; CHECK: @test20 +; CHECK-NOT: store +; CHECK: ret void |