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 } 230 231 Value *llvm::emitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B, 232 const AttributeSet &Attrs) { 233 SmallString<20> NameBuffer; 234 appendTypeSuffix(Op, Name, NameBuffer); 235 236 Module *M = B.GetInsertBlock()->getModule(); 237 Value *Callee = M->getOrInsertFunction(Name, Op->getType(), 238 Op->getType(), nullptr); 239 CallInst *CI = B.CreateCall(Callee, Op, Name); 240 CI->setAttributes(Attrs); 241 if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts())) 242 CI->setCallingConv(F->getCallingConv()); 243 244 return CI; 245 } 246 247 Value *llvm::emitBinaryFloatFnCall(Value *Op1, Value *Op2, StringRef Name, 248 IRBuilder<> &B, const AttributeSet &Attrs) { 249 SmallString<20> NameBuffer; 250 appendTypeSuffix(Op1, Name, NameBuffer); 251 252 Module *M = B.GetInsertBlock()->getModule(); 253 Value *Callee = M->getOrInsertFunction(Name, Op1->getType(), Op1->getType(), 254 Op2->getType(), nullptr); 255 CallInst *CI = B.CreateCall(Callee, {Op1, Op2}, Name); 256 CI->setAttributes(Attrs); 257 if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts())) 258 CI->setCallingConv(F->getCallingConv()); 259 260 return CI; 261 } 262 263 Value *llvm::emitPutChar(Value *Char, IRBuilder<> &B, 264 const TargetLibraryInfo *TLI) { 265 if (!TLI->has(LibFunc::putchar)) 266 return nullptr; 267 268 Module *M = B.GetInsertBlock()->getModule(); 269 Value *PutChar = M->getOrInsertFunction("putchar", B.getInt32Ty(), 270 B.getInt32Ty(), nullptr); 271 CallInst *CI = B.CreateCall(PutChar, 272 B.CreateIntCast(Char, 273 B.getInt32Ty(), 274 /*isSigned*/true, 275 "chari"), 276 "putchar"); 277 278 if (const Function *F = dyn_cast<Function>(PutChar->stripPointerCasts())) 279 CI->setCallingConv(F->getCallingConv()); 280 return CI; 281 } 282 283 Value *llvm::emitPutS(Value *Str, IRBuilder<> &B, 284 const TargetLibraryInfo *TLI) { 285 if (!TLI->has(LibFunc::puts)) 286 return nullptr; 287 288 Module *M = B.GetInsertBlock()->getModule(); 289 AttributeSet AS[2]; 290 AS[0] = AttributeSet::get(M->getContext(), 1, Attribute::NoCapture); 291 AS[1] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex, 292 Attribute::NoUnwind); 293 294 Value *PutS = M->getOrInsertFunction("puts", 295 AttributeSet::get(M->getContext(), AS), 296 B.getInt32Ty(), 297 B.getInt8PtrTy(), 298 nullptr); 299 CallInst *CI = B.CreateCall(PutS, castToCStr(Str, B), "puts"); 300 if (const Function *F = dyn_cast<Function>(PutS->stripPointerCasts())) 301 CI->setCallingConv(F->getCallingConv()); 302 return CI; 303 } 304 305 Value *llvm::emitFPutC(Value *Char, Value *File, IRBuilder<> &B, 306 const TargetLibraryInfo *TLI) { 307 if (!TLI->has(LibFunc::fputc)) 308 return nullptr; 309 310 Module *M = B.GetInsertBlock()->getModule(); 311 AttributeSet AS[2]; 312 AS[0] = AttributeSet::get(M->getContext(), 2, Attribute::NoCapture); 313 AS[1] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex, 314 Attribute::NoUnwind); 315 Constant *F; 316 if (File->getType()->isPointerTy()) 317 F = M->getOrInsertFunction("fputc", 318 AttributeSet::get(M->getContext(), AS), 319 B.getInt32Ty(), 320 B.getInt32Ty(), File->getType(), 321 nullptr); 322 else 323 F = M->getOrInsertFunction("fputc", 324 B.getInt32Ty(), 325 B.getInt32Ty(), 326 File->getType(), nullptr); 327 Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/true, 328 "chari"); 329 CallInst *CI = B.CreateCall(F, {Char, File}, "fputc"); 330 331 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts())) 332 CI->setCallingConv(Fn->getCallingConv()); 333 return CI; 334 } 335 336 Value *llvm::emitFPutS(Value *Str, Value *File, IRBuilder<> &B, 337 const TargetLibraryInfo *TLI) { 338 if (!TLI->has(LibFunc::fputs)) 339 return nullptr; 340 341 Module *M = B.GetInsertBlock()->getModule(); 342 AttributeSet AS[3]; 343 AS[0] = AttributeSet::get(M->getContext(), 1, Attribute::NoCapture); 344 AS[1] = AttributeSet::get(M->getContext(), 2, Attribute::NoCapture); 345 AS[2] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex, 346 Attribute::NoUnwind); 347 StringRef FPutsName = TLI->getName(LibFunc::fputs); 348 Constant *F; 349 if (File->getType()->isPointerTy()) 350 F = M->getOrInsertFunction(FPutsName, 351 AttributeSet::get(M->getContext(), AS), 352 B.getInt32Ty(), 353 B.getInt8PtrTy(), 354 File->getType(), nullptr); 355 else 356 F = M->getOrInsertFunction(FPutsName, B.getInt32Ty(), 357 B.getInt8PtrTy(), 358 File->getType(), nullptr); 359 CallInst *CI = B.CreateCall(F, {castToCStr(Str, B), File}, "fputs"); 360 361 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts())) 362 CI->setCallingConv(Fn->getCallingConv()); 363 return CI; 364 } 365 366 Value *llvm::emitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilder<> &B, 367 const DataLayout &DL, const TargetLibraryInfo *TLI) { 368 if (!TLI->has(LibFunc::fwrite)) 369 return nullptr; 370 371 Module *M = B.GetInsertBlock()->getModule(); 372 AttributeSet AS[3]; 373 AS[0] = AttributeSet::get(M->getContext(), 1, Attribute::NoCapture); 374 AS[1] = AttributeSet::get(M->getContext(), 4, Attribute::NoCapture); 375 AS[2] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex, 376 Attribute::NoUnwind); 377 LLVMContext &Context = B.GetInsertBlock()->getContext(); 378 StringRef FWriteName = TLI->getName(LibFunc::fwrite); 379 Constant *F; 380 if (File->getType()->isPointerTy()) 381 F = M->getOrInsertFunction( 382 FWriteName, AttributeSet::get(M->getContext(), AS), 383 DL.getIntPtrType(Context), B.getInt8PtrTy(), DL.getIntPtrType(Context), 384 DL.getIntPtrType(Context), File->getType(), nullptr); 385 else 386 F = M->getOrInsertFunction(FWriteName, DL.getIntPtrType(Context), 387 B.getInt8PtrTy(), DL.getIntPtrType(Context), 388 DL.getIntPtrType(Context), File->getType(), 389 nullptr); 390 CallInst *CI = 391 B.CreateCall(F, {castToCStr(Ptr, B), Size, 392 ConstantInt::get(DL.getIntPtrType(Context), 1), File}); 393 394 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts())) 395 CI->setCallingConv(Fn->getCallingConv()); 396 return CI; 397 } 398