diff options
Diffstat (limited to 'contrib/llvm/lib/Analysis/TargetLibraryInfo.cpp')
-rw-r--r-- | contrib/llvm/lib/Analysis/TargetLibraryInfo.cpp | 161 |
1 files changed, 132 insertions, 29 deletions
diff --git a/contrib/llvm/lib/Analysis/TargetLibraryInfo.cpp b/contrib/llvm/lib/Analysis/TargetLibraryInfo.cpp index 93d537a..112118a 100644 --- a/contrib/llvm/lib/Analysis/TargetLibraryInfo.cpp +++ b/contrib/llvm/lib/Analysis/TargetLibraryInfo.cpp @@ -23,9 +23,10 @@ static cl::opt<TargetLibraryInfoImpl::VectorLibrary> ClVectorLibrary( "No vector functions library"), clEnumValN(TargetLibraryInfoImpl::Accelerate, "Accelerate", "Accelerate framework"), - clEnumValEnd)); + clEnumValN(TargetLibraryInfoImpl::SVML, "SVML", + "Intel SVML library"))); -const char *const TargetLibraryInfoImpl::StandardNames[LibFunc::NumLibFuncs] = { +StringRef const TargetLibraryInfoImpl::StandardNames[LibFunc::NumLibFuncs] = { #define TLI_DEFINE_STRING #include "llvm/Analysis/TargetLibraryInfo.def" }; @@ -52,14 +53,33 @@ static bool hasSinCosPiStret(const Triple &T) { /// specified target triple. This should be carefully written so that a missing /// target triple gets a sane set of defaults. static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, - ArrayRef<const char *> StandardNames) { + ArrayRef<StringRef> StandardNames) { // Verify that the StandardNames array is in alphabetical order. assert(std::is_sorted(StandardNames.begin(), StandardNames.end(), - [](const char *LHS, const char *RHS) { - return strcmp(LHS, RHS) < 0; + [](StringRef LHS, StringRef RHS) { + return LHS < RHS; }) && "TargetLibraryInfoImpl function names must be sorted"); + bool ShouldExtI32Param = false, ShouldExtI32Return = false, + ShouldSignExtI32Param = false; + // PowerPC64, Sparc64, SystemZ need signext/zeroext on i32 parameters and + // returns corresponding to C-level ints and unsigned ints. + if (T.getArch() == Triple::ppc64 || T.getArch() == Triple::ppc64le || + T.getArch() == Triple::sparcv9 || T.getArch() == Triple::systemz) { + ShouldExtI32Param = true; + ShouldExtI32Return = true; + } + // 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) { + ShouldSignExtI32Param = true; + } + TLI.setShouldExtI32Param(ShouldExtI32Param); + TLI.setShouldExtI32Return(ShouldExtI32Return); + TLI.setShouldSignExtI32Param(ShouldSignExtI32Param); + if (T.getArch() == Triple::r600 || T.getArch() == Triple::amdgcn) { TLI.setUnavailable(LibFunc::ldexp); @@ -322,6 +342,7 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, // on Linux. // // Fall through to disable all of them. + LLVM_FALLTHROUGH; default: TLI.setUnavailable(LibFunc::exp10); TLI.setUnavailable(LibFunc::exp10f); @@ -429,14 +450,19 @@ TargetLibraryInfoImpl::TargetLibraryInfoImpl(const Triple &T) { } TargetLibraryInfoImpl::TargetLibraryInfoImpl(const TargetLibraryInfoImpl &TLI) - : CustomNames(TLI.CustomNames) { + : CustomNames(TLI.CustomNames), ShouldExtI32Param(TLI.ShouldExtI32Param), + ShouldExtI32Return(TLI.ShouldExtI32Return), + ShouldSignExtI32Param(TLI.ShouldSignExtI32Param) { memcpy(AvailableArray, TLI.AvailableArray, sizeof(AvailableArray)); VectorDescs = TLI.VectorDescs; ScalarDescs = TLI.ScalarDescs; } TargetLibraryInfoImpl::TargetLibraryInfoImpl(TargetLibraryInfoImpl &&TLI) - : CustomNames(std::move(TLI.CustomNames)) { + : CustomNames(std::move(TLI.CustomNames)), + ShouldExtI32Param(TLI.ShouldExtI32Param), + ShouldExtI32Return(TLI.ShouldExtI32Return), + ShouldSignExtI32Param(TLI.ShouldSignExtI32Param) { std::move(std::begin(TLI.AvailableArray), std::end(TLI.AvailableArray), AvailableArray); VectorDescs = TLI.VectorDescs; @@ -445,12 +471,18 @@ TargetLibraryInfoImpl::TargetLibraryInfoImpl(TargetLibraryInfoImpl &&TLI) TargetLibraryInfoImpl &TargetLibraryInfoImpl::operator=(const TargetLibraryInfoImpl &TLI) { CustomNames = TLI.CustomNames; + ShouldExtI32Param = TLI.ShouldExtI32Param; + ShouldExtI32Return = TLI.ShouldExtI32Return; + ShouldSignExtI32Param = TLI.ShouldSignExtI32Param; memcpy(AvailableArray, TLI.AvailableArray, sizeof(AvailableArray)); return *this; } TargetLibraryInfoImpl &TargetLibraryInfoImpl::operator=(TargetLibraryInfoImpl &&TLI) { CustomNames = std::move(TLI.CustomNames); + ShouldExtI32Param = TLI.ShouldExtI32Param; + ShouldExtI32Return = TLI.ShouldExtI32Return; + ShouldSignExtI32Param = TLI.ShouldSignExtI32Param; std::move(std::begin(TLI.AvailableArray), std::end(TLI.AvailableArray), AvailableArray); return *this; @@ -469,16 +501,16 @@ static StringRef sanitizeFunctionName(StringRef funcName) { bool TargetLibraryInfoImpl::getLibFunc(StringRef funcName, LibFunc::Func &F) const { - const char *const *Start = &StandardNames[0]; - const char *const *End = &StandardNames[LibFunc::NumLibFuncs]; + StringRef const *Start = &StandardNames[0]; + StringRef const *End = &StandardNames[LibFunc::NumLibFuncs]; funcName = sanitizeFunctionName(funcName); if (funcName.empty()) return false; - const char *const *I = std::lower_bound( - Start, End, funcName, [](const char *LHS, StringRef RHS) { - return std::strncmp(LHS, RHS.data(), RHS.size()) < 0; + StringRef const *I = std::lower_bound( + Start, End, funcName, [](StringRef LHS, StringRef RHS) { + return LHS < RHS; }); if (I != End && *I == funcName) { F = (LibFunc::Func)(I - Start); @@ -535,7 +567,7 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy, --NumParams; if (!IsSizeTTy(FTy.getParamType(NumParams))) return false; - // fallthrough + LLVM_FALLTHROUGH; case LibFunc::strcpy: case LibFunc::stpcpy: return (NumParams == 2 && FTy.getReturnType() == FTy.getParamType(0) && @@ -547,7 +579,7 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy, --NumParams; if (!IsSizeTTy(FTy.getParamType(NumParams))) return false; - // fallthrough + LLVM_FALLTHROUGH; case LibFunc::strncpy: case LibFunc::stpncpy: return (NumParams == 3 && FTy.getReturnType() == FTy.getParamType(0) && @@ -640,8 +672,9 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy, --NumParams; if (!IsSizeTTy(FTy.getParamType(NumParams))) return false; - // fallthrough + LLVM_FALLTHROUGH; case LibFunc::memcpy: + case LibFunc::mempcpy: case LibFunc::memmove: return (NumParams == 3 && FTy.getReturnType() == FTy.getParamType(0) && FTy.getParamType(0)->isPointerTy() && @@ -652,7 +685,7 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy, --NumParams; if (!IsSizeTTy(FTy.getParamType(NumParams))) return false; - // fallthrough + LLVM_FALLTHROUGH; case LibFunc::memset: return (NumParams == 3 && FTy.getReturnType() == FTy.getParamType(0) && FTy.getParamType(0)->isPointerTy() && @@ -843,10 +876,10 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy, case LibFunc::stat64: case LibFunc::lstat64: case LibFunc::statvfs64: - return (NumParams >= 1 && FTy.getParamType(0)->isPointerTy() && + return (NumParams == 2 && FTy.getParamType(0)->isPointerTy() && FTy.getParamType(1)->isPointerTy()); case LibFunc::dunder_isoc99_sscanf: - return (NumParams >= 1 && FTy.getParamType(0)->isPointerTy() && + return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && FTy.getParamType(1)->isPointerTy()); case LibFunc::fopen64: return (NumParams == 2 && FTy.getReturnType()->isPointerTy() && @@ -953,15 +986,18 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy, case LibFunc::ffs: case LibFunc::ffsl: case LibFunc::ffsll: + case LibFunc::fls: + case LibFunc::flsl: + case LibFunc::flsll: + return (NumParams == 1 && FTy.getReturnType()->isIntegerTy(32) && + FTy.getParamType(0)->isIntegerTy()); + case LibFunc::isdigit: case LibFunc::isascii: case LibFunc::toascii: return (NumParams == 1 && FTy.getReturnType()->isIntegerTy(32) && - FTy.getParamType(0)->isIntegerTy()); + FTy.getReturnType() == FTy.getParamType(0)); - case LibFunc::fls: - case LibFunc::flsl: - case LibFunc::flsll: case LibFunc::abs: case LibFunc::labs: case LibFunc::llabs: @@ -1004,21 +1040,19 @@ void TargetLibraryInfoImpl::disableAllFunctions() { } static bool compareByScalarFnName(const VecDesc &LHS, const VecDesc &RHS) { - return std::strncmp(LHS.ScalarFnName, RHS.ScalarFnName, - std::strlen(RHS.ScalarFnName)) < 0; + return LHS.ScalarFnName < RHS.ScalarFnName; } static bool compareByVectorFnName(const VecDesc &LHS, const VecDesc &RHS) { - return std::strncmp(LHS.VectorFnName, RHS.VectorFnName, - std::strlen(RHS.VectorFnName)) < 0; + return LHS.VectorFnName < RHS.VectorFnName; } static bool compareWithScalarFnName(const VecDesc &LHS, StringRef S) { - return std::strncmp(LHS.ScalarFnName, S.data(), S.size()) < 0; + return LHS.ScalarFnName < S; } static bool compareWithVectorFnName(const VecDesc &LHS, StringRef S) { - return std::strncmp(LHS.VectorFnName, S.data(), S.size()) < 0; + return LHS.VectorFnName < S; } void TargetLibraryInfoImpl::addVectorizableFunctions(ArrayRef<VecDesc> Fns) { @@ -1074,6 +1108,75 @@ void TargetLibraryInfoImpl::addVectorizableFunctionsFromVecLib( addVectorizableFunctions(VecFuncs); break; } + case SVML: { + const VecDesc VecFuncs[] = { + {"sin", "__svml_sin2", 2}, + {"sin", "__svml_sin4", 4}, + {"sin", "__svml_sin8", 8}, + + {"sinf", "__svml_sinf4", 4}, + {"sinf", "__svml_sinf8", 8}, + {"sinf", "__svml_sinf16", 16}, + + {"cos", "__svml_cos2", 2}, + {"cos", "__svml_cos4", 4}, + {"cos", "__svml_cos8", 8}, + + {"cosf", "__svml_cosf4", 4}, + {"cosf", "__svml_cosf8", 8}, + {"cosf", "__svml_cosf16", 16}, + + {"pow", "__svml_pow2", 2}, + {"pow", "__svml_pow4", 4}, + {"pow", "__svml_pow8", 8}, + + {"powf", "__svml_powf4", 4}, + {"powf", "__svml_powf8", 8}, + {"powf", "__svml_powf16", 16}, + + {"llvm.pow.f64", "__svml_pow2", 2}, + {"llvm.pow.f64", "__svml_pow4", 4}, + {"llvm.pow.f64", "__svml_pow8", 8}, + + {"llvm.pow.f32", "__svml_powf4", 4}, + {"llvm.pow.f32", "__svml_powf8", 8}, + {"llvm.pow.f32", "__svml_powf16", 16}, + + {"exp", "__svml_exp2", 2}, + {"exp", "__svml_exp4", 4}, + {"exp", "__svml_exp8", 8}, + + {"expf", "__svml_expf4", 4}, + {"expf", "__svml_expf8", 8}, + {"expf", "__svml_expf16", 16}, + + {"llvm.exp.f64", "__svml_exp2", 2}, + {"llvm.exp.f64", "__svml_exp4", 4}, + {"llvm.exp.f64", "__svml_exp8", 8}, + + {"llvm.exp.f32", "__svml_expf4", 4}, + {"llvm.exp.f32", "__svml_expf8", 8}, + {"llvm.exp.f32", "__svml_expf16", 16}, + + {"log", "__svml_log2", 2}, + {"log", "__svml_log4", 4}, + {"log", "__svml_log8", 8}, + + {"logf", "__svml_logf4", 4}, + {"logf", "__svml_logf8", 8}, + {"logf", "__svml_logf16", 16}, + + {"llvm.log.f64", "__svml_log2", 2}, + {"llvm.log.f64", "__svml_log4", 4}, + {"llvm.log.f64", "__svml_log8", 8}, + + {"llvm.log.f32", "__svml_logf4", 4}, + {"llvm.log.f32", "__svml_logf8", 8}, + {"llvm.log.f32", "__svml_logf16", 16}, + }; + addVectorizableFunctions(VecFuncs); + break; + } case NoLibrary: break; } @@ -1162,7 +1265,7 @@ TargetLibraryInfoWrapperPass::TargetLibraryInfoWrapperPass( initializeTargetLibraryInfoWrapperPassPass(*PassRegistry::getPassRegistry()); } -char TargetLibraryAnalysis::PassID; +AnalysisKey TargetLibraryAnalysis::Key; // Register the basic pass. INITIALIZE_PASS(TargetLibraryInfoWrapperPass, "targetlibinfo", |