summaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/TargetLibraryInfo.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2021-07-29 20:15:26 +0000
committerDimitry Andric <dim@FreeBSD.org>2021-07-29 20:15:26 +0000
commit344a3780b2e33f6ca763666c380202b18aab72a3 (patch)
treef0b203ee6eb71d7fdd792373e3c81eb18d6934dd /llvm/lib/Analysis/TargetLibraryInfo.cpp
parentb60736ec1405bb0a8dd40989f67ef4c93da068ab (diff)
Diffstat (limited to 'llvm/lib/Analysis/TargetLibraryInfo.cpp')
-rw-r--r--llvm/lib/Analysis/TargetLibraryInfo.cpp194
1 files changed, 134 insertions, 60 deletions
diff --git a/llvm/lib/Analysis/TargetLibraryInfo.cpp b/llvm/lib/Analysis/TargetLibraryInfo.cpp
index a4de21a2541e..4a8818f2e2a8 100644
--- a/llvm/lib/Analysis/TargetLibraryInfo.cpp
+++ b/llvm/lib/Analysis/TargetLibraryInfo.cpp
@@ -24,6 +24,8 @@ static cl::opt<TargetLibraryInfoImpl::VectorLibrary> ClVectorLibrary(
"No vector functions library"),
clEnumValN(TargetLibraryInfoImpl::Accelerate, "Accelerate",
"Accelerate framework"),
+ clEnumValN(TargetLibraryInfoImpl::DarwinLibSystemM,
+ "Darwin_libsystem_m", "Darwin libsystem_m"),
clEnumValN(TargetLibraryInfoImpl::LIBMVEC_X86, "LIBMVEC-X86",
"GLIBC Vector Math library"),
clEnumValN(TargetLibraryInfoImpl::MASSV, "MASSV",
@@ -65,6 +67,49 @@ static bool hasBcmp(const Triple &TT) {
return TT.isOSFreeBSD() || TT.isOSSolaris();
}
+static bool isCallingConvCCompatible(CallingConv::ID CC, StringRef TT,
+ FunctionType *FuncTy) {
+ switch (CC) {
+ default:
+ return false;
+ case llvm::CallingConv::C:
+ return true;
+ case llvm::CallingConv::ARM_APCS:
+ case llvm::CallingConv::ARM_AAPCS:
+ case llvm::CallingConv::ARM_AAPCS_VFP: {
+
+ // The iOS ABI diverges from the standard in some cases, so for now don't
+ // try to simplify those calls.
+ if (Triple(TT).isiOS())
+ return false;
+
+ if (!FuncTy->getReturnType()->isPointerTy() &&
+ !FuncTy->getReturnType()->isIntegerTy() &&
+ !FuncTy->getReturnType()->isVoidTy())
+ return false;
+
+ for (auto *Param : FuncTy->params()) {
+ if (!Param->isPointerTy() && !Param->isIntegerTy())
+ return false;
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
+bool TargetLibraryInfoImpl::isCallingConvCCompatible(CallBase *CI) {
+ return ::isCallingConvCCompatible(CI->getCallingConv(),
+ CI->getModule()->getTargetTriple(),
+ CI->getFunctionType());
+}
+
+bool TargetLibraryInfoImpl::isCallingConvCCompatible(Function *F) {
+ return ::isCallingConvCCompatible(F->getCallingConv(),
+ F->getParent()->getTargetTriple(),
+ F->getFunctionType());
+}
+
/// Initialize the set of available library functions based on the specified
/// target triple. This should be carefully written so that a missing target
/// triple gets a sane set of defaults.
@@ -106,6 +151,11 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T,
TLI.setShouldExtI32Return(ShouldExtI32Return);
TLI.setShouldSignExtI32Param(ShouldSignExtI32Param);
+ // Let's assume by default that the size of int is 32 bits, unless the target
+ // is a 16-bit architecture because then it most likely is 16 bits. If that
+ // isn't true for a target those defaults should be overridden below.
+ TLI.setIntSize(T.isArch16Bit() ? 16 : 32);
+
if (T.isAMDGPU())
TLI.disableAllFunctions();
@@ -115,6 +165,8 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T,
TLI.setUnavailable(LibFunc_memcpy);
TLI.setUnavailable(LibFunc_memset);
TLI.setUnavailable(LibFunc_memset_pattern16);
+ TLI.setAvailable(llvm::LibFunc___kmpc_alloc_shared);
+ TLI.setAvailable(llvm::LibFunc___kmpc_free_shared);
return;
}
@@ -307,59 +359,63 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T,
// Win32 does not support these functions, but
// they are generally available on POSIX-compliant systems.
TLI.setUnavailable(LibFunc_access);
+ TLI.setUnavailable(LibFunc_chmod);
+ TLI.setUnavailable(LibFunc_closedir);
+ TLI.setUnavailable(LibFunc_fdopen);
+ TLI.setUnavailable(LibFunc_fileno);
+ TLI.setUnavailable(LibFunc_fseeko);
+ TLI.setUnavailable(LibFunc_fstat);
+ TLI.setUnavailable(LibFunc_ftello);
+ TLI.setUnavailable(LibFunc_gettimeofday);
+ TLI.setUnavailable(LibFunc_memccpy);
+ TLI.setUnavailable(LibFunc_mkdir);
+ TLI.setUnavailable(LibFunc_open);
+ TLI.setUnavailable(LibFunc_opendir);
+ TLI.setUnavailable(LibFunc_pclose);
+ TLI.setUnavailable(LibFunc_popen);
+ TLI.setUnavailable(LibFunc_read);
+ TLI.setUnavailable(LibFunc_rmdir);
+ TLI.setUnavailable(LibFunc_stat);
+ TLI.setUnavailable(LibFunc_strcasecmp);
+ TLI.setUnavailable(LibFunc_strncasecmp);
+ TLI.setUnavailable(LibFunc_unlink);
+ TLI.setUnavailable(LibFunc_utime);
+ TLI.setUnavailable(LibFunc_write);
+ }
+
+ if (T.isOSWindows() && !T.isWindowsCygwinEnvironment()) {
+ // These functions aren't available in either MSVC or MinGW environments.
TLI.setUnavailable(LibFunc_bcmp);
TLI.setUnavailable(LibFunc_bcopy);
TLI.setUnavailable(LibFunc_bzero);
- TLI.setUnavailable(LibFunc_chmod);
TLI.setUnavailable(LibFunc_chown);
- TLI.setUnavailable(LibFunc_closedir);
TLI.setUnavailable(LibFunc_ctermid);
- TLI.setUnavailable(LibFunc_fdopen);
TLI.setUnavailable(LibFunc_ffs);
- TLI.setUnavailable(LibFunc_fileno);
TLI.setUnavailable(LibFunc_flockfile);
- TLI.setUnavailable(LibFunc_fseeko);
- TLI.setUnavailable(LibFunc_fstat);
TLI.setUnavailable(LibFunc_fstatvfs);
- TLI.setUnavailable(LibFunc_ftello);
TLI.setUnavailable(LibFunc_ftrylockfile);
TLI.setUnavailable(LibFunc_funlockfile);
TLI.setUnavailable(LibFunc_getitimer);
TLI.setUnavailable(LibFunc_getlogin_r);
TLI.setUnavailable(LibFunc_getpwnam);
- TLI.setUnavailable(LibFunc_gettimeofday);
TLI.setUnavailable(LibFunc_htonl);
TLI.setUnavailable(LibFunc_htons);
TLI.setUnavailable(LibFunc_lchown);
TLI.setUnavailable(LibFunc_lstat);
- TLI.setUnavailable(LibFunc_memccpy);
- TLI.setUnavailable(LibFunc_mkdir);
TLI.setUnavailable(LibFunc_ntohl);
TLI.setUnavailable(LibFunc_ntohs);
- TLI.setUnavailable(LibFunc_open);
- TLI.setUnavailable(LibFunc_opendir);
- TLI.setUnavailable(LibFunc_pclose);
- TLI.setUnavailable(LibFunc_popen);
TLI.setUnavailable(LibFunc_pread);
TLI.setUnavailable(LibFunc_pwrite);
- TLI.setUnavailable(LibFunc_read);
TLI.setUnavailable(LibFunc_readlink);
TLI.setUnavailable(LibFunc_realpath);
- TLI.setUnavailable(LibFunc_rmdir);
TLI.setUnavailable(LibFunc_setitimer);
- TLI.setUnavailable(LibFunc_stat);
TLI.setUnavailable(LibFunc_statvfs);
TLI.setUnavailable(LibFunc_stpcpy);
TLI.setUnavailable(LibFunc_stpncpy);
- TLI.setUnavailable(LibFunc_strcasecmp);
- TLI.setUnavailable(LibFunc_strncasecmp);
TLI.setUnavailable(LibFunc_times);
TLI.setUnavailable(LibFunc_uname);
- TLI.setUnavailable(LibFunc_unlink);
TLI.setUnavailable(LibFunc_unsetenv);
- TLI.setUnavailable(LibFunc_utime);
TLI.setUnavailable(LibFunc_utimes);
- TLI.setUnavailable(LibFunc_write);
}
switch (T.getOS()) {
@@ -547,6 +603,19 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T,
if (T.isNVPTX()) {
TLI.disableAllFunctions();
TLI.setAvailable(LibFunc_nvvm_reflect);
+ TLI.setAvailable(llvm::LibFunc_malloc);
+ TLI.setAvailable(llvm::LibFunc_free);
+
+ // TODO: We could enable the following two according to [0] but we haven't
+ // done an evaluation wrt. the performance implications.
+ // [0]
+ // https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#dynamic-global-memory-allocation-and-operations
+ //
+ // TLI.setAvailable(llvm::LibFunc_memcpy);
+ // TLI.setAvailable(llvm::LibFunc_memset);
+
+ TLI.setAvailable(llvm::LibFunc___kmpc_alloc_shared);
+ TLI.setAvailable(llvm::LibFunc___kmpc_free_shared);
} else {
TLI.setUnavailable(LibFunc_nvvm_reflect);
}
@@ -579,7 +648,8 @@ TargetLibraryInfoImpl::TargetLibraryInfoImpl(const Triple &T) {
TargetLibraryInfoImpl::TargetLibraryInfoImpl(const TargetLibraryInfoImpl &TLI)
: CustomNames(TLI.CustomNames), ShouldExtI32Param(TLI.ShouldExtI32Param),
ShouldExtI32Return(TLI.ShouldExtI32Return),
- ShouldSignExtI32Param(TLI.ShouldSignExtI32Param) {
+ ShouldSignExtI32Param(TLI.ShouldSignExtI32Param),
+ SizeOfInt(TLI.SizeOfInt) {
memcpy(AvailableArray, TLI.AvailableArray, sizeof(AvailableArray));
VectorDescs = TLI.VectorDescs;
ScalarDescs = TLI.ScalarDescs;
@@ -589,7 +659,8 @@ TargetLibraryInfoImpl::TargetLibraryInfoImpl(TargetLibraryInfoImpl &&TLI)
: CustomNames(std::move(TLI.CustomNames)),
ShouldExtI32Param(TLI.ShouldExtI32Param),
ShouldExtI32Return(TLI.ShouldExtI32Return),
- ShouldSignExtI32Param(TLI.ShouldSignExtI32Param) {
+ ShouldSignExtI32Param(TLI.ShouldSignExtI32Param),
+ SizeOfInt(TLI.SizeOfInt) {
std::move(std::begin(TLI.AvailableArray), std::end(TLI.AvailableArray),
AvailableArray);
VectorDescs = TLI.VectorDescs;
@@ -601,6 +672,7 @@ TargetLibraryInfoImpl &TargetLibraryInfoImpl::operator=(const TargetLibraryInfoI
ShouldExtI32Param = TLI.ShouldExtI32Param;
ShouldExtI32Return = TLI.ShouldExtI32Return;
ShouldSignExtI32Param = TLI.ShouldSignExtI32Param;
+ SizeOfInt = TLI.SizeOfInt;
memcpy(AvailableArray, TLI.AvailableArray, sizeof(AvailableArray));
return *this;
}
@@ -610,6 +682,7 @@ TargetLibraryInfoImpl &TargetLibraryInfoImpl::operator=(TargetLibraryInfoImpl &&
ShouldExtI32Param = TLI.ShouldExtI32Param;
ShouldExtI32Return = TLI.ShouldExtI32Return;
ShouldSignExtI32Param = TLI.ShouldSignExtI32Param;
+ SizeOfInt = TLI.SizeOfInt;
std::move(std::begin(TLI.AvailableArray), std::end(TLI.AvailableArray),
AvailableArray);
return *this;
@@ -645,7 +718,6 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy,
LibFunc F,
const DataLayout *DL) const {
LLVMContext &Ctx = FTy.getContext();
- Type *PCharTy = Type::getInt8PtrTy(Ctx);
Type *SizeTTy = DL ? DL->getIntPtrType(Ctx, /*AddressSpace=*/0) : nullptr;
auto IsSizeTTy = [SizeTTy](Type *Ty) {
return SizeTTy ? Ty == SizeTTy : Ty->isIntegerTy();
@@ -727,7 +799,7 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy,
case LibFunc_stpcpy:
return (NumParams == 2 && FTy.getReturnType() == FTy.getParamType(0) &&
FTy.getParamType(0) == FTy.getParamType(1) &&
- FTy.getParamType(0) == PCharTy);
+ FTy.getParamType(0)->isPointerTy());
case LibFunc_strlcat_chk:
case LibFunc_strlcpy_chk:
@@ -752,7 +824,7 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy,
case LibFunc_stpncpy:
return (NumParams == 3 && FTy.getReturnType() == FTy.getParamType(0) &&
FTy.getParamType(0) == FTy.getParamType(1) &&
- FTy.getParamType(0) == PCharTy &&
+ FTy.getParamType(0)->isPointerTy() &&
IsSizeTTy(FTy.getParamType(2)));
case LibFunc_strxfrm:
@@ -838,6 +910,7 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy,
FTy.getParamType(2)->isPointerTy());
case LibFunc_system:
return (NumParams == 1 && FTy.getParamType(0)->isPointerTy());
+ case LibFunc___kmpc_alloc_shared:
case LibFunc_malloc:
case LibFunc_vec_malloc:
return (NumParams == 1 && FTy.getReturnType()->isPointerTy());
@@ -895,7 +968,7 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy,
case LibFunc_realloc:
case LibFunc_reallocf:
case LibFunc_vec_realloc:
- return (NumParams == 2 && FTy.getReturnType() == PCharTy &&
+ return (NumParams == 2 && FTy.getReturnType()->isPointerTy() &&
FTy.getParamType(0) == FTy.getReturnType() &&
IsSizeTTy(FTy.getParamType(1)));
case LibFunc_read:
@@ -923,7 +996,8 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy,
return (NumParams == 2 && FTy.getParamType(0)->isPointerTy());
case LibFunc_calloc:
case LibFunc_vec_calloc:
- return (NumParams == 2 && FTy.getReturnType()->isPointerTy());
+ return (NumParams == 2 && FTy.getReturnType()->isPointerTy() &&
+ FTy.getParamType(0) == FTy.getParamType(1));
case LibFunc_atof:
case LibFunc_atoi:
@@ -975,6 +1049,9 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy,
case LibFunc_times:
case LibFunc_vec_free:
return (NumParams != 0 && FTy.getParamType(0)->isPointerTy());
+ case LibFunc___kmpc_free_shared:
+ return (NumParams == 2 && FTy.getParamType(0)->isPointerTy() &&
+ IsSizeTTy(FTy.getParamType(1)));
case LibFunc_fopen:
return (NumParams == 2 && FTy.getReturnType()->isPointerTy() &&
@@ -1026,7 +1103,7 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy,
case LibFunc_getchar_unlocked:
return (NumParams == 0 && FTy.getReturnType()->isIntegerTy());
case LibFunc_gets:
- return (NumParams == 1 && FTy.getParamType(0) == PCharTy);
+ return (NumParams == 1 && FTy.getParamType(0)->isPointerTy());
case LibFunc_getitimer:
return (NumParams == 2 && FTy.getParamType(1)->isPointerTy());
case LibFunc_ungetc:
@@ -1439,7 +1516,7 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy,
case LibFunc_ldexpl:
return (NumParams == 2 && FTy.getReturnType()->isFloatingPointTy() &&
FTy.getReturnType() == FTy.getParamType(0) &&
- FTy.getParamType(1)->isIntegerTy(32));
+ FTy.getParamType(1)->isIntegerTy(getIntSize()));
case LibFunc_ffs:
case LibFunc_ffsl:
@@ -1482,13 +1559,13 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy,
case LibFunc_strnlen:
return (NumParams == 2 && FTy.getReturnType() == FTy.getParamType(1) &&
- FTy.getParamType(0) == PCharTy &&
- FTy.getParamType(1) == SizeTTy);
+ FTy.getParamType(0)->isPointerTy() &&
+ IsSizeTTy(FTy.getParamType(1)));
case LibFunc_posix_memalign:
return (NumParams == 3 && FTy.getReturnType()->isIntegerTy(32) &&
FTy.getParamType(0)->isPointerTy() &&
- FTy.getParamType(1) == SizeTTy && FTy.getParamType(2) == SizeTTy);
+ IsSizeTTy(FTy.getParamType(1)) && IsSizeTTy(FTy.getParamType(2)));
case LibFunc_wcslen:
return (NumParams == 1 && FTy.getParamType(0)->isPointerTy() &&
@@ -1550,10 +1627,6 @@ static bool compareWithScalarFnName(const VecDesc &LHS, StringRef S) {
return LHS.ScalarFnName < S;
}
-static bool compareWithVectorFnName(const VecDesc &LHS, StringRef S) {
- return LHS.VectorFnName < S;
-}
-
void TargetLibraryInfoImpl::addVectorizableFunctions(ArrayRef<VecDesc> Fns) {
llvm::append_range(VectorDescs, Fns);
llvm::sort(VectorDescs, compareByScalarFnName);
@@ -1573,6 +1646,14 @@ void TargetLibraryInfoImpl::addVectorizableFunctionsFromVecLib(
addVectorizableFunctions(VecFuncs);
break;
}
+ case DarwinLibSystemM: {
+ const VecDesc VecFuncs[] = {
+ #define TLI_DEFINE_DARWIN_LIBSYSTEM_M_VECFUNCS
+ #include "llvm/Analysis/VecFuncs.def"
+ };
+ addVectorizableFunctions(VecFuncs);
+ break;
+ }
case LIBMVEC_X86: {
const VecDesc VecFuncs[] = {
#define TLI_DEFINE_LIBMVEC_X86_VECFUNCS
@@ -1612,8 +1693,9 @@ bool TargetLibraryInfoImpl::isFunctionVectorizable(StringRef funcName) const {
return I != VectorDescs.end() && StringRef(I->ScalarFnName) == funcName;
}
-StringRef TargetLibraryInfoImpl::getVectorizedFunction(StringRef F,
- unsigned VF) const {
+StringRef
+TargetLibraryInfoImpl::getVectorizedFunction(StringRef F,
+ const ElementCount &VF) const {
F = sanitizeFunctionName(F);
if (F.empty())
return F;
@@ -1627,20 +1709,6 @@ StringRef TargetLibraryInfoImpl::getVectorizedFunction(StringRef F,
return StringRef();
}
-StringRef TargetLibraryInfoImpl::getScalarizedFunction(StringRef F,
- unsigned &VF) const {
- F = sanitizeFunctionName(F);
- if (F.empty())
- return F;
-
- std::vector<VecDesc>::const_iterator I =
- llvm::lower_bound(ScalarDescs, F, compareWithVectorFnName);
- if (I == VectorDescs.end() || StringRef(I->VectorFnName) != F)
- return StringRef();
- VF = I->VectorizationFactor;
- return I->ScalarFnName;
-}
-
TargetLibraryInfo TargetLibraryAnalysis::run(const Function &F,
FunctionAnalysisManager &) {
if (!BaselineInfoImpl)
@@ -1681,18 +1749,24 @@ char TargetLibraryInfoWrapperPass::ID = 0;
void TargetLibraryInfoWrapperPass::anchor() {}
-unsigned TargetLibraryInfoImpl::getWidestVF(StringRef ScalarF) const {
+void TargetLibraryInfoImpl::getWidestVF(StringRef ScalarF,
+ ElementCount &FixedVF,
+ ElementCount &ScalableVF) const {
ScalarF = sanitizeFunctionName(ScalarF);
+ // Use '0' here because a type of the form <vscale x 1 x ElTy> is not the
+ // same as a scalar.
+ ScalableVF = ElementCount::getScalable(0);
+ FixedVF = ElementCount::getFixed(1);
if (ScalarF.empty())
- return 1;
+ return;
- unsigned VF = 1;
std::vector<VecDesc>::const_iterator I =
llvm::lower_bound(VectorDescs, ScalarF, compareWithScalarFnName);
while (I != VectorDescs.end() && StringRef(I->ScalarFnName) == ScalarF) {
- if (I->VectorizationFactor > VF)
- VF = I->VectorizationFactor;
+ ElementCount *VF =
+ I->VectorizationFactor.isScalable() ? &ScalableVF : &FixedVF;
+ if (ElementCount::isKnownGT(I->VectorizationFactor, *VF))
+ *VF = I->VectorizationFactor;
++I;
}
- return VF;
}