From: Owen Anderson Date: Tue, 29 Jan 2008 06:18:36 +0000 (+0000) Subject: Add support for eliminating memcpy's at the end of functions. Also fix some errors... X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=a34d8a0d83bb39f4058e5dea4558e69cc4eda37c;p=oota-llvm.git Add support for eliminating memcpy's at the end of functions. Also fix some errors I noticed in the handling of eliminating stores to byval arguments. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@46494 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/Scalar/DeadStoreElimination.cpp b/lib/Transforms/Scalar/DeadStoreElimination.cpp index f4b432f88e5..fc359404594 100644 --- a/lib/Transforms/Scalar/DeadStoreElimination.cpp +++ b/lib/Transforms/Scalar/DeadStoreElimination.cpp @@ -20,6 +20,7 @@ #include "llvm/Constants.h" #include "llvm/Function.h" #include "llvm/Instructions.h" +#include "llvm/IntrinsicInst.h" #include "llvm/Pass.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallPtrSet.h" @@ -53,7 +54,7 @@ namespace { bool handleEndBlock(BasicBlock& BB, SetVector& possiblyDead); bool RemoveUndeadPointers(Value* pointer, BasicBlock::iterator& BBI, - SmallPtrSet& deadPointers, + SmallPtrSet& deadPointers, SetVector& possiblyDead); void DeleteDeadInstructionChains(Instruction *I, SetVector &DeadInsts); @@ -249,13 +250,17 @@ bool DSE::handleEndBlock(BasicBlock& BB, bool MadeChange = false; // Pointers alloca'd in this function are dead in the end block - SmallPtrSet deadPointers; + SmallPtrSet deadPointers; // 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) if (AllocaInst *AI = dyn_cast(I)) deadPointers.insert(AI); + for (Function::arg_iterator AI = BB.getParent()->arg_begin(), + AE = BB.getParent()->arg_end(); AI != AE; ++AI) + if (AI->hasByValAttr()) + deadPointers.insert(AI); // Scan the basic block backwards for (BasicBlock::iterator BBI = BB.end(); BBI != BB.begin(); ){ @@ -270,10 +275,7 @@ bool DSE::handleEndBlock(BasicBlock& BB, // Alloca'd pointers or byval arguments (which are functionally like // alloca's) are valid candidates for removal. - if ( (isa(pointerOperand) && - deadPointers.count(cast(pointerOperand))) || - (isa(pointerOperand) && - cast(pointerOperand)->hasByValAttr())) { + if (deadPointers.count(pointerOperand)) { // Remove it! MD.removeInstruction(S); @@ -291,6 +293,32 @@ bool DSE::handleEndBlock(BasicBlock& BB, } continue; + + // We can also remove memcpy's to local variables at the end of a function + } else if (MemCpyInst* M = dyn_cast(BBI)) { + Value* dest = M->getDest(); + TranslatePointerBitCasts(dest); + + if (deadPointers.count(dest)) { + MD.removeInstruction(M); + + // DCE instructions only used to calculate that memcpy + if (Instruction* D = dyn_cast(M->getSource())) + possiblyDead.insert(D); + if (Instruction* D = dyn_cast(M->getLength())) + possiblyDead.insert(D); + if (Instruction* D = dyn_cast(M->getRawDest())) + possiblyDead.insert(D); + + BBI++; + M->eraseFromParent(); + NumFastOther++; + MadeChange = true; + + continue; + } + + // Because a memcpy is also a load, we can't skip it if we didn't remove it } Value* killPointer = 0; @@ -314,8 +342,8 @@ bool DSE::handleEndBlock(BasicBlock& BB, unsigned other = 0; // Remove any pointers made undead by the call from the dead set - std::vector dead; - for (SmallPtrSet::iterator I = deadPointers.begin(), + std::vector dead; + for (SmallPtrSet::iterator I = deadPointers.begin(), E = deadPointers.end(); I != E; ++I) { // HACK: if we detect that our AA is imprecise, it's not // worth it to scan the rest of the deadPointers set. Just @@ -328,9 +356,15 @@ bool DSE::handleEndBlock(BasicBlock& BB, // Get size information for the alloca unsigned pointerSize = ~0U; - if (ConstantInt* C = dyn_cast((*I)->getArraySize())) - pointerSize = C->getZExtValue() * \ - TD.getABITypeSize((*I)->getAllocatedType()); + if (AllocaInst* A = dyn_cast(*I)) { + if (ConstantInt* C = dyn_cast(A->getArraySize())) + pointerSize = C->getZExtValue() * \ + TD.getABITypeSize(A->getAllocatedType()); + } else { + const PointerType* PT = cast( + cast(*I)->getType()); + pointerSize = TD.getABITypeSize(PT->getElementType()); + } // See if the call site touches it AliasAnalysis::ModRefResult A = AA.getModRefInfo(CS, *I, pointerSize); @@ -344,10 +378,9 @@ bool DSE::handleEndBlock(BasicBlock& BB, dead.push_back(*I); } - for (std::vector::iterator I = dead.begin(), E = dead.end(); + for (std::vector::iterator I = dead.begin(), E = dead.end(); I != E; ++I) - if (AllocaInst *AI = dyn_cast(*I)) - deadPointers.erase(AI); + deadPointers.erase(*I); continue; } @@ -369,7 +402,7 @@ bool DSE::handleEndBlock(BasicBlock& BB, /// undead when scanning for dead stores to alloca's. bool DSE::RemoveUndeadPointers(Value* killPointer, BasicBlock::iterator& BBI, - SmallPtrSet& deadPointers, + SmallPtrSet& deadPointers, SetVector& possiblyDead) { TargetData &TD = getAnalysis(); AliasAnalysis &AA = getAnalysis(); @@ -377,9 +410,8 @@ bool DSE::RemoveUndeadPointers(Value* killPointer, // If the kill pointer can be easily reduced to an alloca, // don't bother doing extraneous AA queries - if (AllocaInst* A = dyn_cast(killPointer)) { - if (deadPointers.count(A)) - deadPointers.erase(A); + if (deadPointers.count(killPointer)) { + deadPointers.erase(killPointer); return false; } else if (isa(killPointer)) { // A global can't be in the dead pointer set @@ -388,15 +420,21 @@ bool DSE::RemoveUndeadPointers(Value* killPointer, bool MadeChange = false; - std::vector undead; + std::vector undead; - for (SmallPtrSet::iterator I = deadPointers.begin(), + for (SmallPtrSet::iterator I = deadPointers.begin(), E = deadPointers.end(); I != E; ++I) { // Get size information for the alloca unsigned pointerSize = ~0U; - if (ConstantInt* C = dyn_cast((*I)->getArraySize())) - pointerSize = C->getZExtValue() * \ - TD.getABITypeSize((*I)->getAllocatedType()); + if (AllocaInst* A = dyn_cast(*I)) { + if (ConstantInt* C = dyn_cast(A->getArraySize())) + pointerSize = C->getZExtValue() * \ + TD.getABITypeSize(A->getAllocatedType()); + } else { + const PointerType* PT = cast( + cast(*I)->getType()); + pointerSize = TD.getABITypeSize(PT->getElementType()); + } // See if this pointer could alias it AliasAnalysis::AliasResult A = AA.alias(*I, pointerSize, @@ -427,10 +465,9 @@ bool DSE::RemoveUndeadPointers(Value* killPointer, undead.push_back(*I); } - for (std::vector::iterator I = undead.begin(), E = undead.end(); + for (std::vector::iterator I = undead.begin(), E = undead.end(); I != E; ++I) - if (AllocaInst *AI = dyn_cast(*I)) - deadPointers.erase(AI); + deadPointers.erase(*I); return MadeChange; }