[llvm-commits] [llvm] r115116 - in /llvm/trunk: lib/Target/README.txt lib/Transforms/Scalar/SimplifyLibCalls.cpp test/Transforms/SimplifyLibCalls/StrSpn.ll

Benjamin Kramer benny.kra at googlemail.com
Wed Sep 29 17:58:35 PDT 2010


Author: d0k
Date: Wed Sep 29 19:58:35 2010
New Revision: 115116

URL: http://llvm.org/viewvc/llvm-project?rev=115116&view=rev
Log:
Add constant folding for strspn and strcspn to SimplifyLibCalls.

Added:
    llvm/trunk/test/Transforms/SimplifyLibCalls/StrSpn.ll
Modified:
    llvm/trunk/lib/Target/README.txt
    llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp

Modified: llvm/trunk/lib/Target/README.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/README.txt?rev=115116&r1=115115&r2=115116&view=diff
==============================================================================
--- llvm/trunk/lib/Target/README.txt (original)
+++ llvm/trunk/lib/Target/README.txt Wed Sep 29 19:58:35 2010
@@ -1340,12 +1340,6 @@
 
 simplifylibcalls should do several optimizations for strspn/strcspn:
 
-strcspn(x, "") -> strlen(x)
-strcspn("", x) -> 0
-strspn("", x) -> 0
-strspn(x, "") -> strlen(x)
-strspn(x, "a") -> strchr(x, 'a')-x
-
 strcspn(x, "a") -> inlined loop for up to 3 letters (similarly for strspn):
 
 size_t __strcspn_c3 (__const char *__s, int __reject1, int __reject2,

Modified: llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp?rev=115116&r1=115115&r2=115116&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp Wed Sep 29 19:58:35 2010
@@ -584,6 +584,67 @@
 };
 
 //===---------------------------------------===//
