diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2018-07-28 10:51:19 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2018-07-28 10:51:19 +0000 | 
| commit | eb11fae6d08f479c0799db45860a98af528fa6e7 (patch) | |
| tree | 44d492a50c8c1a7eb8e2d17ea3360ec4d066f042 /lib/Transforms/Utils/BuildLibCalls.cpp | |
| parent | b8a2042aa938069e862750553db0e4d82d25822c (diff) | |
Notes
Diffstat (limited to 'lib/Transforms/Utils/BuildLibCalls.cpp')
| -rw-r--r-- | lib/Transforms/Utils/BuildLibCalls.cpp | 191 | 
1 files changed, 188 insertions, 3 deletions
| diff --git a/lib/Transforms/Utils/BuildLibCalls.cpp b/lib/Transforms/Utils/BuildLibCalls.cpp index b60dfb4f3541..5f5c4150d3bb 100644 --- a/lib/Transforms/Utils/BuildLibCalls.cpp +++ b/lib/Transforms/Utils/BuildLibCalls.cpp @@ -105,12 +105,23 @@ 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(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 +386,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 +405,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 +415,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 +464,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 +503,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 +524,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 +707,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 +729,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) { @@ -973,6 +1006,24 @@ Value *llvm::emitFPutC(Value *Char, Value *File, IRBuilder<> &B,    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(); +  Constant *F = M->getOrInsertFunction("fputc_unlocked", B.getInt32Ty(), +                                       B.getInt32Ty(), File->getType()); +  if (File->getType()->isPointerTy()) +    inferLibFuncAttributes(*M->getFunction("fputc_unlocked"), *TLI); +  Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/ true, "chari"); +  CallInst *CI = B.CreateCall(F, {Char, File}, "fputc_unlocked"); + +  if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts())) +    CI->setCallingConv(Fn->getCallingConv()); +  return CI; +} +  Value *llvm::emitFPutS(Value *Str, Value *File, IRBuilder<> &B,                         const TargetLibraryInfo *TLI) {    if (!TLI->has(LibFunc_fputs)) @@ -991,6 +1042,24 @@ Value *llvm::emitFPutS(Value *Str, Value *File, IRBuilder<> &B,    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->getFunction(FPutsUnlockedName), *TLI); +  CallInst *CI = B.CreateCall(F, {castToCStr(Str, B), File}, "fputs_unlocked"); + +  if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts())) +    CI->setCallingConv(Fn->getCallingConv()); +  return CI; +} +  Value *llvm::emitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilder<> &B,                          const DataLayout &DL, const TargetLibraryInfo *TLI) {    if (!TLI->has(LibFunc_fwrite)) @@ -1013,3 +1082,119 @@ 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(); +  LLVMContext &Context = B.GetInsertBlock()->getContext(); +  Value *Malloc = M->getOrInsertFunction("malloc", B.getInt8PtrTy(), +                                         DL.getIntPtrType(Context)); +  inferLibFuncAttributes(*M->getFunction("malloc"), *TLI); +  CallInst *CI = B.CreateCall(Malloc, Num, "malloc"); + +  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(); +  const DataLayout &DL = M->getDataLayout(); +  IntegerType *PtrType = DL.getIntPtrType((B.GetInsertBlock()->getContext())); +  Value *Calloc = M->getOrInsertFunction("calloc", Attrs, B.getInt8PtrTy(), +                                         PtrType, PtrType); +  inferLibFuncAttributes(*M->getFunction("calloc"), TLI); +  CallInst *CI = B.CreateCall(Calloc, {Num, Size}, "calloc"); + +  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->getFunction(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(); +  Constant *F = +      M->getOrInsertFunction("fgetc_unlocked", B.getInt32Ty(), File->getType()); +  if (File->getType()->isPointerTy()) +    inferLibFuncAttributes(*M->getFunction("fgetc_unlocked"), *TLI); +  CallInst *CI = B.CreateCall(F, File, "fgetc_unlocked"); + +  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(); +  Constant *F = +      M->getOrInsertFunction("fgets_unlocked", B.getInt8PtrTy(), +                             B.getInt8PtrTy(), B.getInt32Ty(), File->getType()); +  inferLibFuncAttributes(*M->getFunction("fgets_unlocked"), *TLI); +  CallInst *CI = +      B.CreateCall(F, {castToCStr(Str, B), Size, File}, "fgets_unlocked"); + +  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->getFunction(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; +} | 
