diff options
author | Chris Lattner <sabre@nondot.org> | 2011-05-01 18:27:11 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2011-05-01 18:27:11 +0000 |
commit | 23f61a09aff4a3c5ca4bba9410878dcfebf0656c (patch) | |
tree | d5db9c1cf3fdfaa1e8ba61064fe21be580c1cced | |
parent | 4d42399d46ed2610703f81386966abfca61799ba (diff) | |
download | bcm5719-llvm-23f61a09aff4a3c5ca4bba9410878dcfebf0656c.tar.gz bcm5719-llvm-23f61a09aff4a3c5ca4bba9410878dcfebf0656c.zip |
enhance memcpyopt to obey -fno-builtin and friends. This addresses a
problem reported on cfe-dev.
llvm-svn: 130661
-rw-r--r-- | llvm/include/llvm/Target/TargetLibraryInfo.h | 3 | ||||
-rw-r--r-- | llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp | 17 |
2 files changed, 20 insertions, 0 deletions
diff --git a/llvm/include/llvm/Target/TargetLibraryInfo.h b/llvm/include/llvm/Target/TargetLibraryInfo.h index 1847a3725e6..0914b5daa4b 100644 --- a/llvm/include/llvm/Target/TargetLibraryInfo.h +++ b/llvm/include/llvm/Target/TargetLibraryInfo.h @@ -23,6 +23,9 @@ namespace llvm { // void *memcpy(void *s1, const void *s2, size_t n); memcpy, + // void *memmove(void *s1, const void *s2, size_t n); + memmove, + /// void memset_pattern16(void *b, const void *pattern16, size_t len); memset_pattern16, diff --git a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp index 1db2e6e227f..a3035cbfb0e 100644 --- a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp +++ b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp @@ -28,6 +28,7 @@ #include "llvm/Support/IRBuilder.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetData.h" +#include "llvm/Target/TargetLibraryInfo.h" #include <list> using namespace llvm; @@ -299,12 +300,15 @@ void MemsetRanges::addRange(int64_t Start, int64_t Size, Value *Ptr, namespace { class MemCpyOpt : public FunctionPass { MemoryDependenceAnalysis *MD; + TargetLibraryInfo *TLI; const TargetData *TD; public: static char ID; // Pass identification, replacement for typeid MemCpyOpt() : FunctionPass(ID) { initializeMemCpyOptPass(*PassRegistry::getPassRegistry()); MD = 0; + TLI = 0; + TD = 0; } bool runOnFunction(Function &F); @@ -316,6 +320,7 @@ namespace { AU.addRequired<DominatorTree>(); AU.addRequired<MemoryDependenceAnalysis>(); AU.addRequired<AliasAnalysis>(); + AU.addRequired<TargetLibraryInfo>(); AU.addPreserved<AliasAnalysis>(); AU.addPreserved<MemoryDependenceAnalysis>(); } @@ -346,6 +351,7 @@ INITIALIZE_PASS_BEGIN(MemCpyOpt, "memcpyopt", "MemCpy Optimization", false, false) INITIALIZE_PASS_DEPENDENCY(DominatorTree) INITIALIZE_PASS_DEPENDENCY(MemoryDependenceAnalysis) +INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfo) INITIALIZE_AG_DEPENDENCY(AliasAnalysis) INITIALIZE_PASS_END(MemCpyOpt, "memcpyopt", "MemCpy Optimization", false, false) @@ -804,6 +810,9 @@ bool MemCpyOpt::processMemCpy(MemCpyInst *M) { bool MemCpyOpt::processMemMove(MemMoveInst *M) { AliasAnalysis &AA = getAnalysis<AliasAnalysis>(); + if (!TLI->has(LibFunc::memmove)) + return false; + // See if the pointers alias. if (!AA.isNoAlias(AA.getLocationForDest(M), AA.getLocationForSource(M))) return false; @@ -935,6 +944,14 @@ bool MemCpyOpt::runOnFunction(Function &F) { bool MadeChange = false; MD = &getAnalysis<MemoryDependenceAnalysis>(); TD = getAnalysisIfAvailable<TargetData>(); + TLI = &getAnalysis<TargetLibraryInfo>(); + + // If we don't have at least memset and memcpy, there is little point of doing + // anything here. These are required by a freestanding implementation, so if + // even they are disabled, there is no point in trying hard. + if (!TLI->has(LibFunc::memset) || !TLI->has(LibFunc::memcpy)) + return false; + while (1) { if (!iterateOnFunction(F)) break; |