summaryrefslogtreecommitdiffstats
path: root/gnu/llvm/lib/Transforms/Utils/BuildLibCalls.cpp
diff options
context:
space:
mode:
authorpatrick <patrick@openbsd.org>2019-01-27 16:42:12 +0000
committerpatrick <patrick@openbsd.org>2019-01-27 16:42:12 +0000
commitb773203fb58f3ef282fb69c832d8710cab5bc82d (patch)
treee75913f147570fbd75169647b144df85b88a038c /gnu/llvm/lib/Transforms/Utils/BuildLibCalls.cpp
parenttweak errno in previous (diff)
downloadwireguard-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.cpp274
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;
+}