+// 'strspn' Optimizations
+
+struct StrSpnOpt : public LibCallOptimization {
+  virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
+    const FunctionType *FT = Callee->getFunctionType();
+    if (FT->getNumParams() != 2 ||
+        FT->getParamType(0) != Type::getInt8PtrTy(*Context) ||
+        FT->getParamType(1) != FT->getParamType(0) ||
+        !FT->getReturnType()->isIntegerTy())
+      return 0;
+
+    std::string S1, S2;
+    bool HasS1 = GetConstantStringInfo(CI->getArgOperand(0), S1);
+    bool HasS2 = GetConstantStringInfo(CI->getArgOperand(1), S2);
+
+    // strspn(s, "") -> 0
+    // strspn("", s) -> 0
+    if ((HasS1 && S1.empty()) || (HasS2 && S2.empty()))
+      return Constant::getNullValue(CI->getType());
+
+    // Constant folding.
+    if (HasS1 && HasS2)
+      return ConstantInt::get(CI->getType(), strspn(S1.c_str(), S2.c_str()));
+
+    return 0;
+  }
+};
+
+//===---------------------------------------===//
+// 'strcspn' Optimizations
+
+struct StrCSpnOpt : public LibCallOptimization {
+  virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
+    const FunctionType *FT = Callee->getFunctionType();
+    if (FT->getNumParams() != 2 ||
+        FT->getParamType(0) != Type::getInt8PtrTy(*Context) ||
+        FT->getParamType(1) != FT->getParamType(0) ||
+        !FT->getReturnType()->isIntegerTy())
+      return 0;
+
+    std::string S1, S2;
+    bool HasS1 = GetConstantStringInfo(CI->getArgOperand(0), S1);
+    bool HasS2 = GetConstantStringInfo(CI->getArgOperand(1), S2);
+
+    // strcspn("", s) -> 0
+    if (HasS1 && S1.empty())
+      return Constant::getNullValue(CI->getType());
+
+    // Constant folding.
+    if (HasS1 && HasS2)
+      return ConstantInt::get(CI->getType(), strcspn(S1.c_str(), S2.c_str()));
+
+    // strcspn(s, "") -> strlen(s)
+    if (TD && HasS2 && S2.empty())
+      return EmitStrLen(CI->getArgOperand(0), B, TD);
+
+    return 0;
+  }
+};
+
+//===---------------------------------------===//
 // 'strstr' Optimizations
 
 struct StrStrOpt : public LibCallOptimization {
@@ -1297,7 +1358,7 @@
     StrCatOpt StrCat; StrNCatOpt StrNCat; StrChrOpt StrChr; StrRChrOpt StrRChr;
     StrCmpOpt StrCmp; StrNCmpOpt StrNCmp; StrCpyOpt StrCpy; StrCpyOpt StrCpyChk;
     StrNCpyOpt StrNCpy; StrLenOpt StrLen; StrPBrkOpt StrPBrk;
-    StrToOpt StrTo; StrStrOpt StrStr;
+    StrToOpt StrTo; StrSpnOpt StrSpn; StrCSpnOpt StrCSpn; StrStrOpt StrStr;
     MemCmpOpt MemCmp; MemCpyOpt MemCpy; MemMoveOpt MemMove; MemSetOpt MemSet;
     // Math Library Optimizations
     PowOpt Pow; Exp2Opt Exp2; UnaryDoubleFPOpt UnaryDoubleFP;
@@ -1357,6 +1418,8 @@
   Optimizations["strtoll"] = &StrTo;
   Optimizations["strtold"] = &StrTo;
   Optimizations["strtoull"] = &StrTo;
+  Optimizations["strspn"] = &StrSpn;
+  Optimizations["strcspn"] = &StrCSpn;
   Optimizations["strstr"] = &StrStr;
   Optimizations["memcmp"] = &MemCmp;
   Optimizations["memcpy"] = &MemCpy;
@@ -2250,14 +2313,6 @@
 //   * stpcpy(str, "literal") ->
 //           llvm.memcpy(str,"literal",strlen("literal")+1,1)
 //
-// strspn, strcspn:
-//   * strspn(s,a)   -> const_int (if both args are constant)
-//   * strspn("",a)  -> 0
-//   * strspn(s,"")  -> 0
-//   * strcspn(s,a)  -> const_int (if both args are constant)
-//   * strcspn("",a) -> 0
-//   * strcspn(s,"") -> strlen(a)
-//
 // tan, tanf, tanl:
 //   * tan(atan(x)) -> x
 //

Added: llvm/trunk/test/Transforms/SimplifyLibCalls/StrSpn.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyLibCalls/StrSpn.ll?rev=115116&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/SimplifyLibCalls/StrSpn.ll (added)
+++ llvm/trunk/test/Transforms/SimplifyLibCalls/StrSpn.ll Wed Sep 29 19:58:35 2010
@@ -0,0 +1,41 @@
+; RUN: opt < %s -simplify-libcalls -S | FileCheck %s
+
+target datalayout = "-p:64:64:64"
+
+ at abcba = constant [6 x i8] c"abcba\00"
+ at abc = constant [4 x i8] c"abc\00"
+ at null = constant [1 x i8] zeroinitializer
+
+declare i64 @strspn(i8*, i8*)
+
+define i64 @testspn(i8* %s1, i8* %s2) {
+  	%abcba_p = getelementptr [6 x i8]* @abcba, i32 0, i32 0
+	%abc_p = getelementptr [4 x i8]* @abc, i32 0, i32 0
+	%null_p = getelementptr [1 x i8]* @null, i32 0, i32 0
+	%test1 = call i64 @strspn(i8* %s1, i8* %null_p)
+	%test2 = call i64 @strspn(i8* %null_p, i8* %s2)
+	%test3 = call i64 @strspn(i8* %abcba_p, i8* %abc_p)
+; CHECK-NOT: call i64 @strspn
+	%test4 = call i64 @strspn(i8* %s1, i8* %s2)
+; CHECK: call i64 @strspn(i8* %s1, i8* %s2)
+	ret i64 %test3
+; CHECK ret i64 5
+}
+
+declare i64 @strcspn(i8*, i8*)
+
+define i64 @testcspn(i8* %s1, i8* %s2) {
+  	%abcba_p = getelementptr [6 x i8]* @abcba, i32 0, i32 0
+	%abc_p = getelementptr [4 x i8]* @abc, i32 0, i32 0
+	%null_p = getelementptr [1 x i8]* @null, i32 0, i32 0
+	%test1 = call i64 @strcspn(i8* %s1, i8* %null_p)
+; CHECK: call i64 @strlen(i8* %s1)
+	%test2 = call i64 @strcspn(i8* %null_p, i8* %s2)
+	%test3 = call i64 @strcspn(i8* %abcba_p, i8* %abc_p)
+; CHECK-NOT: call i64 @strcspn
+	%test4 = call i64 @strcspn(i8* %s1, i8* %s2)
+; CHECK: call i64 @strcspn(i8* %s1, i8* %s2)
+        %add0 = add i64 %test1, %test3
+; CHECK: add i64 %{{.+}}, 0
+	ret i64 %add0
+}





More information about the llvm-commits mailing list