From: Nick Lewycky Date: Sat, 22 Oct 2011 21:59:35 +0000 (+0000) Subject: A non-escaping malloc in the entry block is not unlike an alloca. Do dead-store X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=4d882aae2acc5194b47385c7cb2e0e9ddd202927;p=oota-llvm.git 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 --- diff --git a/lib/Transforms/Scalar/DeadStoreElimination.cpp b/lib/Transforms/Scalar/DeadStoreElimination.cpp index a593d0f4463..c0738a951c4 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(V)) { + assert(isMalloc(CI) && "Expected Malloc call!"); + if (ConstantInt *C = dyn_cast(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(V) && "Expected AllocaInst or Argument!"); + assert(isa(V) && "Expected AllocaInst, malloc call or Argument!"); PointerType *PT = cast(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(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(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(BBI)) { // If this call does not access memory, it can't be loading any of our // pointers. diff --git a/test/Transforms/DeadStoreElimination/simple.ll b/test/Transforms/DeadStoreElimination/simple.ll index ec2f15737a3..1703ee961f5 100644 --- a/test/Transforms/DeadStoreElimination/simple.ll +++ b/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