diff options
| author | 2019-01-27 16:42:12 +0000 | |
|---|---|---|
| committer | 2019-01-27 16:42:12 +0000 | |
| commit | b773203fb58f3ef282fb69c832d8710cab5bc82d (patch) | |
| tree | e75913f147570fbd75169647b144df85b88a038c /gnu/llvm/lib/Transforms/Utils/BuildLibCalls.cpp | |
| parent | tweak errno in previous (diff) | |
| download | wireguard-openbsd-b773203fb58f3ef282fb69c832d8710cab5bc82d.tar.xz wireguard-openbsd-b773203fb58f3ef282fb69c832d8710cab5bc82d.zip | |
Import LLVM 7.0.1 release including clang, lld and lldb.
Diffstat (limited to 'gnu/llvm/lib/Transforms/Utils/BuildLibCalls.cpp')
| -rw-r--r-- | gnu/llvm/lib/Transforms/Utils/BuildLibCalls.cpp | 274 |
1 files changed, 240 insertions, 34 deletions
diff --git a/gnu/llvm/lib/Transforms/Utils/BuildLibCalls.cpp b/gnu/llvm/lib/Transforms/Utils/BuildLibCalls.cpp index b60dfb4f354..24520036201 100644 --- a/gnu/llvm/lib/Transforms/Utils/BuildLibCalls.cpp +++ b/gnu/llvm/lib/Transforms/Utils/BuildLibCalls.cpp @@ -105,12 +105,31 @@ static bool setRetNonNull(Function &F) { return true; } +static bool setNonLazyBind(Function &F) { + if (F.hasFnAttribute(Attribute::NonLazyBind)) + return false; + F.addFnAttr(Attribute::NonLazyBind); + return true; +} + +bool llvm::inferLibFuncAttributes(Module *M, StringRef Name, + const TargetLibraryInfo &TLI) { + Function *F = M->getFunction(Name); + if (!F) + return false; + return inferLibFuncAttributes(*F, TLI); +} + bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) { LibFunc TheLibFunc; if (!(TLI.getLibFunc(F, TheLibFunc) && TLI.has(TheLibFunc))) return false; bool Changed = false; + + if (F.getParent() != nullptr && F.getParent()->getRtLibUseGOT()) + Changed |= setNonLazyBind(F); + switch (TheLibFunc) { case LibFunc_strlen: case LibFunc_wcslen: @@ -375,6 +394,7 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) { case LibFunc_fseek: case LibFunc_ftell: case LibFunc_fgetc: + case LibFunc_fgetc_unlocked: case LibFunc_fseeko: case LibFunc_ftello: case LibFunc_fileno: @@ -393,6 +413,7 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) { Changed |= setOnlyReadsMemory(F); return Changed; case LibFunc_fputc: + case LibFunc_fputc_unlocked: case LibFunc_fstat: case LibFunc_frexp: case LibFunc_frexpf: @@ -402,21 +423,25 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) { Changed |= setDoesNotCapture(F, 1); return Changed; case LibFunc_fgets: + case LibFunc_fgets_unlocked: Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 2); return Changed; case LibFunc_fread: + case LibFunc_fread_unlocked: Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setDoesNotCapture(F, 3); return Changed; case LibFunc_fwrite: + case LibFunc_fwrite_unlocked: Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setDoesNotCapture(F, 3); // FIXME: readonly #1? return Changed; case LibFunc_fputs: + case LibFunc_fputs_unlocked: Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setDoesNotCapture(F, 1); @@ -447,6 +472,7 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) { return Changed; case LibFunc_gets: case LibFunc_getchar: + case LibFunc_getchar_unlocked: Changed |= setDoesNotThrow(F); return Changed; case LibFunc_getitimer: @@ -485,6 +511,7 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) { Changed |= setOnlyReadsMemory(F, 1); return Changed; case LibFunc_putc: + case LibFunc_putc_unlocked: Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 1); return Changed; @@ -505,6 +532,7 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) { Changed |= setOnlyReadsMemory(F, 1); return Changed; case LibFunc_putchar: + case LibFunc_putchar_unlocked: Changed |= setDoesNotThrow(F); return Changed; case LibFunc_popen: @@ -687,9 +715,9 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) { Changed |= setRetNonNull(F); Changed |= setRetDoesNotAlias(F); return Changed; - //TODO: add LibFunc entries for: - //case LibFunc_memset_pattern4: - //case LibFunc_memset_pattern8: + // TODO: add LibFunc entries for: + // case LibFunc_memset_pattern4: + // case LibFunc_memset_pattern8: case LibFunc_memset_pattern16: Changed |= setOnlyAccessesArgMemory(F); Changed |= setDoesNotCapture(F, 0); @@ -709,6 +737,19 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) { } } +bool llvm::hasUnaryFloatFn(const TargetLibraryInfo *TLI, Type *Ty, + LibFunc DoubleFn, LibFunc FloatFn, + LibFunc LongDoubleFn) { + switch (Ty->getTypeID()) { + case Type::FloatTyID: + return TLI->has(FloatFn); + case Type::DoubleTyID: + return TLI->has(DoubleFn); + default: + return TLI->has(LongDoubleFn); + } +} + //- Emit LibCalls ------------------------------------------------------------// Value *llvm::castToCStr(Value *V, IRBuilder<> &B) { @@ -722,11 +763,12 @@ Value *llvm::emitStrLen(Value *Ptr, IRBuilder<> &B, const DataLayout &DL, return nullptr; Module *M = B.GetInsertBlock()->getModule(); + StringRef StrlenName = TLI->getName(LibFunc_strlen); LLVMContext &Context = B.GetInsertBlock()->getContext(); - Constant *StrLen = M->getOrInsertFunction("strlen", DL.getIntPtrType(Context), + Constant *StrLen = M->getOrInsertFunction(StrlenName, DL.getIntPtrType(Context), B.getInt8PtrTy()); - inferLibFuncAttributes(*M->getFunction("strlen"), *TLI); - CallInst *CI = B.CreateCall(StrLen, castToCStr(Ptr, B), "strlen"); + inferLibFuncAttributes(M, StrlenName, *TLI); + CallInst *CI = B.CreateCall(StrLen, castToCStr(Ptr, B), StrlenName); if (const Function *F = dyn_cast<Function>(StrLen->stripPointerCasts())) CI->setCallingConv(F->getCallingConv()); @@ -739,13 +781,14 @@ Value *llvm::emitStrChr(Value *Ptr, char C, IRBuilder<> &B, return nullptr; Module *M = B.GetInsertBlock()->getModule(); + StringRef StrChrName = TLI->getName(LibFunc_strchr); Type *I8Ptr = B.getInt8PtrTy(); Type *I32Ty = B.getInt32Ty(); Constant *StrChr = - M->getOrInsertFunction("strchr", I8Ptr, I8Ptr, I32Ty); - inferLibFuncAttributes(*M->getFunction("strchr"), *TLI); + M->getOrInsertFunction(StrChrName, I8Ptr, I8Ptr, I32Ty); + inferLibFuncAttributes(M, StrChrName, *TLI); CallInst *CI = B.CreateCall( - StrChr, {castToCStr(Ptr, B), ConstantInt::get(I32Ty, C)}, "strchr"); + StrChr, {castToCStr(Ptr, B), ConstantInt::get(I32Ty, C)}, StrChrName); if (const Function *F = dyn_cast<Function>(StrChr->stripPointerCasts())) CI->setCallingConv(F->getCallingConv()); return CI; @@ -757,13 +800,14 @@ Value *llvm::emitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B, return nullptr; Module *M = B.GetInsertBlock()->getModule(); + StringRef StrNCmpName = TLI->getName(LibFunc_strncmp); LLVMContext &Context = B.GetInsertBlock()->getContext(); - Value *StrNCmp = M->getOrInsertFunction("strncmp", B.getInt32Ty(), + Value *StrNCmp = M->getOrInsertFunction(StrNCmpName, B.getInt32Ty(), B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context)); - inferLibFuncAttributes(*M->getFunction("strncmp"), *TLI); + inferLibFuncAttributes(M, StrNCmpName, *TLI); CallInst *CI = B.CreateCall( - StrNCmp, {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, "strncmp"); + StrNCmp, {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, StrNCmpName); if (const Function *F = dyn_cast<Function>(StrNCmp->stripPointerCasts())) CI->setCallingConv(F->getCallingConv()); @@ -779,7 +823,7 @@ Value *llvm::emitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B, Module *M = B.GetInsertBlock()->getModule(); Type *I8Ptr = B.getInt8PtrTy(); Value *StrCpy = M->getOrInsertFunction(Name, I8Ptr, I8Ptr, I8Ptr); - inferLibFuncAttributes(*M->getFunction(Name), *TLI); + inferLibFuncAttributes(M, Name, *TLI); CallInst *CI = B.CreateCall(StrCpy, {castToCStr(Dst, B), castToCStr(Src, B)}, Name); if (const Function *F = dyn_cast<Function>(StrCpy->stripPointerCasts())) @@ -796,9 +840,9 @@ Value *llvm::emitStrNCpy(Value *Dst, Value *Src, Value *Len, IRBuilder<> &B, Type *I8Ptr = B.getInt8PtrTy(); Value *StrNCpy = M->getOrInsertFunction(Name, I8Ptr, I8Ptr, I8Ptr, Len->getType()); - inferLibFuncAttributes(*M->getFunction(Name), *TLI); + inferLibFuncAttributes(M, Name, *TLI); CallInst *CI = B.CreateCall( - StrNCpy, {castToCStr(Dst, B), castToCStr(Src, B), Len}, "strncpy"); + StrNCpy, {castToCStr(Dst, B), castToCStr(Src, B), Len}, Name); if (const Function *F = dyn_cast<Function>(StrNCpy->stripPointerCasts())) CI->setCallingConv(F->getCallingConv()); return CI; @@ -833,12 +877,13 @@ Value *llvm::emitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilder<> &B, return nullptr; Module *M = B.GetInsertBlock()->getModule(); + StringRef MemChrName = TLI->getName(LibFunc_memchr); LLVMContext &Context = B.GetInsertBlock()->getContext(); - Value *MemChr = M->getOrInsertFunction("memchr", B.getInt8PtrTy(), + Value *MemChr = M->getOrInsertFunction(MemChrName, B.getInt8PtrTy(), B.getInt8PtrTy(), B.getInt32Ty(), DL.getIntPtrType(Context)); - inferLibFuncAttributes(*M->getFunction("memchr"), *TLI); - CallInst *CI = B.CreateCall(MemChr, {castToCStr(Ptr, B), Val, Len}, "memchr"); + inferLibFuncAttributes(M, MemChrName, *TLI); + CallInst *CI = B.CreateCall(MemChr, {castToCStr(Ptr, B), Val, Len}, MemChrName); if (const Function *F = dyn_cast<Function>(MemChr->stripPointerCasts())) CI->setCallingConv(F->getCallingConv()); @@ -852,13 +897,14 @@ Value *llvm::emitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B, return nullptr; Module *M = B.GetInsertBlock()->getModule(); + StringRef MemCmpName = TLI->getName(LibFunc_memcmp); LLVMContext &Context = B.GetInsertBlock()->getContext(); - Value *MemCmp = M->getOrInsertFunction("memcmp", B.getInt32Ty(), + Value *MemCmp = M->getOrInsertFunction(MemCmpName, B.getInt32Ty(), B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context)); - inferLibFuncAttributes(*M->getFunction("memcmp"), *TLI); + inferLibFuncAttributes(M, MemCmpName, *TLI); CallInst *CI = B.CreateCall( - MemCmp, {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, "memcmp"); + MemCmp, {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, MemCmpName); if (const Function *F = dyn_cast<Function>(MemCmp->stripPointerCasts())) CI->setCallingConv(F->getCallingConv()); @@ -878,7 +924,7 @@ static void appendTypeSuffix(Value *Op, StringRef &Name, NameBuffer += 'l'; Name = NameBuffer; - } + } } Value *llvm::emitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B, @@ -925,14 +971,15 @@ Value *llvm::emitPutChar(Value *Char, IRBuilder<> &B, return nullptr; Module *M = B.GetInsertBlock()->getModule(); - Value *PutChar = M->getOrInsertFunction("putchar", B.getInt32Ty(), B.getInt32Ty()); - inferLibFuncAttributes(*M->getFunction("putchar"), *TLI); + StringRef PutCharName = TLI->getName(LibFunc_putchar); + Value *PutChar = M->getOrInsertFunction(PutCharName, B.getInt32Ty(), B.getInt32Ty()); + inferLibFuncAttributes(M, PutCharName, *TLI); CallInst *CI = B.CreateCall(PutChar, B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/true, "chari"), - "putchar"); + PutCharName); if (const Function *F = dyn_cast<Function>(PutChar->stripPointerCasts())) CI->setCallingConv(F->getCallingConv()); @@ -945,10 +992,11 @@ Value *llvm::emitPutS(Value *Str, IRBuilder<> &B, return nullptr; Module *M = B.GetInsertBlock()->getModule(); + StringRef PutsName = TLI->getName(LibFunc_puts); Value *PutS = - M->getOrInsertFunction("puts", B.getInt32Ty(), B.getInt8PtrTy()); - inferLibFuncAttributes(*M->getFunction("puts"), *TLI); - CallInst *CI = B.CreateCall(PutS, castToCStr(Str, B), "puts"); + M->getOrInsertFunction(PutsName, B.getInt32Ty(), B.getInt8PtrTy()); + inferLibFuncAttributes(M, PutsName, *TLI); + CallInst *CI = B.CreateCall(PutS, castToCStr(Str, B), PutsName); if (const Function *F = dyn_cast<Function>(PutS->stripPointerCasts())) CI->setCallingConv(F->getCallingConv()); return CI; @@ -960,13 +1008,33 @@ Value *llvm::emitFPutC(Value *Char, Value *File, IRBuilder<> &B, return nullptr; Module *M = B.GetInsertBlock()->getModule(); - Constant *F = M->getOrInsertFunction("fputc", B.getInt32Ty(), B.getInt32Ty(), + StringRef FPutcName = TLI->getName(LibFunc_fputc); + Constant *F = M->getOrInsertFunction(FPutcName, B.getInt32Ty(), B.getInt32Ty(), File->getType()); if (File->getType()->isPointerTy()) - inferLibFuncAttributes(*M->getFunction("fputc"), *TLI); + inferLibFuncAttributes(M, FPutcName, *TLI); Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/true, "chari"); - CallInst *CI = B.CreateCall(F, {Char, File}, "fputc"); + CallInst *CI = B.CreateCall(F, {Char, File}, FPutcName); + + if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts())) + CI->setCallingConv(Fn->getCallingConv()); + return CI; +} + +Value *llvm::emitFPutCUnlocked(Value *Char, Value *File, IRBuilder<> &B, + const TargetLibraryInfo *TLI) { + if (!TLI->has(LibFunc_fputc_unlocked)) + return nullptr; + + Module *M = B.GetInsertBlock()->getModule(); + StringRef FPutcUnlockedName = TLI->getName(LibFunc_fputc_unlocked); + Constant *F = M->getOrInsertFunction(FPutcUnlockedName, B.getInt32Ty(), + B.getInt32Ty(), File->getType()); + if (File->getType()->isPointerTy()) + inferLibFuncAttributes(M, FPutcUnlockedName, *TLI); + Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/ true, "chari"); + CallInst *CI = B.CreateCall(F, {Char, File}, FPutcUnlockedName); if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts())) CI->setCallingConv(Fn->getCallingConv()); @@ -983,8 +1051,26 @@ Value *llvm::emitFPutS(Value *Str, Value *File, IRBuilder<> &B, Constant *F = M->getOrInsertFunction( FPutsName, B.getInt32Ty(), B.getInt8PtrTy(), File->getType()); if (File->getType()->isPointerTy()) - inferLibFuncAttributes(*M->getFunction(FPutsName), *TLI); - CallInst *CI = B.CreateCall(F, {castToCStr(Str, B), File}, "fputs"); + inferLibFuncAttributes(M, FPutsName, *TLI); + CallInst *CI = B.CreateCall(F, {castToCStr(Str, B), File}, FPutsName); + + if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts())) + CI->setCallingConv(Fn->getCallingConv()); + return CI; +} + +Value *llvm::emitFPutSUnlocked(Value *Str, Value *File, IRBuilder<> &B, + const TargetLibraryInfo *TLI) { + if (!TLI->has(LibFunc_fputs_unlocked)) + return nullptr; + + Module *M = B.GetInsertBlock()->getModule(); + StringRef FPutsUnlockedName = TLI->getName(LibFunc_fputs_unlocked); + Constant *F = M->getOrInsertFunction(FPutsUnlockedName, B.getInt32Ty(), + B.getInt8PtrTy(), File->getType()); + if (File->getType()->isPointerTy()) + inferLibFuncAttributes(M, FPutsUnlockedName, *TLI); + CallInst *CI = B.CreateCall(F, {castToCStr(Str, B), File}, FPutsUnlockedName); if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts())) CI->setCallingConv(Fn->getCallingConv()); @@ -1004,7 +1090,7 @@ Value *llvm::emitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilder<> &B, DL.getIntPtrType(Context), DL.getIntPtrType(Context), File->getType()); if (File->getType()->isPointerTy()) - inferLibFuncAttributes(*M->getFunction(FWriteName), *TLI); + inferLibFuncAttributes(M, FWriteName, *TLI); CallInst *CI = B.CreateCall(F, {castToCStr(Ptr, B), Size, ConstantInt::get(DL.getIntPtrType(Context), 1), File}); @@ -1013,3 +1099,123 @@ Value *llvm::emitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilder<> &B, CI->setCallingConv(Fn->getCallingConv()); return CI; } + +Value *llvm::emitMalloc(Value *Num, IRBuilder<> &B, const DataLayout &DL, + const TargetLibraryInfo *TLI) { + if (!TLI->has(LibFunc_malloc)) + return nullptr; + + Module *M = B.GetInsertBlock()->getModule(); + StringRef MallocName = TLI->getName(LibFunc_malloc); + LLVMContext &Context = B.GetInsertBlock()->getContext(); + Value *Malloc = M->getOrInsertFunction(MallocName, B.getInt8PtrTy(), + DL.getIntPtrType(Context)); + inferLibFuncAttributes(M, MallocName, *TLI); + CallInst *CI = B.CreateCall(Malloc, Num, MallocName); + + if (const Function *F = dyn_cast<Function>(Malloc->stripPointerCasts())) + CI->setCallingConv(F->getCallingConv()); + + return CI; +} + +Value *llvm::emitCalloc(Value *Num, Value *Size, const AttributeList &Attrs, + IRBuilder<> &B, const TargetLibraryInfo &TLI) { + if (!TLI.has(LibFunc_calloc)) + return nullptr; + + Module *M = B.GetInsertBlock()->getModule(); + StringRef CallocName = TLI.getName(LibFunc_calloc); + const DataLayout &DL = M->getDataLayout(); + IntegerType *PtrType = DL.getIntPtrType((B.GetInsertBlock()->getContext())); + Value *Calloc = M->getOrInsertFunction(CallocName, Attrs, B.getInt8PtrTy(), + PtrType, PtrType); + inferLibFuncAttributes(M, CallocName, TLI); + CallInst *CI = B.CreateCall(Calloc, {Num, Size}, CallocName); + + if (const auto *F = dyn_cast<Function>(Calloc->stripPointerCasts())) + CI->setCallingConv(F->getCallingConv()); + + return CI; +} + +Value *llvm::emitFWriteUnlocked(Value *Ptr, Value *Size, Value *N, Value *File, + IRBuilder<> &B, const DataLayout &DL, + const TargetLibraryInfo *TLI) { + if (!TLI->has(LibFunc_fwrite_unlocked)) + return nullptr; + + Module *M = B.GetInsertBlock()->getModule(); + LLVMContext &Context = B.GetInsertBlock()->getContext(); + StringRef FWriteUnlockedName = TLI->getName(LibFunc_fwrite_unlocked); + Constant *F = M->getOrInsertFunction( + FWriteUnlockedName, DL.getIntPtrType(Context), B.getInt8PtrTy(), + DL.getIntPtrType(Context), DL.getIntPtrType(Context), File->getType()); + + if (File->getType()->isPointerTy()) + inferLibFuncAttributes(M, FWriteUnlockedName, *TLI); + CallInst *CI = B.CreateCall(F, {castToCStr(Ptr, B), Size, N, File}); + + if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts())) + CI->setCallingConv(Fn->getCallingConv()); + return CI; +} + +Value *llvm::emitFGetCUnlocked(Value *File, IRBuilder<> &B, + const TargetLibraryInfo *TLI) { + if (!TLI->has(LibFunc_fgetc_unlocked)) + return nullptr; + + Module *M = B.GetInsertBlock()->getModule(); + StringRef FGetCUnlockedName = TLI->getName(LibFunc_fgetc_unlocked); + Constant *F = + M->getOrInsertFunction(FGetCUnlockedName, B.getInt32Ty(), File->getType()); + if (File->getType()->isPointerTy()) + inferLibFuncAttributes(M, FGetCUnlockedName, *TLI); + CallInst *CI = B.CreateCall(F, File, FGetCUnlockedName); + + if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts())) + CI->setCallingConv(Fn->getCallingConv()); + return CI; +} + +Value *llvm::emitFGetSUnlocked(Value *Str, Value *Size, Value *File, + IRBuilder<> &B, const TargetLibraryInfo *TLI) { + if (!TLI->has(LibFunc_fgets_unlocked)) + return nullptr; + + Module *M = B.GetInsertBlock()->getModule(); + StringRef FGetSUnlockedName = TLI->getName(LibFunc_fgets_unlocked); + Constant *F = + M->getOrInsertFunction(FGetSUnlockedName, B.getInt8PtrTy(), + B.getInt8PtrTy(), B.getInt32Ty(), File->getType()); + inferLibFuncAttributes(M, FGetSUnlockedName, *TLI); + CallInst *CI = + B.CreateCall(F, {castToCStr(Str, B), Size, File}, FGetSUnlockedName); + + if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts())) + CI->setCallingConv(Fn->getCallingConv()); + return CI; +} + +Value *llvm::emitFReadUnlocked(Value *Ptr, Value *Size, Value *N, Value *File, + IRBuilder<> &B, const DataLayout &DL, + const TargetLibraryInfo *TLI) { + if (!TLI->has(LibFunc_fread_unlocked)) + return nullptr; + + Module *M = B.GetInsertBlock()->getModule(); + LLVMContext &Context = B.GetInsertBlock()->getContext(); + StringRef FReadUnlockedName = TLI->getName(LibFunc_fread_unlocked); + Constant *F = M->getOrInsertFunction( + FReadUnlockedName, DL.getIntPtrType(Context), B.getInt8PtrTy(), + DL.getIntPtrType(Context), DL.getIntPtrType(Context), File->getType()); + + if (File->getType()->isPointerTy()) + inferLibFuncAttributes(M, FReadUnlockedName, *TLI); + CallInst *CI = B.CreateCall(F, {castToCStr(Ptr, B), Size, N, File}); + + if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts())) + CI->setCallingConv(Fn->getCallingConv()); + return CI; +} |
