1 //===- BuildLibCalls.cpp - Utility builder for libcalls -------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file implements some functions that will create standard C libcalls. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/Transforms/Utils/BuildLibCalls.h" 15 #include "llvm/ADT/SmallString.h" 16 #include "llvm/Analysis/TargetLibraryInfo.h" 17 #include "llvm/IR/Constants.h" 18 #include "llvm/IR/DataLayout.h" 19 #include "llvm/IR/Function.h" 20 #include "llvm/IR/IRBuilder.h" 21 #include "llvm/IR/Intrinsics.h" 22 #include "llvm/IR/LLVMContext.h" 23 #include "llvm/IR/Module.h" 24 #include "llvm/IR/Type.h" 25 26 using namespace llvm; 27 28 Value *llvm::castToCStr(Value *V, IRBuilder<> &B) { 29 unsigned AS = V->getType()->getPointerAddressSpace(); 30 return B.CreateBitCast(V, B.getInt8PtrTy(AS), "cstr"); 31 } 32 33 Value *llvm::emitStrLen(Value *Ptr, IRBuilder<> &B, const DataLayout &DL, 34 const TargetLibraryInfo *TLI) { 35 if (!TLI->has(LibFunc::strlen)) 36 return nullptr; 37 38 Module *M = B.GetInsertBlock()->getModule(); 39 AttributeSet AS[2]; 40 AS[0] = AttributeSet::get(M->getContext(), 1, Attribute::NoCapture); 41 Attribute::AttrKind AVs[2] = { Attribute::ReadOnly, Attribute::NoUnwind }; 42 AS[1] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex, AVs); 43 44 LLVMContext &Context = B.GetInsertBlock()->getContext(); 45 Constant *StrLen = M->getOrInsertFunction( 46 "strlen", AttributeSet::get(M->getContext(), AS), 47 DL.getIntPtrType(Context), B.getInt8PtrTy(), nullptr); 48 CallInst *CI = B.CreateCall(StrLen, castToCStr(Ptr, B), "strlen"); 49 if (const Function *F = dyn_cast<Function>(StrLen->stripPointerCasts())) 50 CI->setCallingConv(F->getCallingConv()); 51 52 return CI; 53 } 54 55 Value *llvm::emitStrChr(Value *Ptr, char C, IRBuilder<> &B, 56 const TargetLibraryInfo *TLI) { 57 if (!TLI->has(LibFunc::strchr)) 58 return nullptr; 59 60 Module *M = B.GetInsertBlock()->getModule(); 61 Attribute::AttrKind AVs[2] = { Attribute::ReadOnly, Attribute::NoUnwind }; 62 AttributeSet AS = 63 AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex, AVs); 64 65 Type *I8Ptr = B.getInt8PtrTy(); 66 Type *I32Ty = B.getInt32Ty(); 67 Constant *StrChr = M->getOrInsertFunction("strchr", 68 AttributeSet::get(M->getContext(), 69 AS), 70 I8Ptr, I8Ptr, I32Ty, nullptr); 71 CallInst *CI = B.CreateCall( 72 StrChr, {castToCStr(Ptr, B), ConstantInt::get(I32Ty, C)}, "strchr"); 73 if (const Function *F = dyn_cast<Function>(StrChr->stripPointerCasts())) 74 CI->setCallingConv(F->getCallingConv()); 75 return CI; 76 } 77 78 Value *llvm::emitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B, 79 const DataLayout &DL, const TargetLibraryInfo *TLI) { 80 if (!TLI->has(LibFunc::strncmp)) 81 return nullptr; 82 83 Module *M = B.GetInsertBlock()->getModule(); 84 AttributeSet AS[3]; 85 AS[0] = AttributeSet::get(M->getContext(), 1, Attribute::NoCapture); 86 AS[1] = AttributeSet::get(M->getContext(), 2, Attribute::NoCapture); 87 Attribute::AttrKind AVs[2] = { Attribute::ReadOnly, Attribute::NoUnwind }; 88 AS[2] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex, AVs); 89 90 LLVMContext &Context = B.GetInsertBlock()->getContext(); 91 Value *StrNCmp = M->getOrInsertFunction( 92 "strncmp", AttributeSet::get(M->getContext(), AS), B.getInt32Ty(), 93 B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context), nullptr); 94 CallInst *CI = B.CreateCall( 95 StrNCmp, {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, "strncmp"); 96 97 if (const Function *F = dyn_cast<Function>(StrNCmp->stripPointerCasts())) 98 CI->setCallingConv(F->getCallingConv()); 99 100 return CI; 101 } 102 103 Value *llvm::emitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B, 104 const TargetLibraryInfo *TLI, StringRef Name) { 105 if (!TLI->has(LibFunc::strcpy)) 106 return nullptr; 107 108 Module *M = B.GetInsertBlock()->getModule(); 109 AttributeSet AS[2]; 110 AS[0] = AttributeSet::get(M->getContext(), 2, Attribute::NoCapture); 111 AS[1] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex, 112 Attribute::NoUnwind); 113 Type *I8Ptr = B.getInt8PtrTy(); 114 Value *StrCpy = M->getOrInsertFunction(Name, 115 AttributeSet::get(M->getContext(), AS), 116 I8Ptr, I8Ptr, I8Ptr, nullptr); 117 CallInst *CI = 118 B.CreateCall(StrCpy, {castToCStr(Dst, B), castToCStr(Src, B)}, Name); 119 if (const Function *F = dyn_cast<Function>(StrCpy->stripPointerCasts())) 120 CI->setCallingConv(F->getCallingConv()); 121 return CI; 122 } 123 124 Value *llvm::emitStrNCpy(Value *Dst, Value *Src, Value *Len, IRBuilder<> &B, 125 const TargetLibraryInfo *TLI, StringRef Name) { 126 if (!TLI->has(LibFunc::strncpy)) 127 return nullptr; 128 129 Module *M = B.GetInsertBlock()->getModule(); 130 AttributeSet AS[2]; 131 AS[0] = AttributeSet::get(M->getContext(), 2, Attribute::NoCapture); 132 AS[1] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex, 133 Attribute::NoUnwind); 134 Type *I8Ptr = B.getInt8PtrTy(); 135 Value *StrNCpy = M->getOrInsertFunction(Name, 136 AttributeSet::get(M->getContext(), 137 AS), 138 I8Ptr, I8Ptr, I8Ptr, 139 Len->getType(), nullptr); 140 CallInst *CI = B.CreateCall( 141 StrNCpy, {castToCStr(Dst, B), castToCStr(Src, B), Len}, "strncpy"); 142 if (const Function *F = dyn_cast<Function>(StrNCpy->stripPointerCasts())) 143 CI->setCallingConv(F->getCallingConv()); 144 return CI; 145 } 146 147 Value *llvm::emitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize, 148 IRBuilder<> &B, const DataLayout &DL, 149 const TargetLibraryInfo *TLI) { 150 if (!TLI->has(LibFunc::memcpy_chk)) 151 return nullptr; 152 153 Module *M = B.GetInsertBlock()->getModule(); 154 AttributeSet AS; 155 AS = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex, 156 Attribute::NoUnwind); 157 LLVMContext &Context = B.GetInsertBlock()->getContext(); 158 Value *MemCpy = M->getOrInsertFunction( 159 "__memcpy_chk", AttributeSet::get(M->getContext(), AS), B.getInt8PtrTy(), 160 B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context), 161 DL.getIntPtrType(Context), nullptr); 162 Dst = castToCStr(Dst, B); 163 Src = castToCStr(Src, B); 164 CallInst *CI = B.CreateCall(MemCpy, {Dst, Src, Len, ObjSize}); 165 if (const Function *F = dyn_cast<Function>(MemCpy->stripPointerCasts())) 166 CI->setCallingConv(F->getCallingConv()); 167 return CI; 168 } 169 170 Value *llvm::emitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilder<> &B, 171 const DataLayout &DL, const TargetLibraryInfo *TLI) { 172 if (!TLI->has(LibFunc::memchr)) 173 return nullptr; 174 175 Module *M = B.GetInsertBlock()->getModule(); 176 AttributeSet AS; 177 Attribute::AttrKind AVs[2] = { Attribute::ReadOnly, Attribute::NoUnwind }; 178 AS = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex, AVs); 179 LLVMContext &Context = B.GetInsertBlock()->getContext(); 180 Value *MemChr = M->getOrInsertFunction( 181 "memchr", AttributeSet::get(M->getContext(), AS), B.getInt8PtrTy(), 182 B.getInt8PtrTy(), B.getInt32Ty(), DL.getIntPtrType(Context), nullptr); 183 CallInst *CI = B.CreateCall(MemChr, {castToCStr(Ptr, B), Val, Len}, "memchr"); 184 185 if (const Function *F = dyn_cast<Function>(MemChr->stripPointerCasts())) 186 CI->setCallingConv(F->getCallingConv()); 187 188 return CI; 189 } 190 191 Value *llvm::emitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B, 192 const DataLayout &DL, const TargetLibraryInfo *TLI) { 193 if (!TLI->has(LibFunc::memcmp)) 194 return nullptr; 195 196 Module *M = B.GetInsertBlock()->getModule(); 197 AttributeSet AS[3]; 198 AS[0] = AttributeSet::get(M->getContext(), 1, Attribute::NoCapture); 199 AS[1] = AttributeSet::get(M->getContext(), 2, Attribute::NoCapture); 200 Attribute::AttrKind AVs[2] = { Attribute::ReadOnly, Attribute::NoUnwind }; 201 AS[2] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex, AVs); 202 203 LLVMContext &Context = B.GetInsertBlock()->getContext(); 204 Value *MemCmp = M->getOrInsertFunction( 205 "memcmp", AttributeSet::get(M->getContext(), AS), B.getInt32Ty(), 206 B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context), nullptr); 207 CallInst *CI = B.CreateCall( 208 MemCmp, {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, "memcmp"); 209 210 if (const Function *F = dyn_cast<Function>(MemCmp->stripPointerCasts())) 211 CI->setCallingConv(F->getCallingConv()); 212 213 return CI; 214 } 215 216 /// Append a suffix to the function name according to the type of 'Op'. 217 static void appendTypeSuffix(Value *Op, StringRef &Name, 218 SmallString<20> &NameBuffer) { 219 if (!Op->getType()->isDoubleTy()) { 220 NameBuffer += Name; 221 222 if (Op->getType()->isFloatTy()) 223 NameBuffer += 'f'; 224 else 225 NameBuffer += 'l'; 226 227 Name = NameBuffer; 228 } 229 return; 230 } 231 232 Value *llvm::emitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B, 233 const AttributeSet &Attrs) { 234 SmallString<20> NameBuffer; 235 appendTypeSuffix(Op, Name, NameBuffer); 236 237 Module *M = B.GetInsertBlock()->getModule(); 238 Value *Callee = M->getOrInsertFunction(Name, Op->getType(), 239 Op->getType(), nullptr); 240 CallInst *CI = B.CreateCall(Callee, Op, Name); 241 CI->setAttributes(Attrs); 242 if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts())) 243 CI->setCallingConv(F->getCallingConv()); 244 245 return CI; 246 } 247 248 Value *llvm::emitBinaryFloatFnCall(Value *Op1, Value *Op2, StringRef Name, 249 IRBuilder<> &B, const AttributeSet &Attrs) { 250 SmallString<20> NameBuffer; 251 appendTypeSuffix(Op1, Name, NameBuffer); 252 253 Module *M = B.GetInsertBlock()->getModule(); 254 Value *Callee = M->getOrInsertFunction(Name, Op1->getType(), Op1->getType(), 255 Op2->getType(), nullptr); 256 CallInst *CI = B.CreateCall(Callee, {Op1, Op2}, Name); 257 CI->setAttributes(Attrs); 258 if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts())) 259 CI->setCallingConv(F->getCallingConv()); 260 261 return CI; 262 } 263 264 Value *llvm::emitPutChar(Value *Char, IRBuilder<> &B, 265 const TargetLibraryInfo *TLI) { 266 if (!TLI->has(LibFunc::putchar)) 267 return nullptr; 268 269 Module *M = B.GetInsertBlock()->getModule(); 270 Value *PutChar = M->getOrInsertFunction("putchar", B.getInt32Ty(), 271 B.getInt32Ty(), nullptr); 272 CallInst *CI = B.CreateCall(PutChar, 273 B.CreateIntCast(Char, 274 B.getInt32Ty(), 275 /*isSigned*/true, 276 "chari"), 277 "putchar"); 278 279 if (const Function *F = dyn_cast<Function>(PutChar->stripPointerCasts())) 280 CI->setCallingConv(F->getCallingConv()); 281 return CI; 282 } 283 284 Value *llvm::emitPutS(Value *Str, IRBuilder<> &B, 285 const TargetLibraryInfo *TLI) { 286 if (!TLI->has(LibFunc::puts)) 287 return nullptr; 288 289 Module *M = B.GetInsertBlock()->getModule(); 290 AttributeSet AS[2]; 291 AS[0] = AttributeSet::get(M->getContext(), 1, Attribute::NoCapture); 292 AS[1] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex, 293 Attribute::NoUnwind); 294 295 Value *PutS = M->getOrInsertFunction("puts", 296 AttributeSet::get(M->getContext(), AS), 297 B.getInt32Ty(), 298 B.getInt8PtrTy(), 299 nullptr); 300 CallInst *CI = B.CreateCall(PutS, castToCStr(Str, B), "puts"); 301 if (const Function *F = dyn_cast<Function>(PutS->stripPointerCasts())) 302 CI->setCallingConv(F->getCallingConv()); 303 return CI; 304 } 305 306 Value *llvm::emitFPutC(Value *Char, Value *File, IRBuilder<> &B, 307 const TargetLibraryInfo *TLI) { 308 if (!TLI->has(LibFunc::fputc)) 309 return nullptr; 310 311 Module *M = B.GetInsertBlock()->getModule(); 312 AttributeSet AS[2]; 313 AS[0] = AttributeSet::get(M->getContext(), 2, Attribute::NoCapture); 314 AS[1] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex, 315 Attribute::NoUnwind); 316 Constant *F; 317 if (File->getType()->isPointerTy()) 318 F = M->getOrInsertFunction("fputc", 319 AttributeSet::get(M->getContext(), AS), 320 B.getInt32Ty(), 321 B.getInt32Ty(), File->getType(), 322 nullptr); 323 else 324 F = M->getOrInsertFunction("fputc", 325 B.getInt32Ty(), 326 B.getInt32Ty(), 327 File->getType(), nullptr); 328 Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/true, 329 "chari"); 330 CallInst *CI = B.CreateCall(F, {Char, File}, "fputc"); 331 332 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts())) 333 CI->setCallingConv(Fn->getCallingConv()); 334 return CI; 335 } 336 337 Value *llvm::emitFPutS(Value *Str, Value *File, IRBuilder<> &B, 338 const TargetLibraryInfo *TLI) { 339 if (!TLI->has(LibFunc::fputs)) 340 return nullptr; 341 342 Module *M = B.GetInsertBlock()->getModule(); 343 AttributeSet AS[3]; 344 AS[0] = AttributeSet::get(M->getContext(), 1, Attribute::NoCapture); 345 AS[1] = AttributeSet::get(M->getContext(), 2, Attribute::NoCapture); 346 AS[2] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex, 347 Attribute::NoUnwind); 348 StringRef FPutsName = TLI->getName(LibFunc::fputs); 349 Constant *F; 350 if (File->getType()->isPointerTy()) 351 F = M->getOrInsertFunction(FPutsName, 352 AttributeSet::get(M->getContext(), AS), 353 B.getInt32Ty(), 354 B.getInt8PtrTy(), 355 File->getType(), nullptr); 356 else 357 F = M->getOrInsertFunction(FPutsName, B.getInt32Ty(), 358 B.getInt8PtrTy(), 359 File->getType(), nullptr); 360 CallInst *CI = B.CreateCall(F, {castToCStr(Str, B), File}, "fputs"); 361 362 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts())) 363 CI->setCallingConv(Fn->getCallingConv()); 364 return CI; 365 } 366 367 Value *llvm::emitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilder<> &B, 368 const DataLayout &DL, const TargetLibraryInfo *TLI) { 369 if (!TLI->has(LibFunc::fwrite)) 370 return nullptr; 371 372 Module *M = B.GetInsertBlock()->getModule(); 373 AttributeSet AS[3]; 374 AS[0] = AttributeSet::get(M->getContext(), 1, Attribute::NoCapture); 375 AS[1] = AttributeSet::get(M->getContext(), 4, Attribute::NoCapture); 376 AS[2] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex, 377 Attribute::NoUnwind); 378 LLVMContext &Context = B.GetInsertBlock()->getContext(); 379 StringRef FWriteName = TLI->getName(LibFunc::fwrite); 380 Constant *F; 381 if (File->getType()->isPointerTy()) 382 F = M->getOrInsertFunction( 383 FWriteName, AttributeSet::get(M->getContext(), AS), 384 DL.getIntPtrType(Context), B.getInt8PtrTy(), DL.getIntPtrType(Context), 385 DL.getIntPtrType(Context), File->getType(), nullptr); 386 else 387 F = M->getOrInsertFunction(FWriteName, DL.getIntPtrType(Context), 388 B.getInt8PtrTy(), DL.getIntPtrType(Context), 389 DL.getIntPtrType(Context), File->getType(), 390 nullptr); 391 CallInst *CI = 392 B.CreateCall(F, {castToCStr(Ptr, B), Size, 393 ConstantInt::get(DL.getIntPtrType(Context), 1), File}); 394 395 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts())) 396 CI->setCallingConv(Fn->getCallingConv()); 397 return CI; 398 } 399