diff options
author | Meador Inge <meadori@codesourcery.com> | 2012-10-31 03:33:06 +0000 |
---|---|---|
committer | Meador Inge <meadori@codesourcery.com> | 2012-10-31 03:33:06 +0000 |
commit | 57cfd71f881ae381fa43667e003f595ffd70ea18 (patch) | |
tree | 51b3c51adbfc59145bcf1438b41fe7b97eaf1756 /lib/Transforms/Utils/SimplifyLibCalls.cpp | |
parent | a0885fb8825ed362041b5cf291a007a9f9301ff8 (diff) | |
download | external_llvm-57cfd71f881ae381fa43667e003f595ffd70ea18.zip external_llvm-57cfd71f881ae381fa43667e003f595ffd70ea18.tar.gz external_llvm-57cfd71f881ae381fa43667e003f595ffd70ea18.tar.bz2 |
instcombine: Migrate strlen optimizations
This patch migrates the strlen optimizations from the simplify-libcalls
pass into the instcombine library call simplifier.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@167103 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Utils/SimplifyLibCalls.cpp')
-rw-r--r-- | lib/Transforms/Utils/SimplifyLibCalls.cpp | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/lib/Transforms/Utils/SimplifyLibCalls.cpp b/lib/Transforms/Utils/SimplifyLibCalls.cpp index cc03573..658e7c3 100644 --- a/lib/Transforms/Utils/SimplifyLibCalls.cpp +++ b/lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -64,6 +64,26 @@ public: }; //===----------------------------------------------------------------------===// +// Helper Functions +//===----------------------------------------------------------------------===// + +/// isOnlyUsedInZeroEqualityComparison - Return true if it only matters that the +/// value is equal or not-equal to zero. +static bool isOnlyUsedInZeroEqualityComparison(Value *V) { + for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); + UI != E; ++UI) { + if (ICmpInst *IC = dyn_cast<ICmpInst>(*UI)) + if (IC->isEquality()) + if (Constant *C = dyn_cast<Constant>(IC->getOperand(1))) + if (C->isNullValue()) + continue; + // Unknown instruction. + return false; + } + return true; +} + +//===----------------------------------------------------------------------===// // Fortified Library Call Optimizations //===----------------------------------------------------------------------===// @@ -675,6 +695,28 @@ struct StrNCpyOpt : public LibCallOptimization { } }; +struct StrLenOpt : public LibCallOptimization { + virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { + FunctionType *FT = Callee->getFunctionType(); + if (FT->getNumParams() != 1 || + FT->getParamType(0) != B.getInt8PtrTy() || + !FT->getReturnType()->isIntegerTy()) + return 0; + + Value *Src = CI->getArgOperand(0); + + // Constant folding: strlen("xyz") -> 3 + if (uint64_t Len = GetStringLength(Src)) + return ConstantInt::get(CI->getType(), Len-1); + + // strlen(x) != 0 --> *x != 0 + // strlen(x) == 0 --> *x == 0 + if (isOnlyUsedInZeroEqualityComparison(CI)) + return B.CreateZExt(B.CreateLoad(Src, "strlenfirst"), CI->getType()); + return 0; + } +}; + } // End anonymous namespace. namespace llvm { @@ -702,6 +744,7 @@ class LibCallSimplifierImpl { StrCpyOpt StrCpy; StpCpyOpt StpCpy; StrNCpyOpt StrNCpy; + StrLenOpt StrLen; void initOptimizations(); public: @@ -733,6 +776,7 @@ void LibCallSimplifierImpl::initOptimizations() { Optimizations["strcpy"] = &StrCpy; Optimizations["stpcpy"] = &StpCpy; Optimizations["strncpy"] = &StrNCpy; + Optimizations["strlen"] = &StrLen; } Value *LibCallSimplifierImpl::optimizeCall(CallInst *CI) { |