summaryrefslogtreecommitdiff
path: root/lib/Transforms/Scalar/MemCpyOptimizer.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-11-18 08:07:09 +0000
committerChris Lattner <sabre@nondot.org>2010-11-18 08:07:09 +0000
commitd528be6636539567194981a8c0f8b90220bec0a5 (patch)
treec5106345606efa7effecf6bb91afb3248b3c45c4 /lib/Transforms/Scalar/MemCpyOptimizer.cpp
parent5a7aeaa01904b9b0adf256108f302f8961295754 (diff)
downloadllvm-d528be6636539567194981a8c0f8b90220bec0a5.tar.gz
llvm-d528be6636539567194981a8c0f8b90220bec0a5.tar.bz2
llvm-d528be6636539567194981a8c0f8b90220bec0a5.tar.xz
slightly simplify code and substantially improve comment. Instead of
saying "it would be bad", give an example of what is going on. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@119695 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Scalar/MemCpyOptimizer.cpp')
-rw-r--r--lib/Transforms/Scalar/MemCpyOptimizer.cpp43
1 files changed, 23 insertions, 20 deletions
diff --git a/lib/Transforms/Scalar/MemCpyOptimizer.cpp b/lib/Transforms/Scalar/MemCpyOptimizer.cpp
index 9c16ae417c..c866659c62 100644
--- a/lib/Transforms/Scalar/MemCpyOptimizer.cpp
+++ b/lib/Transforms/Scalar/MemCpyOptimizer.cpp
@@ -712,34 +712,37 @@ bool MemCpyOpt::processMemCpyMemCpyDependence(MemCpyInst *M, MemCpyInst *MDep,
// the alignment past what can be read from or written to.
// TODO: Is this worth it if we're creating a less aligned memcpy? For
// example we could be moving from movaps -> movq on x86.
- unsigned Align = std::min(MDep->getAlignmentCst()->getZExtValue(),
- M->getAlignmentCst()->getZExtValue());
- LLVMContext &Context = M->getContext();
- ConstantInt *AlignCI = ConstantInt::get(Type::getInt32Ty(Context), Align);
+ unsigned Align = std::min(MDep->getAlignment(), M->getAlignment());
Value *Args[5] = {
- M->getRawDest(), MDep->getRawSource(), M->getLength(),
- AlignCI, M->getVolatileCst()
+ M->getRawDest(),
+ MDep->getRawSource(),
+ M->getLength(),
+ ConstantInt::get(Type::getInt32Ty(M->getContext()), Align),
+ M->getVolatileCst()
};
CallInst *C = CallInst::Create(MemCpyFun, Args, Args+5, "", M);
MemoryDependenceAnalysis &MD = getAnalysis<MemoryDependenceAnalysis>();
- // If C and M don't interfere, then this is a valid transformation. If they
- // did, this would mean that the two sources overlap, which would be bad.
- MemDepResult dep = MD.getDependency(C);
- if (dep.isClobber() && dep.getInst() == MDep) {
- MD.removeInstruction(M);
- M->eraseFromParent();
- ++NumMemCpyInstr;
- return true;
+ // 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).
+ MemDepResult NewDep = MD.getDependency(C);
+ if (!NewDep.isClobber() || NewDep.getInst() != MDep) {
+ MD.removeInstruction(C);
+ C->eraseFromParent();
+ return false;
}
-
- // Otherwise, there was no point in doing this, so we remove the call we
- // inserted and act like nothing happened.
- MD.removeInstruction(C);
- C->eraseFromParent();
- return false;
+
+ // Otherwise we're good! Nuke the instruction we're replacing.
+ MD.removeInstruction(M);
+ M->eraseFromParent();
+ ++NumMemCpyInstr;
+ return true;
}