summaryrefslogtreecommitdiff
path: root/lib/Analysis/TargetLibraryInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Analysis/TargetLibraryInfo.cpp')
-rw-r--r--lib/Analysis/TargetLibraryInfo.cpp199
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},