diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2021-07-29 20:15:26 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2021-07-29 20:15:26 +0000 |
| commit | 344a3780b2e33f6ca763666c380202b18aab72a3 (patch) | |
| tree | f0b203ee6eb71d7fdd792373e3c81eb18d6934dd /llvm/lib/Analysis/TargetLibraryInfo.cpp | |
| parent | b60736ec1405bb0a8dd40989f67ef4c93da068ab (diff) | |
vendor/llvm-project/llvmorg-13-init-16847-g88e66fa60ae5vendor/llvm-project/llvmorg-12.0.1-rc2-0-ge7dac564cd0evendor/llvm-project/llvmorg-12.0.1-0-gfed41342a82f
Diffstat (limited to 'llvm/lib/Analysis/TargetLibraryInfo.cpp')
| -rw-r--r-- | llvm/lib/Analysis/TargetLibraryInfo.cpp | 194 |
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; } |
