LLVM  mainline
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/Analysis/TargetLibraryInfo.h"
00017 #include "llvm/IR/Constants.h"
00018 #include "llvm/IR/DataLayout.h"
00019 #include "llvm/IR/Function.h"
00020 #include "llvm/IR/IRBuilder.h"
00021 #include "llvm/IR/Intrinsics.h"
00022 #include "llvm/IR/LLVMContext.h"
00023 #include "llvm/IR/Module.h"
00024 #include "llvm/IR/Type.h"
00025 
00026 using namespace llvm;
00027 
00028 Value *llvm::castToCStr(Value *V, IRBuilder<> &B) {
00029   unsigned AS = V->getType()->getPointerAddressSpace();
00030   return B.CreateBitCast(V, B.getInt8PtrTy(AS), "cstr");
00031 }
00032 
00033 Value *llvm::emitStrLen(Value *Ptr, IRBuilder<> &B, const DataLayout &DL,
00034                         const TargetLibraryInfo *TLI) {
00035   if (!TLI->has(LibFunc::strlen))
00036     return nullptr;
00037 
00038   Module *M = B.GetInsertBlock()->getModule();
00039   AttributeSet AS[2];
00040   AS[0] = AttributeSet::get(M->getContext(), 1, Attribute::NoCapture);
00041   Attribute::AttrKind AVs[2] = { Attribute::ReadOnly, Attribute::NoUnwind };
00042   AS[1] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex, AVs);
00043 
00044   LLVMContext &Context = B.GetInsertBlock()->getContext();
00045   Constant *StrLen = M->getOrInsertFunction(
00046       "strlen", AttributeSet::get(M->getContext(), AS),
00047       DL.getIntPtrType(Context), B.getInt8PtrTy(), nullptr);
00048   CallInst *CI = B.CreateCall(StrLen, castToCStr(Ptr, B), "strlen");
00049   if (const Function *F = dyn_cast<Function>(StrLen->stripPointerCasts()))
00050     CI->setCallingConv(F->getCallingConv());
00051 
00052   return CI;
00053 }
00054 
00055 Value *llvm::emitStrChr(Value *Ptr, char C, IRBuilder<> &B,
00056                         const TargetLibraryInfo *TLI) {
00057   if (!TLI->has(LibFunc::strchr))
00058     return nullptr;
00059 
00060   Module *M = B.GetInsertBlock()->getModule();
00061   Attribute::AttrKind AVs[2] = { Attribute::ReadOnly, Attribute::NoUnwind };
00062   AttributeSet AS =
00063     AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex, AVs);
00064 
00065   Type *I8Ptr = B.getInt8PtrTy();
00066   Type *I32Ty = B.getInt32Ty();
00067   Constant *StrChr = M->getOrInsertFunction("strchr",
00068                                             AttributeSet::get(M->getContext(),
00069                                                              AS),
00070                                             I8Ptr, I8Ptr, I32Ty, nullptr);
00071   CallInst *CI = B.CreateCall(
00072       StrChr, {castToCStr(Ptr, B), ConstantInt::get(I32Ty, C)}, "strchr");
00073   if (const Function *F = dyn_cast<Function>(StrChr->stripPointerCasts()))
00074     CI->setCallingConv(F->getCallingConv());
00075   return CI;
00076 }
00077 
00078 Value *llvm::emitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
00079                          const DataLayout &DL, const TargetLibraryInfo *TLI) {
00080   if (!TLI->has(LibFunc::strncmp))
00081     return nullptr;
00082 
00083   Module *M = B.GetInsertBlock()->getModule();
00084   AttributeSet AS[3];
00085   AS[0] = AttributeSet::get(M->getContext(), 1, Attribute::NoCapture);
00086   AS[1] = AttributeSet::get(M->getContext(), 2, Attribute::NoCapture);
00087   Attribute::AttrKind AVs[2] = { Attribute::ReadOnly, Attribute::NoUnwind };
00088   AS[2] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex, AVs);
00089 
00090   LLVMContext &Context = B.GetInsertBlock()->getContext();
00091   Value *StrNCmp = M->getOrInsertFunction(
00092       "strncmp", AttributeSet::get(M->getContext(), AS), B.getInt32Ty(),
00093       B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context), nullptr);
00094   CallInst *CI = B.CreateCall(
00095       StrNCmp, {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, "strncmp");
00096 
00097   if (const Function *F = dyn_cast<Function>(StrNCmp->stripPointerCasts()))
00098     CI->setCallingConv(F->getCallingConv());
00099 
00100   return CI;
00101 }
00102 
00103 Value *llvm::emitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B,
00104                         const TargetLibraryInfo *TLI, StringRef Name) {
00105   if (!TLI->has(LibFunc::strcpy))
00106     return nullptr;
00107 
00108   Module *M = B.GetInsertBlock()->getModule();
00109   AttributeSet AS[2];
00110   AS[0] = AttributeSet::get(M->getContext(), 2, Attribute::NoCapture);
00111   AS[1] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex,
00112                             Attribute::NoUnwind);
00113   Type *I8Ptr = B.getInt8PtrTy();
00114   Value *StrCpy = M->getOrInsertFunction(Name,
00115                                          AttributeSet::get(M->getContext(), AS),
00116                                          I8Ptr, I8Ptr, I8Ptr, nullptr);
00117   CallInst *CI =
00118       B.CreateCall(StrCpy, {castToCStr(Dst, B), castToCStr(Src, B)}, Name);
00119   if (const Function *F = dyn_cast<Function>(StrCpy->stripPointerCasts()))
00120     CI->setCallingConv(F->getCallingConv());
00121   return CI;
00122 }
00123 
00124 Value *llvm::emitStrNCpy(Value *Dst, Value *Src, Value *Len, IRBuilder<> &B,
00125                          const TargetLibraryInfo *TLI, StringRef Name) {
00126   if (!TLI->has(LibFunc::strncpy))
00127     return nullptr;
00128 
00129   Module *M = B.GetInsertBlock()->getModule();
00130   AttributeSet AS[2];
00131   AS[0] = AttributeSet::get(M->getContext(), 2, Attribute::NoCapture);
00132   AS[1] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex,
00133                             Attribute::NoUnwind);
00134   Type *I8Ptr = B.getInt8PtrTy();
00135   Value *StrNCpy = M->getOrInsertFunction(Name,
00136                                           AttributeSet::get(M->getContext(),
00137                                                             AS),
00138                                           I8Ptr, I8Ptr, I8Ptr,
00139                                           Len->getType(), nullptr);
00140   CallInst *CI = B.CreateCall(
00141       StrNCpy, {castToCStr(Dst, B), castToCStr(Src, B), Len}, "strncpy");
00142   if (const Function *F = dyn_cast<Function>(StrNCpy->stripPointerCasts()))
00143     CI->setCallingConv(F->getCallingConv());
00144   return CI;
00145 }
00146 
00147 Value *llvm::emitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize,
00148                            IRBuilder<> &B, const DataLayout &DL,
00149                            const TargetLibraryInfo *TLI) {
00150   if (!TLI->has(LibFunc::memcpy_chk))
00151     return nullptr;
00152 
00153   Module *M = B.GetInsertBlock()->getModule();
00154   AttributeSet AS;
00155   AS = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex,
00156                          Attribute::NoUnwind);
00157   LLVMContext &Context = B.GetInsertBlock()->getContext();
00158   Value *MemCpy = M->getOrInsertFunction(
00159       "__memcpy_chk", AttributeSet::get(M->getContext(), AS), B.getInt8PtrTy(),
00160       B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context),
00161       DL.getIntPtrType(Context), nullptr);
00162   Dst = castToCStr(Dst, B);
00163   Src = castToCStr(Src, B);
00164   CallInst *CI = B.CreateCall(MemCpy, {Dst, Src, Len, ObjSize});
00165   if (const Function *F = dyn_cast<Function>(MemCpy->stripPointerCasts()))
00166     CI->setCallingConv(F->getCallingConv());
00167   return CI;
00168 }
00169 
00170 Value *llvm::emitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilder<> &B,
00171                         const DataLayout &DL, const TargetLibraryInfo *TLI) {
00172   if (!TLI->has(LibFunc::memchr))
00173     return nullptr;
00174 
00175   Module *M = B.GetInsertBlock()->getModule();
00176   AttributeSet AS;
00177   Attribute::AttrKind AVs[2] = { Attribute::ReadOnly, Attribute::NoUnwind };
00178   AS = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex, AVs);
00179   LLVMContext &Context = B.GetInsertBlock()->getContext();
00180   Value *MemChr = M->getOrInsertFunction(
00181       "memchr", AttributeSet::get(M->getContext(), AS), B.getInt8PtrTy(),
00182       B.getInt8PtrTy(), B.getInt32Ty(), DL.getIntPtrType(Context), nullptr);
00183   CallInst *CI = B.CreateCall(MemChr, {castToCStr(Ptr, B), Val, Len}, "memchr");
00184 
00185   if (const Function *F = dyn_cast<Function>(MemChr->stripPointerCasts()))
00186     CI->setCallingConv(F->getCallingConv());
00187 
00188   return CI;
00189 }
00190 
00191 Value *llvm::emitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
00192                         const DataLayout &DL, const TargetLibraryInfo *TLI) {
00193   if (!TLI->has(LibFunc::memcmp))
00194     return nullptr;
00195 
00196   Module *M = B.GetInsertBlock()->getModule();
00197   AttributeSet AS[3];
00198   AS[0] = AttributeSet::get(M->getContext(), 1, Attribute::NoCapture);
00199   AS[1] = AttributeSet::get(M->getContext(), 2, Attribute::NoCapture);
00200   Attribute::AttrKind AVs[2] = { Attribute::ReadOnly, Attribute::NoUnwind };
00201   AS[2] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex, AVs);
00202 
00203   LLVMContext &Context = B.GetInsertBlock()->getContext();
00204   Value *MemCmp = M->getOrInsertFunction(
00205       "memcmp", AttributeSet::get(M->getContext(), AS), B.getInt32Ty(),
00206       B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context), nullptr);
00207   CallInst *CI = B.CreateCall(
00208       MemCmp, {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, "memcmp");
00209 
00210   if (const Function *F = dyn_cast<Function>(MemCmp->stripPointerCasts()))
00211     CI->setCallingConv(F->getCallingConv());
00212 
00213   return CI;
00214 }
00215 
00216 /// Append a suffix to the function name according to the type of 'Op'.
00217 static void appendTypeSuffix(Value *Op, StringRef &Name,
00218                              SmallString<20> &NameBuffer) {
00219   if (!Op->getType()->isDoubleTy()) {
00220       NameBuffer += Name;
00221 
00222     if (Op->getType()->isFloatTy())
00223       NameBuffer += 'f';
00224     else
00225       NameBuffer += 'l';
00226 
00227     Name = NameBuffer;
00228   }  
00229   return;
00230 }
00231 
00232 Value *llvm::emitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B,
00233                                   const AttributeSet &Attrs) {
00234   SmallString<20> NameBuffer;
00235   appendTypeSuffix(Op, Name, NameBuffer);
00236 
00237   Module *M = B.GetInsertBlock()->getModule();
00238   Value *Callee = M->getOrInsertFunction(Name, Op->getType(),
00239                                          Op->getType(), nullptr);
00240   CallInst *CI = B.CreateCall(Callee, Op, Name);
00241   CI->setAttributes(Attrs);
00242   if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts()))
00243     CI->setCallingConv(F->getCallingConv());
00244 
00245   return CI;
00246 }
00247 
00248 Value *llvm::emitBinaryFloatFnCall(Value *Op1, Value *Op2, StringRef Name,
00249                                   IRBuilder<> &B, const AttributeSet &Attrs) {
00250   SmallString<20> NameBuffer;
00251   appendTypeSuffix(Op1, Name, NameBuffer);
00252 
00253   Module *M = B.GetInsertBlock()->getModule();
00254   Value *Callee = M->getOrInsertFunction(Name, Op1->getType(), Op1->getType(),
00255                                          Op2->getType(), nullptr);
00256   CallInst *CI = B.CreateCall(Callee, {Op1, Op2}, Name);
00257   CI->setAttributes(Attrs);
00258   if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts()))
00259     CI->setCallingConv(F->getCallingConv());
00260 
00261   return CI;
00262 }
00263 
00264 Value *llvm::emitPutChar(Value *Char, IRBuilder<> &B,
00265                          const TargetLibraryInfo *TLI) {
00266   if (!TLI->has(LibFunc::putchar))
00267     return nullptr;
00268 
00269   Module *M = B.GetInsertBlock()->getModule();
00270   Value *PutChar = M->getOrInsertFunction("putchar", B.getInt32Ty(),
00271                                           B.getInt32Ty(), nullptr);
00272   CallInst *CI = B.CreateCall(PutChar,
00273                               B.CreateIntCast(Char,
00274                               B.getInt32Ty(),
00275                               /*isSigned*/true,
00276                               "chari"),
00277                               "putchar");
00278 
00279   if (const Function *F = dyn_cast<Function>(PutChar->stripPointerCasts()))
00280     CI->setCallingConv(F->getCallingConv());
00281   return CI;
00282 }
00283 
00284 Value *llvm::emitPutS(Value *Str, IRBuilder<> &B,
00285                       const TargetLibraryInfo *TLI) {
00286   if (!TLI->has(LibFunc::puts))
00287     return nullptr;
00288 
00289   Module *M = B.GetInsertBlock()->getModule();
00290   AttributeSet AS[2];
00291   AS[0] = AttributeSet::get(M->getContext(), 1, Attribute::NoCapture);
00292   AS[1] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex,
00293                             Attribute::NoUnwind);
00294 
00295   Value *PutS = M->getOrInsertFunction("puts",
00296                                        AttributeSet::get(M->getContext(), AS),
00297                                        B.getInt32Ty(),
00298                                        B.getInt8PtrTy(),
00299                                        nullptr);
00300   CallInst *CI = B.CreateCall(PutS, castToCStr(Str, B), "puts");
00301   if (const Function *F = dyn_cast<Function>(PutS->stripPointerCasts()))
00302     CI->setCallingConv(F->getCallingConv());
00303   return CI;
00304 }
00305 
00306 Value *llvm::emitFPutC(Value *Char, Value *File, IRBuilder<> &B,
00307                        const TargetLibraryInfo *TLI) {
00308   if (!TLI->has(LibFunc::fputc))
00309     return nullptr;
00310 
00311   Module *M = B.GetInsertBlock()->getModule();
00312   AttributeSet AS[2];
00313   AS[0] = AttributeSet::get(M->getContext(), 2, Attribute::NoCapture);
00314   AS[1] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex,
00315                             Attribute::NoUnwind);
00316   Constant *F;
00317   if (File->getType()->isPointerTy())
00318     F = M->getOrInsertFunction("fputc",
00319                                AttributeSet::get(M->getContext(), AS),
00320                                B.getInt32Ty(),
00321                                B.getInt32Ty(), File->getType(),
00322                                nullptr);
00323   else
00324     F = M->getOrInsertFunction("fputc",
00325                                B.getInt32Ty(),
00326                                B.getInt32Ty(),
00327                                File->getType(), nullptr);
00328   Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/true,
00329                          "chari");
00330   CallInst *CI = B.CreateCall(F, {Char, File}, "fputc");
00331 
00332   if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
00333     CI->setCallingConv(Fn->getCallingConv());
00334   return CI;
00335 }
00336 
00337 Value *llvm::emitFPutS(Value *Str, Value *File, IRBuilder<> &B,
00338                        const TargetLibraryInfo *TLI) {
00339   if (!TLI->has(LibFunc::fputs))
00340     return nullptr;
00341 
00342   Module *M = B.GetInsertBlock()->getModule();
00343   AttributeSet AS[3];
00344   AS[0] = AttributeSet::get(M->getContext(), 1, Attribute::NoCapture);
00345   AS[1] = AttributeSet::get(M->getContext(), 2, Attribute::NoCapture);
00346   AS[2] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex,
00347                             Attribute::NoUnwind);
00348   StringRef FPutsName = TLI->getName(LibFunc::fputs);
00349   Constant *F;
00350   if (File->getType()->isPointerTy())
00351     F = M->getOrInsertFunction(FPutsName,
00352                                AttributeSet::get(M->getContext(), AS),
00353                                B.getInt32Ty(),
00354                                B.getInt8PtrTy(),
00355                                File->getType(), nullptr);
00356   else
00357     F = M->getOrInsertFunction(FPutsName, B.getInt32Ty(),
00358                                B.getInt8PtrTy(),
00359                                File->getType(), nullptr);
00360   CallInst *CI = B.CreateCall(F, {castToCStr(Str, B), File}, "fputs");
00361 
00362   if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
00363     CI->setCallingConv(Fn->getCallingConv());
00364   return CI;
00365 }
00366 
00367 Value *llvm::emitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilder<> &B,
00368                         const DataLayout &DL, const TargetLibraryInfo *TLI) {
00369   if (!TLI->has(LibFunc::fwrite))
00370     return nullptr;
00371 
00372   Module *M = B.GetInsertBlock()->getModule();
00373   AttributeSet AS[3];
00374   AS[0] = AttributeSet::get(M->getContext(), 1, Attribute::NoCapture);
00375   AS[1] = AttributeSet::get(M->getContext(), 4, Attribute::NoCapture);
00376   AS[2] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex,
00377                             Attribute::NoUnwind);
00378   LLVMContext &Context = B.GetInsertBlock()->getContext();
00379   StringRef FWriteName = TLI->getName(LibFunc::fwrite);
00380   Constant *F;
00381   if (File->getType()->isPointerTy())
00382     F = M->getOrInsertFunction(
00383         FWriteName, AttributeSet::get(M->getContext(), AS),
00384         DL.getIntPtrType(Context), B.getInt8PtrTy(), DL.getIntPtrType(Context),
00385         DL.getIntPtrType(Context), File->getType(), nullptr);
00386   else
00387     F = M->getOrInsertFunction(FWriteName, DL.getIntPtrType(Context),
00388                                B.getInt8PtrTy(), DL.getIntPtrType(Context),
00389                                DL.getIntPtrType(Context), File->getType(),
00390                                nullptr);
00391   CallInst *CI =
00392       B.CreateCall(F, {castToCStr(Ptr, B), Size,
00393                        ConstantInt::get(DL.getIntPtrType(Context), 1), File});
00394 
00395   if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
00396     CI->setCallingConv(Fn->getCallingConv());
00397   return CI;
00398 }