X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FTargetLibraryInfo.cpp;h=616ff9067300706adf65999f7b3854f21dc6c44b;hb=dd7a7107c16fd6ec19dae44e4e830506a8fec168;hp=e5fdce22f4da49b57f8c214a6387b92b49c89de7;hpb=cf70590c38ef580758c8a255519959fc7160fdb2;p=oota-llvm.git diff --git a/lib/Target/TargetLibraryInfo.cpp b/lib/Target/TargetLibraryInfo.cpp index e5fdce22f4d..616ff906730 100644 --- a/lib/Target/TargetLibraryInfo.cpp +++ b/lib/Target/TargetLibraryInfo.cpp @@ -27,7 +27,9 @@ const char* TargetLibraryInfo::StandardNames[LibFunc::NumLibFuncs] = "_IO_getc", "_IO_putc", "_ZdaPv", + "_ZdaPvRKSt9nothrow_t", "_ZdlPv", + "_ZdlPvRKSt9nothrow_t", "_Znaj", "_ZnajRKSt9nothrow_t", "_Znam", @@ -36,6 +38,8 @@ const char* TargetLibraryInfo::StandardNames[LibFunc::NumLibFuncs] = "_ZnwjRKSt9nothrow_t", "_Znwm", "_ZnwmRKSt9nothrow_t", + "__cospi", + "__cospif", "__cxa_atexit", "__cxa_guard_abort", "__cxa_guard_acquire", @@ -43,6 +47,13 @@ const char* TargetLibraryInfo::StandardNames[LibFunc::NumLibFuncs] = "__isoc99_scanf", "__isoc99_sscanf", "__memcpy_chk", + "__sincospi_stret", + "__sincospif_stret", + "__sinpi", + "__sinpif", + "__sqrt_finite", + "__sqrtf_finite", + "__sqrtl_finite", "__strdup", "__strndup", "__strtok_r", @@ -129,6 +140,12 @@ const char* TargetLibraryInfo::StandardNames[LibFunc::NumLibFuncs] = "floor", "floorf", "floorl", + "fmax", + "fmaxf", + "fmaxl", + "fmin", + "fminf", + "fminl", "fmod", "fmodf", "fmodl", @@ -165,6 +182,7 @@ const char* TargetLibraryInfo::StandardNames[LibFunc::NumLibFuncs] = "getlogin_r", "getpwnam", "gets", + "gettimeofday", "htonl", "htons", "iprintf", @@ -172,6 +190,9 @@ const char* TargetLibraryInfo::StandardNames[LibFunc::NumLibFuncs] = "isdigit", "labs", "lchown", + "ldexp", + "ldexpf", + "ldexpl", "llabs", "log", "log10", @@ -325,6 +346,24 @@ const char* TargetLibraryInfo::StandardNames[LibFunc::NumLibFuncs] = "write" }; +static bool hasSinCosPiStret(const Triple &T) { + // Only Darwin variants have _stret versions of combined trig functions. + if (!T.isMacOSX() && T.getOS() != Triple::IOS) + return false; + + // The ABI is rather complicated on x86, so don't do anything special there. + if (T.getArch() == Triple::x86) + return false; + + if (T.isMacOSX() && T.isMacOSXVersionLT(10, 9)) + return false; + + if (T.getOS() == Triple::IOS && T.isOSVersionLT(7, 0)) + return false; + + return true; +} + /// initialize - 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. @@ -339,18 +378,36 @@ static void initialize(TargetLibraryInfo &TLI, const Triple &T, llvm_unreachable("TargetLibraryInfo function names must be sorted"); } #endif // !NDEBUG - - // memset_pattern16 is only available on iOS 3.0 and Mac OS/X 10.5 and later. + + // There are no library implementations of mempcy and memset for r600 and + // these can be difficult to lower in the backend. + if (T.getArch() == Triple::r600) { + TLI.setUnavailable(LibFunc::memcpy); + TLI.setUnavailable(LibFunc::memset); + TLI.setUnavailable(LibFunc::memset_pattern16); + return; + } + + // memset_pattern16 is only available on iOS 3.0 and Mac OS X 10.5 and later. if (T.isMacOSX()) { if (T.isMacOSXVersionLT(10, 5)) TLI.setUnavailable(LibFunc::memset_pattern16); - } else if (T.getOS() == Triple::IOS) { + } else if (T.isiOS()) { if (T.isOSVersionLT(3, 0)) TLI.setUnavailable(LibFunc::memset_pattern16); } else { TLI.setUnavailable(LibFunc::memset_pattern16); } + if (!hasSinCosPiStret(T)) { + TLI.setUnavailable(LibFunc::sinpi); + TLI.setUnavailable(LibFunc::sinpif); + TLI.setUnavailable(LibFunc::cospi); + TLI.setUnavailable(LibFunc::cospif); + TLI.setUnavailable(LibFunc::sincospi_stret); + TLI.setUnavailable(LibFunc::sincospif_stret); + } + if (T.isMacOSX() && T.getArch() == Triple::x86 && !T.isMacOSXVersionLT(10, 7)) { // x86-32 OSX has a scheme where fwrite and fputs (and some other functions @@ -369,7 +426,7 @@ static void initialize(TargetLibraryInfo &TLI, const Triple &T, TLI.setUnavailable(LibFunc::fiprintf); } - if (T.getOS() == Triple::Win32) { + if (T.isOSWindows() && !T.isOSCygMing()) { // Win32 does not support long double TLI.setUnavailable(LibFunc::acosl); TLI.setUnavailable(LibFunc::asinl); @@ -383,8 +440,12 @@ static void initialize(TargetLibraryInfo &TLI, const Triple &T, TLI.setUnavailable(LibFunc::fabsf); // Win32 and Win64 both lack fabsf TLI.setUnavailable(LibFunc::fabsl); TLI.setUnavailable(LibFunc::floorl); + TLI.setUnavailable(LibFunc::fmaxl); + TLI.setUnavailable(LibFunc::fminl); TLI.setUnavailable(LibFunc::fmodl); TLI.setUnavailable(LibFunc::frexpl); + TLI.setUnavailable(LibFunc::ldexpf); + TLI.setUnavailable(LibFunc::ldexpl); TLI.setUnavailable(LibFunc::logl); TLI.setUnavailable(LibFunc::modfl); TLI.setUnavailable(LibFunc::powl); @@ -407,9 +468,6 @@ static void initialize(TargetLibraryInfo &TLI, const Triple &T, TLI.setUnavailable(LibFunc::cbrt); TLI.setUnavailable(LibFunc::cbrtf); TLI.setUnavailable(LibFunc::cbrtl); - TLI.setUnavailable(LibFunc::exp10); - TLI.setUnavailable(LibFunc::exp10f); - TLI.setUnavailable(LibFunc::exp10l); TLI.setUnavailable(LibFunc::exp2); TLI.setUnavailable(LibFunc::exp2f); TLI.setUnavailable(LibFunc::exp2l); @@ -453,6 +511,8 @@ static void initialize(TargetLibraryInfo &TLI, const Triple &T, TLI.setUnavailable(LibFunc::coshf); TLI.setUnavailable(LibFunc::expf); TLI.setUnavailable(LibFunc::floorf); + TLI.setUnavailable(LibFunc::fminf); + TLI.setUnavailable(LibFunc::fmaxf); TLI.setUnavailable(LibFunc::fmodf); TLI.setUnavailable(LibFunc::logf); TLI.setUnavailable(LibFunc::powf); @@ -487,6 +547,7 @@ static void initialize(TargetLibraryInfo &TLI, const Triple &T, 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); @@ -527,6 +588,43 @@ static void initialize(TargetLibraryInfo &TLI, const Triple &T, TLI.setUnavailable(LibFunc::llabs); } + switch (T.getOS()) { + case Triple::MacOSX: + // exp10 and exp10f are not available on OS X until 10.9 and iOS until 7.0 + // and their names are __exp10 and __exp10f. exp10l is not available on + // OS X or iOS. + TLI.setUnavailable(LibFunc::exp10l); + if (T.isMacOSXVersionLT(10, 9)) { + TLI.setUnavailable(LibFunc::exp10); + TLI.setUnavailable(LibFunc::exp10f); + } else { + TLI.setAvailableWithName(LibFunc::exp10, "__exp10"); + TLI.setAvailableWithName(LibFunc::exp10f, "__exp10f"); + } + break; + case Triple::IOS: + TLI.setUnavailable(LibFunc::exp10l); + if (T.isOSVersionLT(7, 0)) { + TLI.setUnavailable(LibFunc::exp10); + TLI.setUnavailable(LibFunc::exp10f); + } else { + TLI.setAvailableWithName(LibFunc::exp10, "__exp10"); + TLI.setAvailableWithName(LibFunc::exp10f, "__exp10f"); + } + break; + case Triple::Linux: + // exp10, exp10f, exp10l is available on Linux (GLIBC) but are extremely + // buggy prior to glibc version 2.18. Until this version is widely deployed + // or we have a reasonable detection strategy, we cannot use exp10 reliably + // on Linux. + // + // Fall through to disable all of them. + default: + TLI.setUnavailable(LibFunc::exp10); + TLI.setUnavailable(LibFunc::exp10f); + TLI.setUnavailable(LibFunc::exp10l); + } + // ffsl is available on at least Darwin, Mac OS X, iOS, FreeBSD, and // Linux (GLIBC): // http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man3/ffsl.3.html @@ -555,7 +653,7 @@ static void initialize(TargetLibraryInfo &TLI, const Triple &T, } // The following functions are available on at least Linux: - if (T.getOS() != Triple::Linux) { + if (!T.isOSLinux()) { TLI.setUnavailable(LibFunc::dunder_strdup); TLI.setUnavailable(LibFunc::dunder_strtok_r); TLI.setUnavailable(LibFunc::dunder_isoc99_scanf); @@ -597,15 +695,40 @@ TargetLibraryInfo::TargetLibraryInfo(const TargetLibraryInfo &TLI) CustomNames = TLI.CustomNames; } +namespace { +struct StringComparator { + /// Compare two strings and return true if LHS is lexicographically less than + /// RHS. Requires that RHS doesn't contain any zero bytes. + bool operator()(const char *LHS, StringRef RHS) const { + // Compare prefixes with strncmp. If prefixes match we know that LHS is + // greater or equal to RHS as RHS can't contain any '\0'. + return std::strncmp(LHS, RHS.data(), RHS.size()) < 0; + } + + // Provided for compatibility with MSVC's debug mode. + bool operator()(StringRef LHS, const char *RHS) const { return LHS < RHS; } + bool operator()(StringRef LHS, StringRef RHS) const { return LHS < RHS; } + bool operator()(const char *LHS, const char *RHS) const { + return std::strcmp(LHS, RHS) < 0; + } +}; +} + bool TargetLibraryInfo::getLibFunc(StringRef funcName, LibFunc::Func &F) const { const char **Start = &StandardNames[0]; const char **End = &StandardNames[LibFunc::NumLibFuncs]; + + // Filter out empty names and names containing null bytes, those can't be in + // our table. + if (funcName.empty() || funcName.find('\0') != StringRef::npos) + return false; + // Check for \01 prefix that is used to mangle __asm declarations and // strip it if present. - if (!funcName.empty() && funcName.front() == '\01') + if (funcName.front() == '\01') funcName = funcName.substr(1); - const char **I = std::lower_bound(Start, End, funcName); + const char **I = std::lower_bound(Start, End, funcName, StringComparator()); if (I != End && *I == funcName) { F = (LibFunc::Func)(I - Start); return true;