diff options
author | Chris Lattner <sabre@nondot.org> | 2010-11-21 08:06:10 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2010-11-21 08:06:10 +0000 |
commit | 604f6fe553eb430c6d991f72baa3633842759b49 (patch) | |
tree | 94f15784b5c8fb9ad26d0ac8f8e24ab6775b6941 /lib/Transforms/Scalar/MemCpyOptimizer.cpp | |
parent | 16f7993e0df4bd0727f8535bd47a2776bec10545 (diff) | |
download | llvm-604f6fe553eb430c6d991f72baa3633842759b49.tar.gz llvm-604f6fe553eb430c6d991f72baa3633842759b49.tar.bz2 llvm-604f6fe553eb430c6d991f72baa3633842759b49.tar.xz |
rework some DSE paths to use the newly-public "getPointerDependencyFrom"
method in MemDep instead of inserting an instruction, doing a query,
then removing it. Neither operation is effectively cached.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@119930 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Scalar/MemCpyOptimizer.cpp')
-rw-r--r-- | lib/Transforms/Scalar/MemCpyOptimizer.cpp | 83 |
1 files changed, 37 insertions, 46 deletions
diff --git a/lib/Transforms/Scalar/MemCpyOptimizer.cpp b/lib/Transforms/Scalar/MemCpyOptimizer.cpp index 4f1cfd622f..edb20381e1 100644 --- a/lib/Transforms/Scalar/MemCpyOptimizer.cpp +++ b/lib/Transforms/Scalar/MemCpyOptimizer.cpp @@ -688,6 +688,24 @@ bool MemCpyOpt::processMemCpyMemCpyDependence(MemCpyInst *M, MemCpyInst *MDep, return false; AliasAnalysis &AA = getAnalysis<AliasAnalysis>(); + + // Verify that the copied-from memory doesn't change in between the two + // transfers. For example, in: + // memcpy(a <- b) + // *b = 42; + // memcpy(c <- a) + // It would be invalid to transform the second memcpy into memcpy(c <- b). + // + // TODO: If the code between M and MDep is transparent to the destination "c", + // then we could still perform the xform by moving M up to the first memcpy. + // + // NOTE: This is conservative, it will stop on any read from the source loc, + // not just the defining memcpy. + MemDepResult SourceDep = + MD->getPointerDependencyFrom(AA.getLocationForSource(MDep), + false, M, M->getParent()); + if (!SourceDep.isClobber() || SourceDep.getInst() != MDep) + return false; // If the dest of the second might alias the source of the first, then the // source and dest might overlap. We still want to eliminate the intermediate @@ -719,26 +737,9 @@ bool MemCpyOpt::processMemCpyMemCpyDependence(MemCpyInst *M, MemCpyInst *MDep, ConstantInt::get(Type::getInt32Ty(MemCpyFun->getContext()), Align), M->getVolatileCst() }; - CallInst *C = CallInst::Create(MemCpyFun, Args, Args+5, "", M); - - - // Verify that the copied-from memory doesn't change in between the two - // transfers. For example, in: - // memcpy(a <- b) - // *b = 42; - // memcpy(c <- a) - // It would be invalid to transform the second memcpy into memcpy(c <- b). - // - // TODO: If the code between M and MDep is transparent to the destination "c", - // then we could still perform the xform by moving M up to the first memcpy. - MemDepResult NewDep = MD->getDependency(C); - if (!NewDep.isClobber() || NewDep.getInst() != MDep) { - MD->removeInstruction(C); - C->eraseFromParent(); - return false; - } + CallInst::Create(MemCpyFun, Args, Args+5, "", M); - // Otherwise we're good! Nuke the instruction we're replacing. + // Remove the instruction we're replacing. MD->removeInstruction(M); M->eraseFromParent(); ++NumMemCpyInstr; @@ -814,16 +815,13 @@ bool MemCpyOpt::processByValArgument(CallSite CS, unsigned ArgNo) { TargetData *TD = getAnalysisIfAvailable<TargetData>(); if (!TD) return false; + // Find out what feeds this byval argument. Value *ByValArg = CS.getArgument(ArgNo); - - // MemDep doesn't have a way to do a local query with a memory location. - // Instead, just insert a load and ask for its dependences. - LoadInst *TmpLoad = new LoadInst(ByValArg, "", CS.getInstruction()); - MemDepResult DepInfo = MD->getDependency(TmpLoad); - - MD->removeInstruction(TmpLoad); - TmpLoad->eraseFromParent(); - + uint64_t ByValSize = TD->getTypeAllocSize(ByValArg->getType()); + MemDepResult DepInfo = + MD->getPointerDependencyFrom(AliasAnalysis::Location(ByValArg, ByValSize), + true, CS.getInstruction(), + CS.getInstruction()->getParent()); if (!DepInfo.isClobber()) return false; @@ -838,8 +836,7 @@ bool MemCpyOpt::processByValArgument(CallSite CS, unsigned ArgNo) { // The length of the memcpy must be larger or equal to the size of the byval. // must be larger than the following one. ConstantInt *C1 = dyn_cast<ConstantInt>(MDep->getLength()); - if (C1 == 0 || - C1->getValue().getZExtValue() < TD->getTypeAllocSize(ByValArg->getType())) + if (C1 == 0 || C1->getValue().getZExtValue() < ByValSize) return false; // Get the alignment of the byval. If it is greater than the memcpy, then we @@ -855,26 +852,20 @@ bool MemCpyOpt::processByValArgument(CallSite CS, unsigned ArgNo) { // *b = 42; // foo(*a) // It would be invalid to transform the second memcpy into foo(*b). + // + // NOTE: This is conservative, it will stop on any read from the source loc, + // not just the defining memcpy. + MemDepResult SourceDep = + MD->getPointerDependencyFrom(AliasAnalysis::getLocationForSource(MDep), + false, CS.getInstruction(), MDep->getParent()); + if (!SourceDep.isClobber() || SourceDep.getInst() != MDep) + return false; + Value *TmpCast = MDep->getSource(); if (MDep->getSource()->getType() != ByValArg->getType()) TmpCast = new BitCastInst(MDep->getSource(), ByValArg->getType(), "tmpcast", CS.getInstruction()); - Value *TmpVal = - UndefValue::get(cast<PointerType>(TmpCast->getType())->getElementType()); - Instruction *TmpStore = new StoreInst(TmpVal, TmpCast, false, - CS.getInstruction()); - DepInfo = MD->getDependency(TmpStore); - bool isUnsafe = !DepInfo.isClobber() || DepInfo.getInst() != MDep; - MD->removeInstruction(TmpStore); - TmpStore->eraseFromParent(); - - if (isUnsafe) { - // Clean up the inserted cast instruction. - if (TmpCast != MDep->getSource()) - cast<Instruction>(TmpCast)->eraseFromParent(); - return false; - } - + DEBUG(dbgs() << "MemCpyOpt: Forwarding memcpy to byval:\n" << " " << *MDep << "\n" << " " << *CS.getInstruction() << "\n"); |