[llvm-commits] [llvm] r60287 - in /llvm/trunk: lib/Transforms/Scalar/SimplifyLibCalls.cpp test/Transforms/SimplifyLibCalls/memmove.ll test/Transforms/SimplifyLibCalls/memset.ll

Eli Friedman eli.friedman at gmail.com
Sun Nov 30 00:32:19 PST 2008


Author: efriedma
Date: Sun Nov 30 02:32:11 2008
New Revision: 60287

URL: http://llvm.org/viewvc/llvm-project?rev=60287&view=rev
Log:
Optimize memmove and memset into the LLVM builtins.  Note that these 
only show up in code from front-ends besides llvm-gcc, like clang.


Added:
    llvm/trunk/test/Transforms/SimplifyLibCalls/memmove.ll
    llvm/trunk/test/Transforms/SimplifyLibCalls/memset.ll
Modified:
    llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp

Modified: llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp?rev=60287&r1=60286&r2=60287&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp Sun Nov 30 02:32:11 2008
@@ -707,6 +707,60 @@
   }
 };
 
+//===---------------------------------------===//
+// 'memmove' Optimizations
+
+struct VISIBILITY_HIDDEN MemMoveOpt : public LibCallOptimization {
+  virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
+    const FunctionType *FT = Callee->getFunctionType();
+    if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) ||
+        !isa<PointerType>(FT->getParamType(0)) ||
+        !isa<PointerType>(FT->getParamType(1)) ||
+        FT->getParamType(2) != TD->getIntPtrType())
+      return 0;
+
+    // memmove(x, y, n) -> llvm.memmove(x, y, n, 1)
+    Module *M = Caller->getParent();
+    Intrinsic::ID IID = Intrinsic::memmove;
+    const Type *Tys[1];
+    Tys[0] = TD->getIntPtrType();
+    Value *MemMove = Intrinsic::getDeclaration(M, IID, Tys, 1);
+    Value *Dst = CastToCStr(CI->getOperand(1), B);
+    Value *Src = CastToCStr(CI->getOperand(2), B);
+    Value *Size = CI->getOperand(3);
+    Value *Align = ConstantInt::get(Type::Int32Ty, 1);
+    B.CreateCall4(MemMove, Dst, Src, Size, Align);
+    return CI->getOperand(1);
+  }
+};
+
+//===---------------------------------------===//
+// 'memset' Optimizations
+
+struct VISIBILITY_HIDDEN MemSetOpt : public LibCallOptimization {
+  virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
+    const FunctionType *FT = Callee->getFunctionType();
+    if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) ||
+        !isa<PointerType>(FT->getParamType(0)) ||
+        FT->getParamType(1) != TD->getIntPtrType() ||
+        FT->getParamType(2) != TD->getIntPtrType())
+      return 0;
+
+    // memset(p, v, n) -> llvm.memset(p, v, n, 1)
+    Module *M = Caller->getParent();
+    Intrinsic::ID IID = Intrinsic::memset;
+    const Type *Tys[1];
+    Tys[0] = TD->getIntPtrType();
+    Value *MemSet = Intrinsic::getDeclaration(M, IID, Tys, 1);
+    Value *Dst = CastToCStr(CI->getOperand(1), B);
+    Value *Val = B.CreateTrunc(CI->getOperand(2), Type::Int8Ty);
+    Value *Size = CI->getOperand(3);
+    Value *Align = ConstantInt::get(Type::Int32Ty, 1);
+    B.CreateCall4(MemSet, Dst, Val, Size, Align);
+    return CI->getOperand(1);
+  }
+};
+
 //===----------------------------------------------------------------------===//
 // Math Library Optimizations
 //===----------------------------------------------------------------------===//
@@ -1197,6 +1251,7 @@
     // String and Memory LibCall Optimizations
     StrCatOpt StrCat; StrChrOpt StrChr; StrCmpOpt StrCmp; StrNCmpOpt StrNCmp;
     StrCpyOpt StrCpy; StrLenOpt StrLen; MemCmpOpt MemCmp; MemCpyOpt  MemCpy;
+    MemMoveOpt MemMove; MemSetOpt MemSet;
     // Math Library Optimizations
     PowOpt Pow; Exp2Opt Exp2; UnaryDoubleFPOpt UnaryDoubleFP;
     // Integer Optimizations
@@ -1242,6 +1297,8 @@
   Optimizations["strlen"] = &StrLen;
   Optimizations["memcmp"] = &MemCmp;
   Optimizations["memcpy"] = &MemCpy;
+  Optimizations["memmove"] = &MemMove;
+  Optimizations["memset"] = &MemSet;
   
   // Math Library Optimizations
   Optimizations["powf"] = &Pow;
@@ -1386,10 +1443,6 @@
 //   * memcmp(x,y,l)   -> cnst
 //      (if all arguments are constant and strlen(x) <= l and strlen(y) <= l)
 //
-// memmove:
-//   * memmove(d,s,l,a) -> memcpy(d,s,l,a)
-//       (if s is a global constant array)
-//
 // pow, powf, powl:
 //   * pow(exp(x),y)  -> exp(x*y)
 //   * pow(sqrt(x),y) -> pow(x,y*0.5)

Added: llvm/trunk/test/Transforms/SimplifyLibCalls/memmove.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyLibCalls/memmove.ll?rev=60287&view=auto

==============================================================================
--- llvm/trunk/test/Transforms/SimplifyLibCalls/memmove.ll (added)
+++ llvm/trunk/test/Transforms/SimplifyLibCalls/memmove.ll Sun Nov 30 02:32:11 2008
@@ -0,0 +1,12 @@
+; RUN: llvm-as < %s | opt -simplify-libcalls | llvm-dis | grep {llvm.memmove}
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32"
+target triple = "i686-pc-linux-gnu"
+
+define i8* @test(i8* %a, i8* %b, i32 %x) {
+entry:
+	%call = call i8* @memmove(i8* %a, i8* %b, i32 %x )
+	ret i8* %call
+}
+
+declare i8* @memmove(i8*,i8*,i32)
+

Added: llvm/trunk/test/Transforms/SimplifyLibCalls/memset.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyLibCalls/memset.ll?rev=60287&view=auto

==============================================================================
--- llvm/trunk/test/Transforms/SimplifyLibCalls/memset.ll (added)
+++ llvm/trunk/test/Transforms/SimplifyLibCalls/memset.ll Sun Nov 30 02:32:11 2008
@@ -0,0 +1,12 @@
+; RUN: llvm-as < %s | opt -simplify-libcalls | llvm-dis | grep {llvm.memset}
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32"
+target triple = "i686-pc-linux-gnu"
+
+define i8* @test(i8* %a, i32 %b, i32 %x) {
+entry:
+	%call = call i8* @memset(i8* %a, i32 %b, i32 %x )
+	ret i8* %call
+}
+
+declare i8* @memset(i8*,i32,i32)
+





More information about the llvm-commits mailing list