LLVM API Documentation

BuildLibCalls.cpp
Go to the documentation of this file.
00001 //===- BuildLibCalls.cpp - Utility builder for libcalls -------------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file implements some functions that will create standard C libcalls.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "llvm/Transforms/Utils/BuildLibCalls.h"
00015 #include "llvm/ADT/SmallString.h"
00016 #include "llvm/IR/Constants.h"
00017 #include "llvm/IR/DataLayout.h"
00018 #include "llvm/IR/Function.h"
00019 #include "llvm/IR/IRBuilder.h"
00020 #include "llvm/IR/Intrinsics.h"
00021 #include "llvm/IR/LLVMContext.h"
00022 #include "llvm/IR/Module.h"
00023 #include "llvm/IR/Type.h"
00024 #include "llvm/Target/TargetLibraryInfo.h"
00025 
00026 using namespace llvm;
00027 
00028 /// CastToCStr - Return V if it is an i8*, otherwise cast it to i8*.
00029 Value *llvm::CastToCStr(Value *V, IRBuilder<> &B) {
00030   unsigned AS = V->getType()->getPointerAddressSpace();
00031   return B.CreateBitCast(V, B.getInt8PtrTy(AS), "cstr");
00032 }
00033 
00034 /// EmitStrLen - Emit a call to the strlen function to the builder, for the
00035 /// specified pointer.  This always returns an integer value of size intptr_t.
00036 Value *llvm::EmitStrLen(Value *Ptr, IRBuilder<> &B, const DataLayout *TD,
00037                         const TargetLibraryInfo *TLI) {
00038   if (!TLI->has(LibFunc::strlen))
00039     return nullptr;
00040 
00041   Module *M = B.GetInsertBlock()->getParent()->getParent();
00042   AttributeSet AS[2];
00043   AS[0] = AttributeSet::get(M->getContext(), 1, Attribute::NoCapture);
00044   Attribute::AttrKind AVs[2] = { Attribute::ReadOnly, Attribute::NoUnwind };
00045   AS[1] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex,
00046                             ArrayRef<Attribute::AttrKind>(AVs, 2));
00047 
00048   LLVMContext &Context = B.GetInsertBlock()->getContext();
00049   Constant *StrLen = M->getOrInsertFunction("strlen",
00050                                             AttributeSet::get(M->getContext(),
00051                                                               AS),
00052                                             TD->getIntPtrType(Context),
00053                                             B.getInt8PtrTy(),
00054                                             NULL);
00055   CallInst *CI = B.CreateCall(StrLen, CastToCStr(Ptr, B), "strlen");
00056   if (const Function *F = dyn_cast<Function>(StrLen->stripPointerCasts()))
00057     CI->setCallingConv(F->getCallingConv());
00058 
00059   return CI;
00060 }
00061 
00062 /// EmitStrNLen - Emit a call to the strnlen function to the builder, for the
00063 /// specified pointer.  Ptr is required to be some pointer type, MaxLen must
00064 /// be of size_t type, and the return value has 'intptr_t' type.
00065 Value *llvm::EmitStrNLen(Value *Ptr, Value *MaxLen, IRBuilder<> &B,
00066                          const DataLayout *TD, const TargetLibraryInfo *TLI) {
00067   if (!TLI->has(LibFunc::strnlen))
00068     return nullptr;
00069 
00070   Module *M = B.GetInsertBlock()->getParent()->getParent();
00071   AttributeSet AS[2];
00072   AS[0] = AttributeSet::get(M->getContext(), 1, Attribute::NoCapture);
00073   Attribute::AttrKind AVs[2] = { Attribute::ReadOnly, Attribute::NoUnwind };
00074   AS[1] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex,
00075                             ArrayRef<Attribute::AttrKind>(AVs, 2));
00076 
00077   LLVMContext &Context = B.GetInsertBlock()->getContext();
00078   Constant *StrNLen = M->getOrInsertFunction("strnlen",
00079                                              AttributeSet::get(M->getContext(),
00080                                                               AS),
00081                                              TD->getIntPtrType(Context),
00082                                              B.getInt8PtrTy(),
00083                                              TD->getIntPtrType(Context),
00084                                              NULL);
00085   CallInst *CI = B.CreateCall2(StrNLen, CastToCStr(Ptr, B), MaxLen, "strnlen");
00086   if (const Function *F = dyn_cast<Function>(StrNLen->stripPointerCasts()))
00087     CI->setCallingConv(F->getCallingConv());
00088 
00089   return CI;
00090 }
00091 
00092 /// EmitStrChr - Emit a call to the strchr function to the builder, for the
00093 /// specified pointer and character.  Ptr is required to be some pointer type,
00094 /// and the return value has 'i8*' type.
00095 Value *llvm::EmitStrChr(Value *Ptr, char C, IRBuilder<> &B,
00096                         const DataLayout *TD, const TargetLibraryInfo *TLI) {
00097   if (!TLI->has(LibFunc::strchr))
00098     return nullptr;
00099 
00100   Module *M = B.GetInsertBlock()->getParent()->getParent();
00101   Attribute::AttrKind AVs[2] = { Attribute::ReadOnly, Attribute::NoUnwind };
00102   AttributeSet AS =
00103     AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex,
00104                       ArrayRef<Attribute::AttrKind>(AVs, 2));
00105 
00106   Type *I8Ptr = B.getInt8PtrTy();
00107   Type *I32Ty = B.getInt32Ty();
00108   Constant *StrChr = M->getOrInsertFunction("strchr",
00109                                             AttributeSet::get(M->getContext(),
00110                                                              AS),
00111                                             I8Ptr, I8Ptr, I32Ty, NULL);
00112   CallInst *CI = B.CreateCall2(StrChr, CastToCStr(Ptr, B),
00113                                ConstantInt::get(I32Ty, C), "strchr");
00114   if (const Function *F = dyn_cast<Function>(StrChr->stripPointerCasts()))
00115     CI->setCallingConv(F->getCallingConv());
00116   return CI;
00117 }
00118 
00119 /// EmitStrNCmp - Emit a call to the strncmp function to the builder.
00120 Value *llvm::EmitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len,
00121                          IRBuilder<> &B, const DataLayout *TD,
00122                          const TargetLibraryInfo *TLI) {
00123   if (!TLI->has(LibFunc::strncmp))
00124     return nullptr;
00125 
00126   Module *M = B.GetInsertBlock()->getParent()->getParent();
00127   AttributeSet AS[3];
00128   AS[0] = AttributeSet::get(M->getContext(), 1, Attribute::NoCapture);
00129   AS[1] = AttributeSet::get(M->getContext(), 2, Attribute::NoCapture);
00130   Attribute::AttrKind AVs[2] = { Attribute::ReadOnly, Attribute::NoUnwind };
00131   AS[2] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex,
00132                             ArrayRef<Attribute::AttrKind>(AVs, 2));
00133 
00134   LLVMContext &Context = B.GetInsertBlock()->getContext();
00135   Value *StrNCmp = M->getOrInsertFunction("strncmp",
00136                                           AttributeSet::get(M->getContext(),
00137                                                            AS),
00138                                           B.getInt32Ty(),
00139                                           B.getInt8PtrTy(),
00140                                           B.getInt8PtrTy(),
00141                                           TD->getIntPtrType(Context), NULL);
00142   CallInst *CI = B.CreateCall3(StrNCmp, CastToCStr(Ptr1, B),
00143                                CastToCStr(Ptr2, B), Len, "strncmp");
00144 
00145   if (const Function *F = dyn_cast<Function>(StrNCmp->stripPointerCasts()))
00146     CI->setCallingConv(F->getCallingConv());
00147 
00148   return CI;
00149 }
00150 
00151 /// EmitStrCpy - Emit a call to the strcpy function to the builder, for the
00152 /// specified pointer arguments.
00153 Value *llvm::EmitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B,
00154                         const DataLayout *TD, const TargetLibraryInfo *TLI,
00155                         StringRef Name) {
00156   if (!TLI->has(LibFunc::strcpy))
00157     return nullptr;
00158 
00159   Module *M = B.GetInsertBlock()->getParent()->getParent();
00160   AttributeSet AS[2];
00161   AS[0] = AttributeSet::get(M->getContext(), 2, Attribute::NoCapture);
00162   AS[1] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex,
00163                             Attribute::NoUnwind);
00164   Type *I8Ptr = B.getInt8PtrTy();
00165   Value *StrCpy = M->getOrInsertFunction(Name,
00166                                          AttributeSet::get(M->getContext(), AS),
00167                                          I8Ptr, I8Ptr, I8Ptr, NULL);
00168   CallInst *CI = B.CreateCall2(StrCpy, CastToCStr(Dst, B), CastToCStr(Src, B),
00169                                Name);
00170   if (const Function *F = dyn_cast<Function>(StrCpy->stripPointerCasts()))
00171     CI->setCallingConv(F->getCallingConv());
00172   return CI;
00173 }
00174 
00175 /// EmitStrNCpy - Emit a call to the strncpy function to the builder, for the
00176 /// specified pointer arguments.
00177 Value *llvm::EmitStrNCpy(Value *Dst, Value *Src, Value *Len,
00178                          IRBuilder<> &B, const DataLayout *TD,
00179                          const TargetLibraryInfo *TLI, StringRef Name) {
00180   if (!TLI->has(LibFunc::strncpy))
00181     return nullptr;
00182 
00183   Module *M = B.GetInsertBlock()->getParent()->getParent();
00184   AttributeSet AS[2];
00185   AS[0] = AttributeSet::get(M->getContext(), 2, Attribute::NoCapture);
00186   AS[1] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex,
00187                             Attribute::NoUnwind);
00188   Type *I8Ptr = B.getInt8PtrTy();
00189   Value *StrNCpy = M->getOrInsertFunction(Name,
00190                                           AttributeSet::get(M->getContext(),
00191                                                             AS),
00192                                           I8Ptr, I8Ptr, I8Ptr,
00193                                           Len->getType(), NULL);
00194   CallInst *CI = B.CreateCall3(StrNCpy, CastToCStr(Dst, B), CastToCStr(Src, B),
00195                                Len, "strncpy");
00196   if (const Function *F = dyn_cast<Function>(StrNCpy->stripPointerCasts()))
00197     CI->setCallingConv(F->getCallingConv());
00198   return CI;
00199 }
00200 
00201 /// EmitMemCpyChk - Emit a call to the __memcpy_chk function to the builder.
00202 /// This expects that the Len and ObjSize have type 'intptr_t' and Dst/Src
00203 /// are pointers.
00204 Value *llvm::EmitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize,
00205                            IRBuilder<> &B, const DataLayout *TD,
00206                            const TargetLibraryInfo *TLI) {
00207   if (!TLI->has(LibFunc::memcpy_chk))
00208     return nullptr;
00209 
00210   Module *M = B.GetInsertBlock()->getParent()->getParent();
00211   AttributeSet AS;
00212   AS = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex,
00213                          Attribute::NoUnwind);
00214   LLVMContext &Context = B.GetInsertBlock()->getContext();
00215   Value *MemCpy = M->getOrInsertFunction("__memcpy_chk",
00216                                          AttributeSet::get(M->getContext(), AS),
00217                                          B.getInt8PtrTy(),
00218                                          B.getInt8PtrTy(),
00219                                          B.getInt8PtrTy(),
00220                                          TD->getIntPtrType(Context),
00221                                          TD->getIntPtrType(Context), NULL);
00222   Dst = CastToCStr(Dst, B);
00223   Src = CastToCStr(Src, B);
00224   CallInst *CI = B.CreateCall4(MemCpy, Dst, Src, Len, ObjSize);
00225   if (const Function *F = dyn_cast<Function>(MemCpy->stripPointerCasts()))
00226     CI->setCallingConv(F->getCallingConv());
00227   return CI;
00228 }
00229 
00230 /// EmitMemChr - Emit a call to the memchr function.  This assumes that Ptr is
00231 /// a pointer, Val is an i32 value, and Len is an 'intptr_t' value.
00232 Value *llvm::EmitMemChr(Value *Ptr, Value *Val,
00233                         Value *Len, IRBuilder<> &B, const DataLayout *TD,
00234                         const TargetLibraryInfo *TLI) {
00235   if (!TLI->has(LibFunc::memchr))
00236     return nullptr;
00237 
00238   Module *M = B.GetInsertBlock()->getParent()->getParent();
00239   AttributeSet AS;
00240   Attribute::AttrKind AVs[2] = { Attribute::ReadOnly, Attribute::NoUnwind };
00241   AS = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex,
00242                          ArrayRef<Attribute::AttrKind>(AVs, 2));
00243   LLVMContext &Context = B.GetInsertBlock()->getContext();
00244   Value *MemChr = M->getOrInsertFunction("memchr",
00245                                          AttributeSet::get(M->getContext(), AS),
00246                                          B.getInt8PtrTy(),
00247                                          B.getInt8PtrTy(),
00248                                          B.getInt32Ty(),
00249                                          TD->getIntPtrType(Context),
00250                                          NULL);
00251   CallInst *CI = B.CreateCall3(MemChr, CastToCStr(Ptr, B), Val, Len, "memchr");
00252 
00253   if (const Function *F = dyn_cast<Function>(MemChr->stripPointerCasts()))
00254     CI->setCallingConv(F->getCallingConv());
00255 
00256   return CI;
00257 }
00258 
00259 /// EmitMemCmp - Emit a call to the memcmp function.
00260 Value *llvm::EmitMemCmp(Value *Ptr1, Value *Ptr2,
00261                         Value *Len, IRBuilder<> &B, const DataLayout *TD,
00262                         const TargetLibraryInfo *TLI) {
00263   if (!TLI->has(LibFunc::memcmp))
00264     return nullptr;
00265 
00266   Module *M = B.GetInsertBlock()->getParent()->getParent();
00267   AttributeSet AS[3];
00268   AS[0] = AttributeSet::get(M->getContext(), 1, Attribute::NoCapture);
00269   AS[1] = AttributeSet::get(M->getContext(), 2, Attribute::NoCapture);
00270   Attribute::AttrKind AVs[2] = { Attribute::ReadOnly, Attribute::NoUnwind };
00271   AS[2] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex,
00272                             ArrayRef<Attribute::AttrKind>(AVs, 2));
00273 
00274   LLVMContext &Context = B.GetInsertBlock()->getContext();
00275   Value *MemCmp = M->getOrInsertFunction("memcmp",
00276                                          AttributeSet::get(M->getContext(), AS),
00277                                          B.getInt32Ty(),
00278                                          B.getInt8PtrTy(),
00279                                          B.getInt8PtrTy(),
00280                                          TD->getIntPtrType(Context), NULL);
00281   CallInst *CI = B.CreateCall3(MemCmp, CastToCStr(Ptr1, B), CastToCStr(Ptr2, B),
00282                                Len, "memcmp");
00283 
00284   if (const Function *F = dyn_cast<Function>(MemCmp->stripPointerCasts()))
00285     CI->setCallingConv(F->getCallingConv());
00286 
00287   return CI;
00288 }
00289 
00290 /// Append a suffix to the function name according to the type of 'Op'.
00291 static void AppendTypeSuffix(Value *Op, StringRef &Name, SmallString<20> &NameBuffer) {
00292   if (!Op->getType()->isDoubleTy()) {
00293       NameBuffer += Name;
00294 
00295     if (Op->getType()->isFloatTy())
00296       NameBuffer += 'f';
00297     else
00298       NameBuffer += 'l';
00299 
00300     Name = NameBuffer;
00301   }  
00302   return;
00303 }
00304 
00305 /// EmitUnaryFloatFnCall - Emit a call to the unary function named 'Name' (e.g.
00306 /// 'floor').  This function is known to take a single of type matching 'Op' and
00307 /// returns one value with the same type.  If 'Op' is a long double, 'l' is
00308 /// added as the suffix of name, if 'Op' is a float, we add a 'f' suffix.
00309 Value *llvm::EmitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B,
00310                                   const AttributeSet &Attrs) {
00311   SmallString<20> NameBuffer;
00312   AppendTypeSuffix(Op, Name, NameBuffer);   
00313 
00314   Module *M = B.GetInsertBlock()->getParent()->getParent();
00315   Value *Callee = M->getOrInsertFunction(Name, Op->getType(),
00316                                          Op->getType(), NULL);
00317   CallInst *CI = B.CreateCall(Callee, Op, Name);
00318   CI->setAttributes(Attrs);
00319   if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts()))
00320     CI->setCallingConv(F->getCallingConv());
00321 
00322   return CI;
00323 }
00324 
00325 /// EmitBinaryFloatFnCall - Emit a call to the binary function named 'Name'
00326 /// (e.g. 'fmin').  This function is known to take type matching 'Op1' and 'Op2'
00327 /// and return one value with the same type.  If 'Op1/Op2' are long double, 'l'
00328 /// is added as the suffix of name, if 'Op1/Op2' is a float, we add a 'f'
00329 /// suffix.
00330 Value *llvm::EmitBinaryFloatFnCall(Value *Op1, Value *Op2, StringRef Name,
00331                                   IRBuilder<> &B, const AttributeSet &Attrs) {
00332   SmallString<20> NameBuffer;
00333   AppendTypeSuffix(Op1, Name, NameBuffer);   
00334 
00335   Module *M = B.GetInsertBlock()->getParent()->getParent();
00336   Value *Callee = M->getOrInsertFunction(Name, Op1->getType(),
00337                                          Op1->getType(), Op2->getType(), NULL);
00338   CallInst *CI = B.CreateCall2(Callee, Op1, Op2, Name);
00339   CI->setAttributes(Attrs);
00340   if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts()))
00341     CI->setCallingConv(F->getCallingConv());
00342 
00343   return CI;
00344 }
00345 
00346 /// EmitPutChar - Emit a call to the putchar function.  This assumes that Char
00347 /// is an integer.
00348 Value *llvm::EmitPutChar(Value *Char, IRBuilder<> &B, const DataLayout *TD,
00349                          const TargetLibraryInfo *TLI) {
00350   if (!TLI->has(LibFunc::putchar))
00351     return nullptr;
00352 
00353   Module *M = B.GetInsertBlock()->getParent()->getParent();
00354   Value *PutChar = M->getOrInsertFunction("putchar", B.getInt32Ty(),
00355                                           B.getInt32Ty(), NULL);
00356   CallInst *CI = B.CreateCall(PutChar,
00357                               B.CreateIntCast(Char,
00358                               B.getInt32Ty(),
00359                               /*isSigned*/true,
00360                               "chari"),
00361                               "putchar");
00362 
00363   if (const Function *F = dyn_cast<Function>(PutChar->stripPointerCasts()))
00364     CI->setCallingConv(F->getCallingConv());
00365   return CI;
00366 }
00367 
00368 /// EmitPutS - Emit a call to the puts function.  This assumes that Str is
00369 /// some pointer.
00370 Value *llvm::EmitPutS(Value *Str, IRBuilder<> &B, const DataLayout *TD,
00371                       const TargetLibraryInfo *TLI) {
00372   if (!TLI->has(LibFunc::puts))
00373     return nullptr;
00374 
00375   Module *M = B.GetInsertBlock()->getParent()->getParent();
00376   AttributeSet AS[2];
00377   AS[0] = AttributeSet::get(M->getContext(), 1, Attribute::NoCapture);
00378   AS[1] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex,
00379                             Attribute::NoUnwind);
00380 
00381   Value *PutS = M->getOrInsertFunction("puts",
00382                                        AttributeSet::get(M->getContext(), AS),
00383                                        B.getInt32Ty(),
00384                                        B.getInt8PtrTy(),
00385                                        NULL);
00386   CallInst *CI = B.CreateCall(PutS, CastToCStr(Str, B), "puts");
00387   if (const Function *F = dyn_cast<Function>(PutS->stripPointerCasts()))
00388     CI->setCallingConv(F->getCallingConv());
00389   return CI;
00390 }
00391 
00392 /// EmitFPutC - Emit a call to the fputc function.  This assumes that Char is
00393 /// an integer and File is a pointer to FILE.
00394 Value *llvm::EmitFPutC(Value *Char, Value *File, IRBuilder<> &B,
00395                        const DataLayout *TD, const TargetLibraryInfo *TLI) {
00396   if (!TLI->has(LibFunc::fputc))
00397     return nullptr;
00398 
00399   Module *M = B.GetInsertBlock()->getParent()->getParent();
00400   AttributeSet AS[2];
00401   AS[0] = AttributeSet::get(M->getContext(), 2, Attribute::NoCapture);
00402   AS[1] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex,
00403                             Attribute::NoUnwind);
00404   Constant *F;
00405   if (File->getType()->isPointerTy())
00406     F = M->getOrInsertFunction("fputc",
00407                                AttributeSet::get(M->getContext(), AS),
00408                                B.getInt32Ty(),
00409                                B.getInt32Ty(), File->getType(),
00410                                NULL);
00411   else
00412     F = M->getOrInsertFunction("fputc",
00413                                B.getInt32Ty(),
00414                                B.getInt32Ty(),
00415                                File->getType(), NULL);
00416   Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/true,
00417                          "chari");
00418   CallInst *CI = B.CreateCall2(F, Char, File, "fputc");
00419 
00420   if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
00421     CI->setCallingConv(Fn->getCallingConv());
00422   return CI;
00423 }
00424 
00425 /// EmitFPutS - Emit a call to the puts function.  Str is required to be a
00426 /// pointer and File is a pointer to FILE.
00427 Value *llvm::EmitFPutS(Value *Str, Value *File, IRBuilder<> &B,
00428                        const DataLayout *TD, const TargetLibraryInfo *TLI) {
00429   if (!TLI->has(LibFunc::fputs))
00430     return nullptr;
00431 
00432   Module *M = B.GetInsertBlock()->getParent()->getParent();
00433   AttributeSet AS[3];
00434   AS[0] = AttributeSet::get(M->getContext(), 1, Attribute::NoCapture);
00435   AS[1] = AttributeSet::get(M->getContext(), 2, Attribute::NoCapture);
00436   AS[2] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex,
00437                             Attribute::NoUnwind);
00438   StringRef FPutsName = TLI->getName(LibFunc::fputs);
00439   Constant *F;
00440   if (File->getType()->isPointerTy())
00441     F = M->getOrInsertFunction(FPutsName,
00442                                AttributeSet::get(M->getContext(), AS),
00443                                B.getInt32Ty(),
00444                                B.getInt8PtrTy(),
00445                                File->getType(), NULL);
00446   else
00447     F = M->getOrInsertFunction(FPutsName, B.getInt32Ty(),
00448                                B.getInt8PtrTy(),
00449                                File->getType(), NULL);
00450   CallInst *CI = B.CreateCall2(F, CastToCStr(Str, B), File, "fputs");
00451 
00452   if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
00453     CI->setCallingConv(Fn->getCallingConv());
00454   return CI;
00455 }
00456 
00457 /// EmitFWrite - Emit a call to the fwrite function.  This assumes that Ptr is
00458 /// a pointer, Size is an 'intptr_t', and File is a pointer to FILE.
00459 Value *llvm::EmitFWrite(Value *Ptr, Value *Size, Value *File,
00460                         IRBuilder<> &B, const DataLayout *TD,
00461                         const TargetLibraryInfo *TLI) {
00462   if (!TLI->has(LibFunc::fwrite))
00463     return nullptr;
00464 
00465   Module *M = B.GetInsertBlock()->getParent()->getParent();
00466   AttributeSet AS[3];
00467   AS[0] = AttributeSet::get(M->getContext(), 1, Attribute::NoCapture);
00468   AS[1] = AttributeSet::get(M->getContext(), 4, Attribute::NoCapture);
00469   AS[2] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex,
00470                             Attribute::NoUnwind);
00471   LLVMContext &Context = B.GetInsertBlock()->getContext();
00472   StringRef FWriteName = TLI->getName(LibFunc::fwrite);
00473   Constant *F;
00474   if (File->getType()->isPointerTy())
00475     F = M->getOrInsertFunction(FWriteName,
00476                                AttributeSet::get(M->getContext(), AS),
00477                                TD->getIntPtrType(Context),
00478                                B.getInt8PtrTy(),
00479                                TD->getIntPtrType(Context),
00480                                TD->getIntPtrType(Context),
00481                                File->getType(), NULL);
00482   else
00483     F = M->getOrInsertFunction(FWriteName, TD->getIntPtrType(Context),
00484                                B.getInt8PtrTy(),
00485                                TD->getIntPtrType(Context),
00486                                TD->getIntPtrType(Context),
00487                                File->getType(), NULL);
00488   CallInst *CI = B.CreateCall4(F, CastToCStr(Ptr, B), Size,
00489                         ConstantInt::get(TD->getIntPtrType(Context), 1), File);
00490 
00491   if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
00492     CI->setCallingConv(Fn->getCallingConv());
00493   return CI;
00494 }
00495 
00496 SimplifyFortifiedLibCalls::~SimplifyFortifiedLibCalls() { }
00497 
00498 bool SimplifyFortifiedLibCalls::fold(CallInst *CI, const DataLayout *TD,
00499                                      const TargetLibraryInfo *TLI) {
00500   // We really need DataLayout for later.
00501   if (!TD) return false;
00502   
00503   this->CI = CI;
00504   Function *Callee = CI->getCalledFunction();
00505   StringRef Name = Callee->getName();
00506   FunctionType *FT = Callee->getFunctionType();
00507   LLVMContext &Context = CI->getParent()->getContext();
00508   IRBuilder<> B(CI);
00509 
00510   if (Name == "__memcpy_chk") {
00511     // Check if this has the right signature.
00512     if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
00513         !FT->getParamType(0)->isPointerTy() ||
00514         !FT->getParamType(1)->isPointerTy() ||
00515         FT->getParamType(2) != TD->getIntPtrType(Context) ||
00516         FT->getParamType(3) != TD->getIntPtrType(Context))
00517       return false;
00518 
00519     if (isFoldable(3, 2, false)) {
00520       B.CreateMemCpy(CI->getArgOperand(0), CI->getArgOperand(1),
00521                      CI->getArgOperand(2), 1);
00522       replaceCall(CI->getArgOperand(0));
00523       return true;
00524     }
00525     return false;
00526   }
00527 
00528   // Should be similar to memcpy.
00529   if (Name == "__mempcpy_chk") {
00530     return false;
00531   }
00532 
00533   if (Name == "__memmove_chk") {
00534     // Check if this has the right signature.
00535     if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
00536         !FT->getParamType(0)->isPointerTy() ||
00537         !FT->getParamType(1)->isPointerTy() ||
00538         FT->getParamType(2) != TD->getIntPtrType(Context) ||
00539         FT->getParamType(3) != TD->getIntPtrType(Context))
00540       return false;
00541 
00542     if (isFoldable(3, 2, false)) {
00543       B.CreateMemMove(CI->getArgOperand(0), CI->getArgOperand(1),
00544                       CI->getArgOperand(2), 1);
00545       replaceCall(CI->getArgOperand(0));
00546       return true;
00547     }
00548     return false;
00549   }
00550 
00551   if (Name == "__memset_chk") {
00552     // Check if this has the right signature.
00553     if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
00554         !FT->getParamType(0)->isPointerTy() ||
00555         !FT->getParamType(1)->isIntegerTy() ||
00556         FT->getParamType(2) != TD->getIntPtrType(Context) ||
00557         FT->getParamType(3) != TD->getIntPtrType(Context))
00558       return false;
00559 
00560     if (isFoldable(3, 2, false)) {
00561       Value *Val = B.CreateIntCast(CI->getArgOperand(1), B.getInt8Ty(),
00562                                    false);
00563       B.CreateMemSet(CI->getArgOperand(0), Val, CI->getArgOperand(2), 1);
00564       replaceCall(CI->getArgOperand(0));
00565       return true;
00566     }
00567     return false;
00568   }
00569 
00570   if (Name == "__strcpy_chk" || Name == "__stpcpy_chk") {
00571     // Check if this has the right signature.
00572     if (FT->getNumParams() != 3 ||
00573         FT->getReturnType() != FT->getParamType(0) ||
00574         FT->getParamType(0) != FT->getParamType(1) ||
00575         FT->getParamType(0) != Type::getInt8PtrTy(Context) ||
00576         FT->getParamType(2) != TD->getIntPtrType(Context))
00577       return 0;
00578     
00579     
00580     // If a) we don't have any length information, or b) we know this will
00581     // fit then just lower to a plain st[rp]cpy. Otherwise we'll keep our
00582     // st[rp]cpy_chk call which may fail at runtime if the size is too long.
00583     // TODO: It might be nice to get a maximum length out of the possible
00584     // string lengths for varying.
00585     if (isFoldable(2, 1, true)) {
00586       Value *Ret = EmitStrCpy(CI->getArgOperand(0), CI->getArgOperand(1), B, TD,
00587                               TLI, Name.substr(2, 6));
00588       if (!Ret)
00589         return false;
00590       replaceCall(Ret);
00591       return true;
00592     }
00593     return false;
00594   }
00595 
00596   if (Name == "__strncpy_chk" || Name == "__stpncpy_chk") {
00597     // Check if this has the right signature.
00598     if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
00599         FT->getParamType(0) != FT->getParamType(1) ||
00600         FT->getParamType(0) != Type::getInt8PtrTy(Context) ||
00601         !FT->getParamType(2)->isIntegerTy() ||
00602         FT->getParamType(3) != TD->getIntPtrType(Context))
00603       return false;
00604 
00605     if (isFoldable(3, 2, false)) {
00606       Value *Ret = EmitStrNCpy(CI->getArgOperand(0), CI->getArgOperand(1),
00607                                CI->getArgOperand(2), B, TD, TLI,
00608                                Name.substr(2, 7));
00609       if (!Ret)
00610         return false;
00611       replaceCall(Ret);
00612       return true;
00613     }
00614     return false;
00615   }
00616 
00617   if (Name == "__strcat_chk") {
00618     return false;
00619   }
00620 
00621   if (Name == "__strncat_chk") {
00622     return false;
00623   }
00624 
00625   return false;
00626 }