diff options
Diffstat (limited to 'contrib/llvm/lib/Transforms/Utils/BuildLibCalls.cpp')
| -rw-r--r-- | contrib/llvm/lib/Transforms/Utils/BuildLibCalls.cpp | 1340 |
1 files changed, 0 insertions, 1340 deletions
diff --git a/contrib/llvm/lib/Transforms/Utils/BuildLibCalls.cpp b/contrib/llvm/lib/Transforms/Utils/BuildLibCalls.cpp deleted file mode 100644 index 27f110e24f9c..000000000000 --- a/contrib/llvm/lib/Transforms/Utils/BuildLibCalls.cpp +++ /dev/null @@ -1,1340 +0,0 @@ -//===- BuildLibCalls.cpp - Utility builder for libcalls -------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file implements some functions that will create standard C libcalls. -// -//===----------------------------------------------------------------------===// - -#include "llvm/Transforms/Utils/BuildLibCalls.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/ADT/Statistic.h" -#include "llvm/Analysis/TargetLibraryInfo.h" -#include "llvm/IR/Constants.h" -#include "llvm/IR/DataLayout.h" -#include "llvm/IR/Function.h" -#include "llvm/IR/IRBuilder.h" -#include "llvm/IR/Intrinsics.h" -#include "llvm/IR/LLVMContext.h" -#include "llvm/IR/Module.h" -#include "llvm/IR/Type.h" -#include "llvm/Analysis/MemoryBuiltins.h" - -using namespace llvm; - -#define DEBUG_TYPE "build-libcalls" - -//- Infer Attributes ---------------------------------------------------------// - -STATISTIC(NumReadNone, "Number of functions inferred as readnone"); -STATISTIC(NumReadOnly, "Number of functions inferred as readonly"); -STATISTIC(NumArgMemOnly, "Number of functions inferred as argmemonly"); -STATISTIC(NumNoUnwind, "Number of functions inferred as nounwind"); -STATISTIC(NumNoCapture, "Number of arguments inferred as nocapture"); -STATISTIC(NumReadOnlyArg, "Number of arguments inferred as readonly"); -STATISTIC(NumNoAlias, "Number of function returns inferred as noalias"); -STATISTIC(NumNonNull, "Number of function returns inferred as nonnull returns"); -STATISTIC(NumReturnedArg, "Number of arguments inferred as returned"); - -static bool setDoesNotAccessMemory(Function &F) { - if (F.doesNotAccessMemory()) - return false; - F.setDoesNotAccessMemory(); - ++NumReadNone; - return true; -} - -static bool setOnlyReadsMemory(Function &F) { - if (F.onlyReadsMemory()) - return false; - F.setOnlyReadsMemory(); - ++NumReadOnly; - return true; -} - -static bool setOnlyAccessesArgMemory(Function &F) { - if (F.onlyAccessesArgMemory()) - return false; - F.setOnlyAccessesArgMemory(); - ++NumArgMemOnly; - return true; -} - -static bool setDoesNotThrow(Function &F) { - if (F.doesNotThrow()) - return false; - F.setDoesNotThrow(); - ++NumNoUnwind; - return true; -} - -static bool setRetDoesNotAlias(Function &F) { - if (F.hasAttribute(AttributeList::ReturnIndex, Attribute::NoAlias)) - return false; - F.addAttribute(AttributeList::ReturnIndex, Attribute::NoAlias); - ++NumNoAlias; - return true; -} - -static bool setDoesNotCapture(Function &F, unsigned ArgNo) { - if (F.hasParamAttribute(ArgNo, Attribute::NoCapture)) - return false; - F.addParamAttr(ArgNo, Attribute::NoCapture); - ++NumNoCapture; - return true; -} - -static bool setOnlyReadsMemory(Function &F, unsigned ArgNo) { - if (F.hasParamAttribute(ArgNo, Attribute::ReadOnly)) - return false; - F.addParamAttr(ArgNo, Attribute::ReadOnly); - ++NumReadOnlyArg; - return true; -} - -static bool setRetNonNull(Function &F) { - assert(F.getReturnType()->isPointerTy() && - "nonnull applies only to pointers"); - if (F.hasAttribute(AttributeList::ReturnIndex, Attribute::NonNull)) - return false; - F.addAttribute(AttributeList::ReturnIndex, Attribute::NonNull); - ++NumNonNull; - return true; -} - -static bool setReturnedArg(Function &F, unsigned ArgNo) { - if (F.hasParamAttribute(ArgNo, Attribute::Returned)) - return false; - F.addParamAttr(ArgNo, Attribute::Returned); - ++NumReturnedArg; - return true; -} - -static bool setNonLazyBind(Function &F) { - if (F.hasFnAttribute(Attribute::NonLazyBind)) - return false; - F.addFnAttr(Attribute::NonLazyBind); - return true; -} - -static bool setDoesNotFreeMemory(Function &F) { - if (F.hasFnAttribute(Attribute::NoFree)) - return false; - F.addFnAttr(Attribute::NoFree); - 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(!isLibFreeFunction(&F, TheLibFunc) && !isReallocLikeFn(&F, &TLI)) - Changed |= setDoesNotFreeMemory(F); - - if (F.getParent() != nullptr && F.getParent()->getRtLibUseGOT()) - Changed |= setNonLazyBind(F); - - switch (TheLibFunc) { - case LibFunc_strlen: - case LibFunc_wcslen: - Changed |= setOnlyReadsMemory(F); - Changed |= setDoesNotThrow(F); - Changed |= setOnlyAccessesArgMemory(F); - Changed |= setDoesNotCapture(F, 0); - return Changed; - case LibFunc_strchr: - case LibFunc_strrchr: - Changed |= setOnlyReadsMemory(F); - Changed |= setDoesNotThrow(F); - return Changed; - case LibFunc_strtol: - case LibFunc_strtod: - case LibFunc_strtof: - case LibFunc_strtoul: - case LibFunc_strtoll: - case LibFunc_strtold: - case LibFunc_strtoull: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 0); - return Changed; - case LibFunc_strcpy: - case LibFunc_strncpy: - case LibFunc_strcat: - case LibFunc_strncat: - Changed |= setReturnedArg(F, 0); - LLVM_FALLTHROUGH; - case LibFunc_stpcpy: - case LibFunc_stpncpy: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; - case LibFunc_strxfrm: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 0); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; - case LibFunc_strcmp: // 0,1 - case LibFunc_strspn: // 0,1 - case LibFunc_strncmp: // 0,1 - case LibFunc_strcspn: // 0,1 - case LibFunc_strcoll: // 0,1 - case LibFunc_strcasecmp: // 0,1 - case LibFunc_strncasecmp: // - Changed |= setOnlyReadsMemory(F); - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 0); - Changed |= setDoesNotCapture(F, 1); - return Changed; - case LibFunc_strstr: - case LibFunc_strpbrk: - Changed |= setOnlyReadsMemory(F); - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - return Changed; - case LibFunc_strtok: - case LibFunc_strtok_r: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; - case LibFunc_scanf: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 0); - Changed |= setOnlyReadsMemory(F, 0); - return Changed; - case LibFunc_setbuf: - case LibFunc_setvbuf: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 0); - return Changed; - case LibFunc_strdup: - case LibFunc_strndup: - Changed |= setDoesNotThrow(F); - Changed |= setRetDoesNotAlias(F); - Changed |= setDoesNotCapture(F, 0); - Changed |= setOnlyReadsMemory(F, 0); - return Changed; - case LibFunc_stat: - case LibFunc_statvfs: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 0); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 0); - return Changed; - case LibFunc_sscanf: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 0); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 0); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; - case LibFunc_sprintf: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 0); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; - case LibFunc_snprintf: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 0); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 2); - return Changed; - case LibFunc_setitimer: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; - case LibFunc_system: - // May throw; "system" is a valid pthread cancellation point. - Changed |= setDoesNotCapture(F, 0); - Changed |= setOnlyReadsMemory(F, 0); - return Changed; - case LibFunc_malloc: - Changed |= setDoesNotThrow(F); - Changed |= setRetDoesNotAlias(F); - return Changed; - case LibFunc_memcmp: - Changed |= setOnlyReadsMemory(F); - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 0); - Changed |= setDoesNotCapture(F, 1); - return Changed; - case LibFunc_memchr: - case LibFunc_memrchr: - Changed |= setOnlyReadsMemory(F); - Changed |= setDoesNotThrow(F); - return Changed; - case LibFunc_modf: - case LibFunc_modff: - case LibFunc_modfl: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - return Changed; - case LibFunc_memcpy: - case LibFunc_memmove: - Changed |= setReturnedArg(F, 0); - LLVM_FALLTHROUGH; - case LibFunc_mempcpy: - case LibFunc_memccpy: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; - case LibFunc_memcpy_chk: - Changed |= setDoesNotThrow(F); - return Changed; - case LibFunc_memalign: - Changed |= setRetDoesNotAlias(F); - return Changed; - case LibFunc_mkdir: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 0); - Changed |= setOnlyReadsMemory(F, 0); - return Changed; - case LibFunc_mktime: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 0); - return Changed; - case LibFunc_realloc: - Changed |= setDoesNotThrow(F); - Changed |= setRetDoesNotAlias(F); - Changed |= setDoesNotCapture(F, 0); - return Changed; - case LibFunc_read: - // May throw; "read" is a valid pthread cancellation point. - Changed |= setDoesNotCapture(F, 1); - return Changed; - case LibFunc_rewind: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 0); - return Changed; - case LibFunc_rmdir: - case LibFunc_remove: - case LibFunc_realpath: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 0); - Changed |= setOnlyReadsMemory(F, 0); - return Changed; - case LibFunc_rename: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 0); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 0); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; - case LibFunc_readlink: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 0); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 0); - return Changed; - case LibFunc_write: - // May throw; "write" is a valid pthread cancellation point. - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; - case LibFunc_bcopy: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 0); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 0); - return Changed; - case LibFunc_bcmp: - Changed |= setDoesNotThrow(F); - Changed |= setOnlyReadsMemory(F); - Changed |= setDoesNotCapture(F, 0); - Changed |= setDoesNotCapture(F, 1); - return Changed; - case LibFunc_bzero: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 0); - return Changed; - case LibFunc_calloc: - Changed |= setDoesNotThrow(F); - Changed |= setRetDoesNotAlias(F); - return Changed; - case LibFunc_chmod: - case LibFunc_chown: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 0); - Changed |= setOnlyReadsMemory(F, 0); - return Changed; - case LibFunc_ctermid: - case LibFunc_clearerr: - case LibFunc_closedir: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 0); - return Changed; - case LibFunc_atoi: - case LibFunc_atol: - case LibFunc_atof: - case LibFunc_atoll: - Changed |= setDoesNotThrow(F); - Changed |= setOnlyReadsMemory(F); - Changed |= setDoesNotCapture(F, 0); - return Changed; - case LibFunc_access: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 0); - Changed |= setOnlyReadsMemory(F, 0); - return Changed; - case LibFunc_fopen: - Changed |= setDoesNotThrow(F); - Changed |= setRetDoesNotAlias(F); - Changed |= setDoesNotCapture(F, 0); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 0); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; - case LibFunc_fdopen: - Changed |= setDoesNotThrow(F); - Changed |= setRetDoesNotAlias(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; - case LibFunc_feof: - case LibFunc_free: - case LibFunc_fseek: - case LibFunc_ftell: - case LibFunc_fgetc: - case LibFunc_fgetc_unlocked: - case LibFunc_fseeko: - case LibFunc_ftello: - case LibFunc_fileno: - case LibFunc_fflush: - case LibFunc_fclose: - case LibFunc_fsetpos: - case LibFunc_flockfile: - case LibFunc_funlockfile: - case LibFunc_ftrylockfile: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 0); - return Changed; - case LibFunc_ferror: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 0); - Changed |= setOnlyReadsMemory(F); - return Changed; - case LibFunc_fputc: - case LibFunc_fputc_unlocked: - case LibFunc_fstat: - case LibFunc_frexp: - case LibFunc_frexpf: - case LibFunc_frexpl: - case LibFunc_fstatvfs: - Changed |= setDoesNotThrow(F); - 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); - Changed |= setOnlyReadsMemory(F, 0); - return Changed; - case LibFunc_fscanf: - case LibFunc_fprintf: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 0); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; - case LibFunc_fgetpos: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 0); - Changed |= setDoesNotCapture(F, 1); - return Changed; - case LibFunc_getc: - case LibFunc_getlogin_r: - case LibFunc_getc_unlocked: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 0); - return Changed; - case LibFunc_getenv: - Changed |= setDoesNotThrow(F); - Changed |= setOnlyReadsMemory(F); - Changed |= setDoesNotCapture(F, 0); - return Changed; - case LibFunc_gets: - case LibFunc_getchar: - case LibFunc_getchar_unlocked: - Changed |= setDoesNotThrow(F); - return Changed; - case LibFunc_getitimer: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - return Changed; - case LibFunc_getpwnam: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 0); - Changed |= setOnlyReadsMemory(F, 0); - return Changed; - case LibFunc_ungetc: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - return Changed; - case LibFunc_uname: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 0); - return Changed; - case LibFunc_unlink: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 0); - Changed |= setOnlyReadsMemory(F, 0); - return Changed; - case LibFunc_unsetenv: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 0); - Changed |= setOnlyReadsMemory(F, 0); - return Changed; - case LibFunc_utime: - case LibFunc_utimes: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 0); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 0); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; - case LibFunc_putc: - case LibFunc_putc_unlocked: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - return Changed; - case LibFunc_puts: - case LibFunc_printf: - case LibFunc_perror: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 0); - Changed |= setOnlyReadsMemory(F, 0); - return Changed; - case LibFunc_pread: - // May throw; "pread" is a valid pthread cancellation point. - Changed |= setDoesNotCapture(F, 1); - return Changed; - case LibFunc_pwrite: - // May throw; "pwrite" is a valid pthread cancellation point. - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; - case LibFunc_putchar: - case LibFunc_putchar_unlocked: - Changed |= setDoesNotThrow(F); - return Changed; - case LibFunc_popen: - Changed |= setDoesNotThrow(F); - Changed |= setRetDoesNotAlias(F); - Changed |= setDoesNotCapture(F, 0); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 0); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; - case LibFunc_pclose: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 0); - return Changed; - case LibFunc_vscanf: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 0); - Changed |= setOnlyReadsMemory(F, 0); - return Changed; - case LibFunc_vsscanf: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 0); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 0); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; - case LibFunc_vfscanf: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 0); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; - case LibFunc_valloc: - Changed |= setDoesNotThrow(F); - Changed |= setRetDoesNotAlias(F); - return Changed; - case LibFunc_vprintf: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 0); - Changed |= setOnlyReadsMemory(F, 0); - return Changed; - case LibFunc_vfprintf: - case LibFunc_vsprintf: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 0); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; - case LibFunc_vsnprintf: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 0); - Changed |= setDoesNotCapture(F, 2); - Changed |= setOnlyReadsMemory(F, 2); - return Changed; - case LibFunc_open: - // May throw; "open" is a valid pthread cancellation point. - Changed |= setDoesNotCapture(F, 0); - Changed |= setOnlyReadsMemory(F, 0); - return Changed; - case LibFunc_opendir: - Changed |= setDoesNotThrow(F); - Changed |= setRetDoesNotAlias(F); - Changed |= setDoesNotCapture(F, 0); - Changed |= setOnlyReadsMemory(F, 0); - return Changed; - case LibFunc_tmpfile: - Changed |= setDoesNotThrow(F); - Changed |= setRetDoesNotAlias(F); - return Changed; - case LibFunc_times: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 0); - return Changed; - case LibFunc_htonl: - case LibFunc_htons: - case LibFunc_ntohl: - case LibFunc_ntohs: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotAccessMemory(F); - return Changed; - case LibFunc_lstat: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 0); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 0); - return Changed; - case LibFunc_lchown: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 0); - Changed |= setOnlyReadsMemory(F, 0); - return Changed; - case LibFunc_qsort: - // May throw; places call through function pointer. - Changed |= setDoesNotCapture(F, 3); - return Changed; - case LibFunc_dunder_strdup: - case LibFunc_dunder_strndup: - Changed |= setDoesNotThrow(F); - Changed |= setRetDoesNotAlias(F); - Changed |= setDoesNotCapture(F, 0); - Changed |= setOnlyReadsMemory(F, 0); - return Changed; - case LibFunc_dunder_strtok_r: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; - case LibFunc_under_IO_getc: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 0); - return Changed; - case LibFunc_under_IO_putc: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - return Changed; - case LibFunc_dunder_isoc99_scanf: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 0); - Changed |= setOnlyReadsMemory(F, 0); - return Changed; - case LibFunc_stat64: - case LibFunc_lstat64: - case LibFunc_statvfs64: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 0); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 0); - return Changed; - case LibFunc_dunder_isoc99_sscanf: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 0); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 0); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; - case LibFunc_fopen64: - Changed |= setDoesNotThrow(F); - Changed |= setRetDoesNotAlias(F); - Changed |= setDoesNotCapture(F, 0); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 0); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; - case LibFunc_fseeko64: - case LibFunc_ftello64: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 0); - return Changed; - case LibFunc_tmpfile64: - Changed |= setDoesNotThrow(F); - Changed |= setRetDoesNotAlias(F); - return Changed; - case LibFunc_fstat64: - case LibFunc_fstatvfs64: - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 1); - return Changed; - case LibFunc_open64: - // May throw; "open" is a valid pthread cancellation point. - Changed |= setDoesNotCapture(F, 0); - Changed |= setOnlyReadsMemory(F, 0); - return Changed; - case LibFunc_gettimeofday: - // Currently some platforms have the restrict keyword on the arguments to - // gettimeofday. To be conservative, do not add noalias to gettimeofday's - // arguments. - Changed |= setDoesNotThrow(F); - Changed |= setDoesNotCapture(F, 0); - Changed |= setDoesNotCapture(F, 1); - return Changed; - case LibFunc_Znwj: // new(unsigned int) - case LibFunc_Znwm: // new(unsigned long) - case LibFunc_Znaj: // new[](unsigned int) - case LibFunc_Znam: // new[](unsigned long) - case LibFunc_msvc_new_int: // new(unsigned int) - case LibFunc_msvc_new_longlong: // new(unsigned long long) - case LibFunc_msvc_new_array_int: // new[](unsigned int) - case LibFunc_msvc_new_array_longlong: // new[](unsigned long long) - // Operator new always returns a nonnull noalias pointer - Changed |= setRetNonNull(F); - Changed |= setRetDoesNotAlias(F); - return Changed; - // TODO: add LibFunc entries for: - // case LibFunc_memset_pattern4: - // case LibFunc_memset_pattern8: - case LibFunc_memset_pattern16: - Changed |= setOnlyAccessesArgMemory(F); - Changed |= setDoesNotCapture(F, 0); - Changed |= setDoesNotCapture(F, 1); - Changed |= setOnlyReadsMemory(F, 1); - return Changed; - // int __nvvm_reflect(const char *) - case LibFunc_nvvm_reflect: - Changed |= setDoesNotAccessMemory(F); - Changed |= setDoesNotThrow(F); - return Changed; - - default: - // FIXME: It'd be really nice to cover all the library functions we're - // aware of here. - return false; - } -} - -bool llvm::hasUnaryFloatFn(const TargetLibraryInfo *TLI, Type *Ty, - LibFunc DoubleFn, LibFunc FloatFn, - LibFunc LongDoubleFn) { - switch (Ty->getTypeID()) { - case Type::HalfTyID: - return false; - case Type::FloatTyID: - return TLI->has(FloatFn); - case Type::DoubleTyID: - return TLI->has(DoubleFn); - default: - return TLI->has(LongDoubleFn); - } -} - -StringRef llvm::getUnaryFloatFn(const TargetLibraryInfo *TLI, Type *Ty, - LibFunc DoubleFn, LibFunc FloatFn, - LibFunc LongDoubleFn) { - assert(hasUnaryFloatFn(TLI, Ty, DoubleFn, FloatFn, LongDoubleFn) && - "Cannot get name for unavailable function!"); - - switch (Ty->getTypeID()) { - case Type::HalfTyID: - llvm_unreachable("No name for HalfTy!"); - case Type::FloatTyID: - return TLI->getName(FloatFn); - case Type::DoubleTyID: - return TLI->getName(DoubleFn); - default: - return TLI->getName(LongDoubleFn); - } -} - -//- Emit LibCalls ------------------------------------------------------------// - -Value *llvm::castToCStr(Value *V, IRBuilder<> &B) { - unsigned AS = V->getType()->getPointerAddressSpace(); - return B.CreateBitCast(V, B.getInt8PtrTy(AS), "cstr"); -} - -static Value *emitLibCall(LibFunc TheLibFunc, Type *ReturnType, - ArrayRef<Type *> ParamTypes, - ArrayRef<Value *> Operands, IRBuilder<> &B, - const TargetLibraryInfo *TLI, - bool IsVaArgs = false) { - if (!TLI->has(TheLibFunc)) - return nullptr; - - Module *M = B.GetInsertBlock()->getModule(); - StringRef FuncName = TLI->getName(TheLibFunc); - FunctionType *FuncType = FunctionType::get(ReturnType, ParamTypes, IsVaArgs); - FunctionCallee Callee = M->getOrInsertFunction(FuncName, FuncType); - inferLibFuncAttributes(M, FuncName, *TLI); - CallInst *CI = B.CreateCall(Callee, Operands, FuncName); - if (const Function *F = - dyn_cast<Function>(Callee.getCallee()->stripPointerCasts())) - CI->setCallingConv(F->getCallingConv()); - return CI; -} - -Value *llvm::emitStrLen(Value *Ptr, IRBuilder<> &B, const DataLayout &DL, - const TargetLibraryInfo *TLI) { - LLVMContext &Context = B.GetInsertBlock()->getContext(); - return emitLibCall(LibFunc_strlen, DL.getIntPtrType(Context), - B.getInt8PtrTy(), castToCStr(Ptr, B), B, TLI); -} - -Value *llvm::emitStrChr(Value *Ptr, char C, IRBuilder<> &B, - const TargetLibraryInfo *TLI) { - Type *I8Ptr = B.getInt8PtrTy(); - Type *I32Ty = B.getInt32Ty(); - return emitLibCall(LibFunc_strchr, I8Ptr, {I8Ptr, I32Ty}, - {castToCStr(Ptr, B), ConstantInt::get(I32Ty, C)}, B, TLI); -} - -Value *llvm::emitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B, - const DataLayout &DL, const TargetLibraryInfo *TLI) { - LLVMContext &Context = B.GetInsertBlock()->getContext(); - return emitLibCall( - LibFunc_strncmp, B.getInt32Ty(), - {B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context)}, - {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, B, TLI); -} - -Value *llvm::emitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B, - const TargetLibraryInfo *TLI) { - Type *I8Ptr = B.getInt8PtrTy(); - return emitLibCall(LibFunc_strcpy, I8Ptr, {I8Ptr, I8Ptr}, - {castToCStr(Dst, B), castToCStr(Src, B)}, B, TLI); -} - -Value *llvm::emitStpCpy(Value *Dst, Value *Src, IRBuilder<> &B, - const TargetLibraryInfo *TLI) { - Type *I8Ptr = B.getInt8PtrTy(); - return emitLibCall(LibFunc_stpcpy, I8Ptr, {I8Ptr, I8Ptr}, - {castToCStr(Dst, B), castToCStr(Src, B)}, B, TLI); -} - -Value *llvm::emitStrNCpy(Value *Dst, Value *Src, Value *Len, IRBuilder<> &B, - const TargetLibraryInfo *TLI) { - Type *I8Ptr = B.getInt8PtrTy(); - return emitLibCall(LibFunc_strncpy, I8Ptr, {I8Ptr, I8Ptr, Len->getType()}, - {castToCStr(Dst, B), castToCStr(Src, B), Len}, B, TLI); -} - -Value *llvm::emitStpNCpy(Value *Dst, Value *Src, Value *Len, IRBuilder<> &B, - const TargetLibraryInfo *TLI) { - Type *I8Ptr = B.getInt8PtrTy(); - return emitLibCall(LibFunc_stpncpy, I8Ptr, {I8Ptr, I8Ptr, Len->getType()}, - {castToCStr(Dst, B), castToCStr(Src, B), Len}, B, TLI); -} - -Value *llvm::emitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize, - IRBuilder<> &B, const DataLayout &DL, - const TargetLibraryInfo *TLI) { - if (!TLI->has(LibFunc_memcpy_chk)) - return nullptr; - - Module *M = B.GetInsertBlock()->getModule(); - AttributeList AS; - AS = AttributeList::get(M->getContext(), AttributeList::FunctionIndex, - Attribute::NoUnwind); - LLVMContext &Context = B.GetInsertBlock()->getContext(); - FunctionCallee MemCpy = M->getOrInsertFunction( - "__memcpy_chk", AttributeList::get(M->getContext(), AS), B.getInt8PtrTy(), - B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context), - DL.getIntPtrType(Context)); - Dst = castToCStr(Dst, B); - Src = castToCStr(Src, B); - CallInst *CI = B.CreateCall(MemCpy, {Dst, Src, Len, ObjSize}); - if (const Function *F = - dyn_cast<Function>(MemCpy.getCallee()->stripPointerCasts())) - CI->setCallingConv(F->getCallingConv()); - return CI; -} - -Value *llvm::emitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilder<> &B, - const DataLayout &DL, const TargetLibraryInfo *TLI) { - LLVMContext &Context = B.GetInsertBlock()->getContext(); - return emitLibCall( - LibFunc_memchr, B.getInt8PtrTy(), - {B.getInt8PtrTy(), B.getInt32Ty(), DL.getIntPtrType(Context)}, - {castToCStr(Ptr, B), Val, Len}, B, TLI); -} - -Value *llvm::emitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B, - const DataLayout &DL, const TargetLibraryInfo *TLI) { - LLVMContext &Context = B.GetInsertBlock()->getContext(); - return emitLibCall( - LibFunc_memcmp, B.getInt32Ty(), - {B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context)}, - {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, B, TLI); -} - -Value *llvm::emitBCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B, - const DataLayout &DL, const TargetLibraryInfo *TLI) { - LLVMContext &Context = B.GetInsertBlock()->getContext(); - return emitLibCall( - LibFunc_bcmp, B.getInt32Ty(), - {B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context)}, - {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, B, TLI); -} - -Value *llvm::emitMemCCpy(Value *Ptr1, Value *Ptr2, Value *Val, Value *Len, - IRBuilder<> &B, const TargetLibraryInfo *TLI) { - return emitLibCall( - LibFunc_memccpy, B.getInt8PtrTy(), - {B.getInt8PtrTy(), B.getInt8PtrTy(), B.getInt32Ty(), Len->getType()}, - {Ptr1, Ptr2, Val, Len}, B, TLI); -} - -Value *llvm::emitSNPrintf(Value *Dest, Value *Size, Value *Fmt, - ArrayRef<Value *> VariadicArgs, IRBuilder<> &B, - const TargetLibraryInfo *TLI) { - SmallVector<Value *, 8> Args{castToCStr(Dest, B), Size, castToCStr(Fmt, B)}; - Args.insert(Args.end(), VariadicArgs.begin(), VariadicArgs.end()); - return emitLibCall(LibFunc_snprintf, B.getInt32Ty(), - {B.getInt8PtrTy(), Size->getType(), B.getInt8PtrTy()}, - Args, B, TLI, /*IsVaArgs=*/true); -} - -Value *llvm::emitSPrintf(Value *Dest, Value *Fmt, - ArrayRef<Value *> VariadicArgs, IRBuilder<> &B, - const TargetLibraryInfo *TLI) { - SmallVector<Value *, 8> Args{castToCStr(Dest, B), castToCStr(Fmt, B)}; - Args.insert(Args.end(), VariadicArgs.begin(), VariadicArgs.end()); - return emitLibCall(LibFunc_sprintf, B.getInt32Ty(), - {B.getInt8PtrTy(), B.getInt8PtrTy()}, Args, B, TLI, - /*IsVaArgs=*/true); -} - -Value *llvm::emitStrCat(Value *Dest, Value *Src, IRBuilder<> &B, - const TargetLibraryInfo *TLI) { - return emitLibCall(LibFunc_strcat, B.getInt8PtrTy(), - {B.getInt8PtrTy(), B.getInt8PtrTy()}, - {castToCStr(Dest, B), castToCStr(Src, B)}, B, TLI); -} - -Value *llvm::emitStrLCpy(Value *Dest, Value *Src, Value *Size, IRBuilder<> &B, - const TargetLibraryInfo *TLI) { - return emitLibCall(LibFunc_strlcpy, Size->getType(), - {B.getInt8PtrTy(), B.getInt8PtrTy(), Size->getType()}, - {castToCStr(Dest, B), castToCStr(Src, B), Size}, B, TLI); -} - -Value *llvm::emitStrLCat(Value *Dest, Value *Src, Value *Size, IRBuilder<> &B, - const TargetLibraryInfo *TLI) { - return emitLibCall(LibFunc_strlcat, Size->getType(), - {B.getInt8PtrTy(), B.getInt8PtrTy(), Size->getType()}, - {castToCStr(Dest, B), castToCStr(Src, B), Size}, B, TLI); -} - -Value *llvm::emitStrNCat(Value *Dest, Value *Src, Value *Size, IRBuilder<> &B, - const TargetLibraryInfo *TLI) { - return emitLibCall(LibFunc_strncat, B.getInt8PtrTy(), - {B.getInt8PtrTy(), B.getInt8PtrTy(), Size->getType()}, - {castToCStr(Dest, B), castToCStr(Src, B), Size}, B, TLI); -} - -Value *llvm::emitVSNPrintf(Value *Dest, Value *Size, Value *Fmt, Value *VAList, - IRBuilder<> &B, const TargetLibraryInfo *TLI) { - return emitLibCall( - LibFunc_vsnprintf, B.getInt32Ty(), - {B.getInt8PtrTy(), Size->getType(), B.getInt8PtrTy(), VAList->getType()}, - {castToCStr(Dest, B), Size, castToCStr(Fmt, B), VAList}, B, TLI); -} - -Value *llvm::emitVSPrintf(Value *Dest, Value *Fmt, Value *VAList, - IRBuilder<> &B, const TargetLibraryInfo *TLI) { - return emitLibCall(LibFunc_vsprintf, B.getInt32Ty(), - {B.getInt8PtrTy(), B.getInt8PtrTy(), VAList->getType()}, - {castToCStr(Dest, B), castToCStr(Fmt, B), VAList}, B, TLI); -} - -/// Append a suffix to the function name according to the type of 'Op'. -static void appendTypeSuffix(Value *Op, StringRef &Name, - SmallString<20> &NameBuffer) { - if (!Op->getType()->isDoubleTy()) { - NameBuffer += Name; - - if (Op->getType()->isFloatTy()) - NameBuffer += 'f'; - else - NameBuffer += 'l'; - - Name = NameBuffer; - } -} - -static Value *emitUnaryFloatFnCallHelper(Value *Op, StringRef Name, - IRBuilder<> &B, - const AttributeList &Attrs) { - assert((Name != "") && "Must specify Name to emitUnaryFloatFnCall"); - - Module *M = B.GetInsertBlock()->getModule(); - FunctionCallee Callee = - M->getOrInsertFunction(Name, Op->getType(), Op->getType()); - CallInst *CI = B.CreateCall(Callee, Op, Name); - - // The incoming attribute set may have come from a speculatable intrinsic, but - // is being replaced with a library call which is not allowed to be - // speculatable. - CI->setAttributes(Attrs.removeAttribute(B.getContext(), - AttributeList::FunctionIndex, - Attribute::Speculatable)); - if (const Function *F = - dyn_cast<Function>(Callee.getCallee()->stripPointerCasts())) - CI->setCallingConv(F->getCallingConv()); - - return CI; -} - -Value *llvm::emitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B, - const AttributeList &Attrs) { - SmallString<20> NameBuffer; - appendTypeSuffix(Op, Name, NameBuffer); - - return emitUnaryFloatFnCallHelper(Op, Name, B, Attrs); -} - -Value *llvm::emitUnaryFloatFnCall(Value *Op, const TargetLibraryInfo *TLI, - LibFunc DoubleFn, LibFunc FloatFn, - LibFunc LongDoubleFn, IRBuilder<> &B, - const AttributeList &Attrs) { - // Get the name of the function according to TLI. - StringRef Name = getUnaryFloatFn(TLI, Op->getType(), - DoubleFn, FloatFn, LongDoubleFn); - - return emitUnaryFloatFnCallHelper(Op, Name, B, Attrs); -} - -Value *llvm::emitBinaryFloatFnCall(Value *Op1, Value *Op2, StringRef Name, - IRBuilder<> &B, const AttributeList &Attrs) { - assert((Name != "") && "Must specify Name to emitBinaryFloatFnCall"); - - SmallString<20> NameBuffer; - appendTypeSuffix(Op1, Name, NameBuffer); - - Module *M = B.GetInsertBlock()->getModule(); - FunctionCallee Callee = M->getOrInsertFunction( - Name, Op1->getType(), Op1->getType(), Op2->getType()); - CallInst *CI = B.CreateCall(Callee, {Op1, Op2}, Name); - CI->setAttributes(Attrs); - if (const Function *F = - dyn_cast<Function>(Callee.getCallee()->stripPointerCasts())) - CI->setCallingConv(F->getCallingConv()); - - return CI; -} - -Value *llvm::emitPutChar(Value *Char, IRBuilder<> &B, - const TargetLibraryInfo *TLI) { - if (!TLI->has(LibFunc_putchar)) - return nullptr; - - Module *M = B.GetInsertBlock()->getModule(); - StringRef PutCharName = TLI->getName(LibFunc_putchar); - FunctionCallee 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"), - PutCharName); - - if (const Function *F = - dyn_cast<Function>(PutChar.getCallee()->stripPointerCasts())) - CI->setCallingConv(F->getCallingConv()); - return CI; -} - -Value *llvm::emitPutS(Value *Str, IRBuilder<> &B, - const TargetLibraryInfo *TLI) { - if (!TLI->has(LibFunc_puts)) - return nullptr; - - Module *M = B.GetInsertBlock()->getModule(); - StringRef PutsName = TLI->getName(LibFunc_puts); - FunctionCallee 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.getCallee()->stripPointerCasts())) - CI->setCallingConv(F->getCallingConv()); - return CI; -} - -Value *llvm::emitFPutC(Value *Char, Value *File, IRBuilder<> &B, - const TargetLibraryInfo *TLI) { - if (!TLI->has(LibFunc_fputc)) - return nullptr; - - Module *M = B.GetInsertBlock()->getModule(); - StringRef FPutcName = TLI->getName(LibFunc_fputc); - FunctionCallee F = M->getOrInsertFunction(FPutcName, B.getInt32Ty(), - B.getInt32Ty(), File->getType()); - if (File->getType()->isPointerTy()) - inferLibFuncAttributes(M, FPutcName, *TLI); - Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/true, - "chari"); - CallInst *CI = B.CreateCall(F, {Char, File}, FPutcName); - - if (const Function *Fn = - dyn_cast<Function>(F.getCallee()->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); - FunctionCallee 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.getCallee()->stripPointerCasts())) - CI->setCallingConv(Fn->getCallingConv()); - return CI; -} - -Value *llvm::emitFPutS(Value *Str, Value *File, IRBuilder<> &B, - const TargetLibraryInfo *TLI) { - if (!TLI->has(LibFunc_fputs)) - return nullptr; - - Module *M = B.GetInsertBlock()->getModule(); - StringRef FPutsName = TLI->getName(LibFunc_fputs); - FunctionCallee F = M->getOrInsertFunction(FPutsName, B.getInt32Ty(), - B.getInt8PtrTy(), File->getType()); - if (File->getType()->isPointerTy()) - inferLibFuncAttributes(M, FPutsName, *TLI); - CallInst *CI = B.CreateCall(F, {castToCStr(Str, B), File}, FPutsName); - - if (const Function *Fn = - dyn_cast<Function>(F.getCallee()->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); - FunctionCallee 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.getCallee()->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)) - return nullptr; - - Module *M = B.GetInsertBlock()->getModule(); - LLVMContext &Context = B.GetInsertBlock()->getContext(); - StringRef FWriteName = TLI->getName(LibFunc_fwrite); - FunctionCallee F = M->getOrInsertFunction( - FWriteName, DL.getIntPtrType(Context), B.getInt8PtrTy(), - DL.getIntPtrType(Context), DL.getIntPtrType(Context), File->getType()); - - if (File->getType()->isPointerTy()) - inferLibFuncAttributes(M, FWriteName, *TLI); - CallInst *CI = - B.CreateCall(F, {castToCStr(Ptr, B), Size, - ConstantInt::get(DL.getIntPtrType(Context), 1), File}); - - if (const Function *Fn = - dyn_cast<Function>(F.getCallee()->stripPointerCasts())) - 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(); - FunctionCallee 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.getCallee()->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())); - FunctionCallee 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.getCallee()->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); - FunctionCallee 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.getCallee()->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); - FunctionCallee 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.getCallee()->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); - FunctionCallee 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.getCallee()->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); - FunctionCallee 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.getCallee()->stripPointerCasts())) - CI->setCallingConv(Fn->getCallingConv()); - return CI; -} |
