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