diff options
Diffstat (limited to 'lib/Analysis/TargetLibraryInfo.cpp')
| -rw-r--r-- | lib/Analysis/TargetLibraryInfo.cpp | 199 | 
1 files changed, 144 insertions, 55 deletions
diff --git a/lib/Analysis/TargetLibraryInfo.cpp b/lib/Analysis/TargetLibraryInfo.cpp index d18246ac5941..102135fbf313 100644 --- a/lib/Analysis/TargetLibraryInfo.cpp +++ b/lib/Analysis/TargetLibraryInfo.cpp @@ -62,6 +62,18 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T,                          }) &&           "TargetLibraryInfoImpl function names must be sorted"); +  // Set IO unlocked variants as unavailable +  // Set them as available per system below +  TLI.setUnavailable(LibFunc_getchar_unlocked); +  TLI.setUnavailable(LibFunc_putc_unlocked); +  TLI.setUnavailable(LibFunc_putchar_unlocked); +  TLI.setUnavailable(LibFunc_fputc_unlocked); +  TLI.setUnavailable(LibFunc_fgetc_unlocked); +  TLI.setUnavailable(LibFunc_fread_unlocked); +  TLI.setUnavailable(LibFunc_fwrite_unlocked); +  TLI.setUnavailable(LibFunc_fputs_unlocked); +  TLI.setUnavailable(LibFunc_fgets_unlocked); +    bool ShouldExtI32Param = false, ShouldExtI32Return = false,         ShouldSignExtI32Param = false;    // PowerPC64, Sparc64, SystemZ need signext/zeroext on i32 parameters and @@ -73,8 +85,7 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T,    }    // Mips, on the other hand, needs signext on i32 parameters corresponding    // to both signed and unsigned ints. -  if (T.getArch() == Triple::mips || T.getArch() == Triple::mipsel || -      T.getArch() == Triple::mips64 || T.getArch() == Triple::mips64el) { +  if (T.isMIPS()) {      ShouldSignExtI32Param = true;    }    TLI.setShouldExtI32Param(ShouldExtI32Param); @@ -107,6 +118,12 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T,    // memset_pattern16 is only available on iOS 3.0 and Mac OS X 10.5 and later.    // All versions of watchOS support it.    if (T.isMacOSX()) { +    // available IO unlocked variants on Mac OS X +    TLI.setAvailable(LibFunc_getc_unlocked); +    TLI.setAvailable(LibFunc_getchar_unlocked); +    TLI.setAvailable(LibFunc_putc_unlocked); +    TLI.setAvailable(LibFunc_putchar_unlocked); +      if (T.isMacOSXVersionLT(10, 5))        TLI.setUnavailable(LibFunc_memset_pattern16);    } else if (T.isiOS()) { @@ -245,51 +262,7 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T,        TLI.setUnavailable(LibFunc_tanhf);      } -    // These definitions are due to math-finite.h header on Linux -    TLI.setUnavailable(LibFunc_acos_finite); -    TLI.setUnavailable(LibFunc_acosf_finite); -    TLI.setUnavailable(LibFunc_acosl_finite); -    TLI.setUnavailable(LibFunc_acosh_finite); -    TLI.setUnavailable(LibFunc_acoshf_finite); -    TLI.setUnavailable(LibFunc_acoshl_finite); -    TLI.setUnavailable(LibFunc_asin_finite); -    TLI.setUnavailable(LibFunc_asinf_finite); -    TLI.setUnavailable(LibFunc_asinl_finite); -    TLI.setUnavailable(LibFunc_atan2_finite); -    TLI.setUnavailable(LibFunc_atan2f_finite); -    TLI.setUnavailable(LibFunc_atan2l_finite); -    TLI.setUnavailable(LibFunc_atanh_finite); -    TLI.setUnavailable(LibFunc_atanhf_finite); -    TLI.setUnavailable(LibFunc_atanhl_finite); -    TLI.setUnavailable(LibFunc_cosh_finite); -    TLI.setUnavailable(LibFunc_coshf_finite); -    TLI.setUnavailable(LibFunc_coshl_finite); -    TLI.setUnavailable(LibFunc_exp10_finite); -    TLI.setUnavailable(LibFunc_exp10f_finite); -    TLI.setUnavailable(LibFunc_exp10l_finite); -    TLI.setUnavailable(LibFunc_exp2_finite); -    TLI.setUnavailable(LibFunc_exp2f_finite); -    TLI.setUnavailable(LibFunc_exp2l_finite); -    TLI.setUnavailable(LibFunc_exp_finite); -    TLI.setUnavailable(LibFunc_expf_finite); -    TLI.setUnavailable(LibFunc_expl_finite); -    TLI.setUnavailable(LibFunc_log10_finite); -    TLI.setUnavailable(LibFunc_log10f_finite); -    TLI.setUnavailable(LibFunc_log10l_finite); -    TLI.setUnavailable(LibFunc_log2_finite); -    TLI.setUnavailable(LibFunc_log2f_finite); -    TLI.setUnavailable(LibFunc_log2l_finite); -    TLI.setUnavailable(LibFunc_log_finite); -    TLI.setUnavailable(LibFunc_logf_finite); -    TLI.setUnavailable(LibFunc_logl_finite); -    TLI.setUnavailable(LibFunc_pow_finite); -    TLI.setUnavailable(LibFunc_powf_finite); -    TLI.setUnavailable(LibFunc_powl_finite); -    TLI.setUnavailable(LibFunc_sinh_finite); -    TLI.setUnavailable(LibFunc_sinhf_finite); -    TLI.setUnavailable(LibFunc_sinhl_finite); - -    // Win32 does *not* provide provide these functions, but they are +    // Win32 does *not* provide these functions, but they are      // generally available on POSIX-compliant systems:      TLI.setUnavailable(LibFunc_access);      TLI.setUnavailable(LibFunc_bcmp); @@ -309,7 +282,6 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T,      TLI.setUnavailable(LibFunc_ftello);      TLI.setUnavailable(LibFunc_ftrylockfile);      TLI.setUnavailable(LibFunc_funlockfile); -    TLI.setUnavailable(LibFunc_getc_unlocked);      TLI.setUnavailable(LibFunc_getitimer);      TLI.setUnavailable(LibFunc_getlogin_r);      TLI.setUnavailable(LibFunc_getpwnam); @@ -441,15 +413,18 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T,      TLI.setUnavailable(LibFunc_flsll);    } -  // The following functions are available on at least Linux: -  if (!T.isOSLinux()) { +  // The following functions are available on Linux, +  // but Android uses bionic instead of glibc. +  if (!T.isOSLinux() || T.isAndroid()) {      TLI.setUnavailable(LibFunc_dunder_strdup);      TLI.setUnavailable(LibFunc_dunder_strtok_r);      TLI.setUnavailable(LibFunc_dunder_isoc99_scanf);      TLI.setUnavailable(LibFunc_dunder_isoc99_sscanf);      TLI.setUnavailable(LibFunc_under_IO_getc);      TLI.setUnavailable(LibFunc_under_IO_putc); -    TLI.setUnavailable(LibFunc_memalign); +    // But, Android has memalign. +    if (!T.isAndroid()) +      TLI.setUnavailable(LibFunc_memalign);      TLI.setUnavailable(LibFunc_fopen64);      TLI.setUnavailable(LibFunc_fseeko64);      TLI.setUnavailable(LibFunc_fstat64); @@ -460,6 +435,65 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T,      TLI.setUnavailable(LibFunc_stat64);      TLI.setUnavailable(LibFunc_statvfs64);      TLI.setUnavailable(LibFunc_tmpfile64); + +    // Relaxed math functions are included in math-finite.h on Linux (GLIBC). +    TLI.setUnavailable(LibFunc_acos_finite); +    TLI.setUnavailable(LibFunc_acosf_finite); +    TLI.setUnavailable(LibFunc_acosl_finite); +    TLI.setUnavailable(LibFunc_acosh_finite); +    TLI.setUnavailable(LibFunc_acoshf_finite); +    TLI.setUnavailable(LibFunc_acoshl_finite); +    TLI.setUnavailable(LibFunc_asin_finite); +    TLI.setUnavailable(LibFunc_asinf_finite); +    TLI.setUnavailable(LibFunc_asinl_finite); +    TLI.setUnavailable(LibFunc_atan2_finite); +    TLI.setUnavailable(LibFunc_atan2f_finite); +    TLI.setUnavailable(LibFunc_atan2l_finite); +    TLI.setUnavailable(LibFunc_atanh_finite); +    TLI.setUnavailable(LibFunc_atanhf_finite); +    TLI.setUnavailable(LibFunc_atanhl_finite); +    TLI.setUnavailable(LibFunc_cosh_finite); +    TLI.setUnavailable(LibFunc_coshf_finite); +    TLI.setUnavailable(LibFunc_coshl_finite); +    TLI.setUnavailable(LibFunc_exp10_finite); +    TLI.setUnavailable(LibFunc_exp10f_finite); +    TLI.setUnavailable(LibFunc_exp10l_finite); +    TLI.setUnavailable(LibFunc_exp2_finite); +    TLI.setUnavailable(LibFunc_exp2f_finite); +    TLI.setUnavailable(LibFunc_exp2l_finite); +    TLI.setUnavailable(LibFunc_exp_finite); +    TLI.setUnavailable(LibFunc_expf_finite); +    TLI.setUnavailable(LibFunc_expl_finite); +    TLI.setUnavailable(LibFunc_log10_finite); +    TLI.setUnavailable(LibFunc_log10f_finite); +    TLI.setUnavailable(LibFunc_log10l_finite); +    TLI.setUnavailable(LibFunc_log2_finite); +    TLI.setUnavailable(LibFunc_log2f_finite); +    TLI.setUnavailable(LibFunc_log2l_finite); +    TLI.setUnavailable(LibFunc_log_finite); +    TLI.setUnavailable(LibFunc_logf_finite); +    TLI.setUnavailable(LibFunc_logl_finite); +    TLI.setUnavailable(LibFunc_pow_finite); +    TLI.setUnavailable(LibFunc_powf_finite); +    TLI.setUnavailable(LibFunc_powl_finite); +    TLI.setUnavailable(LibFunc_sinh_finite); +    TLI.setUnavailable(LibFunc_sinhf_finite); +    TLI.setUnavailable(LibFunc_sinhl_finite); +  } + +  if ((T.isOSLinux() && T.isGNUEnvironment()) || +      (T.isAndroid() && !T.isAndroidVersionLT(28))) { +    // available IO unlocked variants on GNU/Linux and Android P or later +    TLI.setAvailable(LibFunc_getc_unlocked); +    TLI.setAvailable(LibFunc_getchar_unlocked); +    TLI.setAvailable(LibFunc_putc_unlocked); +    TLI.setAvailable(LibFunc_putchar_unlocked); +    TLI.setAvailable(LibFunc_fputc_unlocked); +    TLI.setAvailable(LibFunc_fgetc_unlocked); +    TLI.setAvailable(LibFunc_fread_unlocked); +    TLI.setAvailable(LibFunc_fwrite_unlocked); +    TLI.setAvailable(LibFunc_fputs_unlocked); +    TLI.setAvailable(LibFunc_fgets_unlocked);    }    // As currently implemented in clang, NVPTX code has no standard library to @@ -689,10 +723,12 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy,    case LibFunc_siprintf:    case LibFunc_sprintf:      return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && -            FTy.getParamType(1)->isPointerTy()); +            FTy.getParamType(1)->isPointerTy() && +            FTy.getReturnType()->isIntegerTy(32));    case LibFunc_snprintf:      return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && -            FTy.getParamType(2)->isPointerTy()); +            FTy.getParamType(2)->isPointerTy() && +            FTy.getReturnType()->isIntegerTy(32));    case LibFunc_setitimer:      return (NumParams == 3 && FTy.getParamType(1)->isPointerTy() &&              FTy.getParamType(2)->isPointerTy()); @@ -802,6 +838,7 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy,    case LibFunc_feof:    case LibFunc_fflush:    case LibFunc_fgetc: +  case LibFunc_fgetc_unlocked:    case LibFunc_fileno:    case LibFunc_flockfile:    case LibFunc_free: @@ -830,6 +867,7 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy,      return (NumParams == 2 && FTy.getReturnType()->isPointerTy() &&              FTy.getParamType(1)->isPointerTy());    case LibFunc_fputc: +  case LibFunc_fputc_unlocked:    case LibFunc_fstat:    case LibFunc_frexp:    case LibFunc_frexpf: @@ -837,18 +875,22 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy,    case LibFunc_fstatvfs:      return (NumParams == 2 && FTy.getParamType(1)->isPointerTy());    case LibFunc_fgets: +  case LibFunc_fgets_unlocked:      return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() &&              FTy.getParamType(2)->isPointerTy());    case LibFunc_fread: +  case LibFunc_fread_unlocked:      return (NumParams == 4 && FTy.getParamType(0)->isPointerTy() &&              FTy.getParamType(3)->isPointerTy());    case LibFunc_fwrite: +  case LibFunc_fwrite_unlocked:      return (NumParams == 4 && FTy.getReturnType()->isIntegerTy() &&              FTy.getParamType(0)->isPointerTy() &&              FTy.getParamType(1)->isIntegerTy() &&              FTy.getParamType(2)->isIntegerTy() &&              FTy.getParamType(3)->isPointerTy());    case LibFunc_fputs: +  case LibFunc_fputs_unlocked:      return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() &&              FTy.getParamType(1)->isPointerTy());    case LibFunc_fscanf: @@ -861,6 +903,7 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy,      return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() &&              FTy.getParamType(1)->isPointerTy());    case LibFunc_getchar: +  case LibFunc_getchar_unlocked:      return (NumParams == 0 && FTy.getReturnType()->isIntegerTy());    case LibFunc_gets:      return (NumParams == 1 && FTy.getParamType(0) == PCharTy); @@ -873,6 +916,7 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy,      return (NumParams == 2 && FTy.getParamType(0)->isPointerTy() &&              FTy.getParamType(1)->isPointerTy());    case LibFunc_putc: +  case LibFunc_putc_unlocked:      return (NumParams == 2 && FTy.getParamType(1)->isPointerTy());    case LibFunc_pread:    case LibFunc_pwrite: @@ -989,8 +1033,26 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy,    case LibFunc_msvc_new_array_int_nothrow:    // new[](unsigned long long, nothrow);    case LibFunc_msvc_new_array_longlong_nothrow: +  // new(unsigned int, align_val_t) +  case LibFunc_ZnwjSt11align_val_t: +  // new(unsigned long, align_val_t) +  case LibFunc_ZnwmSt11align_val_t: +  // new[](unsigned int, align_val_t) +  case LibFunc_ZnajSt11align_val_t: +  // new[](unsigned long, align_val_t) +  case LibFunc_ZnamSt11align_val_t:      return (NumParams == 2 && FTy.getReturnType()->isPointerTy()); +  // new(unsigned int, align_val_t, nothrow) +  case LibFunc_ZnwjSt11align_val_tRKSt9nothrow_t: +  // new(unsigned long, align_val_t, nothrow) +  case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t: +  // new[](unsigned int, align_val_t, nothrow) +  case LibFunc_ZnajSt11align_val_tRKSt9nothrow_t: +  // new[](unsigned long, align_val_t, nothrow) +  case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t: +    return (NumParams == 3 && FTy.getReturnType()->isPointerTy()); +    // void operator delete[](void*);    case LibFunc_ZdaPv:    // void operator delete(void*); @@ -1017,6 +1079,10 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy,    case LibFunc_ZdlPvj:    // void operator delete(void*, unsigned long);    case LibFunc_ZdlPvm: +  // void operator delete(void*, align_val_t) +  case LibFunc_ZdlPvSt11align_val_t: +  // void operator delete[](void*, align_val_t) +  case LibFunc_ZdaPvSt11align_val_t:    // void operator delete[](void*, unsigned int);    case LibFunc_msvc_delete_array_ptr32_int:    // void operator delete[](void*, nothrow); @@ -1035,6 +1101,12 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy,    case LibFunc_msvc_delete_ptr64_nothrow:      return (NumParams == 2 && FTy.getParamType(0)->isPointerTy()); +  // void operator delete(void*, align_val_t, nothrow) +  case LibFunc_ZdlPvSt11align_val_tRKSt9nothrow_t: +  // void operator delete[](void*, align_val_t, nothrow) +  case LibFunc_ZdaPvSt11align_val_tRKSt9nothrow_t: +    return (NumParams == 3 && FTy.getParamType(0)->isPointerTy()); +    case LibFunc_memset_pattern16:      return (!FTy.isVarArg() && NumParams == 3 &&              FTy.getParamType(0)->isPointerTy() && @@ -1231,6 +1303,7 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy,    case LibFunc_isascii:    case LibFunc_toascii:    case LibFunc_putchar: +  case LibFunc_putchar_unlocked:      return (NumParams == 1 && FTy.getReturnType()->isIntegerTy(32) &&              FTy.getReturnType() == FTy.getParamType(0)); @@ -1326,10 +1399,10 @@ static bool compareWithVectorFnName(const VecDesc &LHS, StringRef S) {  void TargetLibraryInfoImpl::addVectorizableFunctions(ArrayRef<VecDesc> Fns) {    VectorDescs.insert(VectorDescs.end(), Fns.begin(), Fns.end()); -  std::sort(VectorDescs.begin(), VectorDescs.end(), compareByScalarFnName); +  llvm::sort(VectorDescs.begin(), VectorDescs.end(), compareByScalarFnName);    ScalarDescs.insert(ScalarDescs.end(), Fns.begin(), Fns.end()); -  std::sort(ScalarDescs.begin(), ScalarDescs.end(), compareByVectorFnName); +  llvm::sort(ScalarDescs.begin(), ScalarDescs.end(), compareByVectorFnName);  }  void TargetLibraryInfoImpl::addVectorizableFunctionsFromVecLib( @@ -1387,6 +1460,14 @@ void TargetLibraryInfoImpl::addVectorizableFunctionsFromVecLib(          {"sinf", "__svml_sinf8", 8},          {"sinf", "__svml_sinf16", 16}, +        {"llvm.sin.f64", "__svml_sin2", 2}, +        {"llvm.sin.f64", "__svml_sin4", 4}, +        {"llvm.sin.f64", "__svml_sin8", 8}, + +        {"llvm.sin.f32", "__svml_sinf4", 4}, +        {"llvm.sin.f32", "__svml_sinf8", 8}, +        {"llvm.sin.f32", "__svml_sinf16", 16}, +          {"cos", "__svml_cos2", 2},          {"cos", "__svml_cos4", 4},          {"cos", "__svml_cos8", 8}, @@ -1395,6 +1476,14 @@ void TargetLibraryInfoImpl::addVectorizableFunctionsFromVecLib(          {"cosf", "__svml_cosf8", 8},          {"cosf", "__svml_cosf16", 16}, +        {"llvm.cos.f64", "__svml_cos2", 2}, +        {"llvm.cos.f64", "__svml_cos4", 4}, +        {"llvm.cos.f64", "__svml_cos8", 8}, + +        {"llvm.cos.f32", "__svml_cosf4", 4}, +        {"llvm.cos.f32", "__svml_cosf8", 8}, +        {"llvm.cos.f32", "__svml_cosf16", 16}, +          {"pow", "__svml_pow2", 2},          {"pow", "__svml_pow4", 4},          {"pow", "__svml_pow8", 8},  | 
