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 | 4d882aae2acc5194b47385c7cb2e0e9ddd202927 (patch) | |
tree | dc52864c852e18d6c72f37300acdb293ef0a00ff /lib/Transforms/Scalar/DeadStoreElimination.cpp | |
parent | 614fef6d5a1e24d01ffe7247b1841fd7e08e1e85 (diff) | |
download | external_llvm-4d882aae2acc5194b47385c7cb2e0e9ddd202927.zip external_llvm-4d882aae2acc5194b47385c7cb2e0e9ddd202927.tar.gz external_llvm-4d882aae2acc5194b47385c7cb2e0e9ddd202927.tar.bz2 |
A non-escaping malloc in the entry block is not unlike an alloca. Do dead-store
elimination on them too.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@142735 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Scalar/DeadStoreElimination.cpp')
-rw-r--r-- | lib/Transforms/Scalar/DeadStoreElimination.cpp | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/lib/Transforms/Scalar/DeadStoreElimination.cpp b/lib/Transforms/Scalar/DeadStoreElimination.cpp index a593d0f..c0738a9 100644 --- a/lib/Transforms/Scalar/DeadStoreElimination.cpp +++ b/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. |