[llvm-commits] CVS: llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp

Reid Spencer reid at x10sys.com
Mon May 2 18:43:56 PDT 2005



Changes in directory llvm/lib/Transforms/IPO:

SimplifyLibCalls.cpp updated: 1.26 -> 1.27
---
Log message:

Add the StrNCmpOptimization which is similar to strcmp.

Unfortunately, this optimization didn't trigger on any llvm-test tests.


---
Diffs of the changes:  (+101 -13)

 SimplifyLibCalls.cpp |  114 +++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 101 insertions(+), 13 deletions(-)


Index: llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp
diff -u llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp:1.26 llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp:1.27
--- llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp:1.26	Mon May  2 18:59:26 2005
+++ llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp	Mon May  2 20:43:45 2005
@@ -573,6 +573,107 @@
   }
 } StrCmpOptimizer;
 
+/// This LibCallOptimization will simplify a call to the strncmp library 
+/// function.  It optimizes out cases where one or both arguments are constant
+/// and the result can be determined statically.
+/// @brief Simplify the strncmp library function.
+struct StrNCmpOptimization : public LibCallOptimization
+{
+public:
+  StrNCmpOptimization() : LibCallOptimization("strncmp") {}
+  virtual ~StrNCmpOptimization() {}
+
+  /// @brief Make sure that the "strcpy" function has the right prototype
+  virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC) 
+  {
+    if (f->getReturnType() == Type::IntTy && f->arg_size() == 3)
+      return true;
+    return false;
+  }
+
+  /// @brief Perform the strncpy optimization
+  virtual bool OptimizeCall(CallInst* ci, SimplifyLibCalls& SLC)
+  {
+    // First, check to see if src and destination are the same. If they are,
+    // then the optimization is to replace the CallInst with a constant 0
+    // because the call is a no-op. 
+    Value* s1 = ci->getOperand(1);
+    Value* s2 = ci->getOperand(2);
+    if (s1 == s2)
+    {
+      // strncmp(x,x,l)  -> 0
+      ci->replaceAllUsesWith(ConstantInt::get(Type::IntTy,0));
+      ci->eraseFromParent();
+      return true;
+    }
+
+    // Check the length argument, if it is Constant zero then the strings are
+    // considered equal.
+    uint64_t len_arg = 0;
+    bool len_arg_is_const = false;
+    if (ConstantInt* len_CI = dyn_cast<ConstantInt>(ci->getOperand(3)))
+    {
+      len_arg_is_const = true;
+      len_arg = len_CI->getRawValue();
+      if (len_arg == 0)
+      {
+        // strncmp(x,y,0)   -> 0
+        ci->replaceAllUsesWith(ConstantInt::get(Type::IntTy,0));
+        ci->eraseFromParent();
+        return true;
+      } 
+    }
+
+    bool isstr_1 = false;
+    uint64_t len_1 = 0;
+    ConstantArray* A1;
+    if (getConstantStringLength(s1,len_1,&A1))
+    {
+      isstr_1 = true;
+      if (len_1 == 0)
+      {
+        // strncmp("",x) -> *x
+        LoadInst* load = new LoadInst(s1,ci->getName()+".load",ci);
+        CastInst* cast = 
+          new CastInst(load,Type::IntTy,ci->getName()+".int",ci);
+        ci->replaceAllUsesWith(cast);
+        ci->eraseFromParent();
+        return true;
+      }
+    }
+
+    bool isstr_2 = false;
+    uint64_t len_2 = 0;
+    ConstantArray* A2;
+    if (getConstantStringLength(s2,len_2,&A2))
+    {
+      isstr_2 = true;
+      if (len_2 == 0)
+      {
+        // strncmp(x,"") -> *x
+        LoadInst* load = new LoadInst(s2,ci->getName()+".val",ci);
+        CastInst* cast = 
+          new CastInst(load,Type::IntTy,ci->getName()+".int",ci);
+        ci->replaceAllUsesWith(cast);
+        ci->eraseFromParent();
+        return true;
+      }
+    }
+
+    if (isstr_1 && isstr_2 && len_arg_is_const)
+    {
+      // strncmp(x,y,const) -> constant
+      std::string str1 = A1->getAsString();
+      std::string str2 = A2->getAsString();
+      int result = strncmp(str1.c_str(), str2.c_str(), len_arg);
+      ci->replaceAllUsesWith(ConstantSInt::get(Type::IntTy,result));
+      ci->eraseFromParent();
+      return true;
+    }
+    return false;
+  }
+} StrNCmpOptimizer;
+
 /// This LibCallOptimization will simplify a call to the strcpy library 
 /// function.  Two optimizations are possible: 
 /// (1) If src and dest are the same and not volatile, just return dest
@@ -1276,24 +1377,11 @@
 //      (if c is a constant integer and s is a constant string)
 //   * strrchr(s1,0) -> strchr(s1,0)
 //
-// strcmp:
-//   * strcmp(x,x)  -> 0
-//   * strcmp(x,"") -> *x
-//   * strcmp("",x) -> *x
-//   * strcmp(x,y)  -> cnst  (if both x and y are constant strings)
-//
 // strncat:
 //   * strncat(x,y,0) -> x
 //   * strncat(x,y,0) -> x (if strlen(y) = 0)
 //   * strncat(x,y,l) -> strcat(x,y) (if y and l are constants an l > strlen(y))
 //
-// strncmp:
-//   * strncmp(x,y,0)   -> 0
-//   * strncmp(x,x,l)   -> 0
-//   * strncmp(x,"",l)  -> *x
-//   * strncmp("",x,l)  -> *x
-//   * strncmp(x,y,1)   -> *x - *y
-//
 // strncpy:
 //   * strncpy(d,s,0) -> d
 //   * strncpy(d,s,l) -> memcpy(d,s,l,1)






More information about the llvm-commits mailing list