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}, |