162d4215bSChandler Carruth //===-- TargetLibraryInfo.cpp - Runtime library information ----------------==// 262d4215bSChandler Carruth // 362d4215bSChandler Carruth // The LLVM Compiler Infrastructure 462d4215bSChandler Carruth // 562d4215bSChandler Carruth // This file is distributed under the University of Illinois Open Source 662d4215bSChandler Carruth // License. See LICENSE.TXT for details. 762d4215bSChandler Carruth // 862d4215bSChandler Carruth //===----------------------------------------------------------------------===// 962d4215bSChandler Carruth // 1062d4215bSChandler Carruth // This file implements the TargetLibraryInfo class. 1162d4215bSChandler Carruth // 1262d4215bSChandler Carruth //===----------------------------------------------------------------------===// 1362d4215bSChandler Carruth 1462d4215bSChandler Carruth #include "llvm/Analysis/TargetLibraryInfo.h" 1562d4215bSChandler Carruth #include "llvm/ADT/Triple.h" 1662d4215bSChandler Carruth using namespace llvm; 1762d4215bSChandler Carruth 18c0291865SChandler Carruth const char* TargetLibraryInfoImpl::StandardNames[LibFunc::NumLibFuncs] = 1962d4215bSChandler Carruth { 20*cd3d25a2SJan Wen Voung #define TLI_DEFINE_STRING 21*cd3d25a2SJan Wen Voung #include "llvm/Analysis/TargetLibraryInfo.def" 2262d4215bSChandler Carruth }; 2362d4215bSChandler Carruth 2462d4215bSChandler Carruth static bool hasSinCosPiStret(const Triple &T) { 2562d4215bSChandler Carruth // Only Darwin variants have _stret versions of combined trig functions. 2662d4215bSChandler Carruth if (!T.isOSDarwin()) 2762d4215bSChandler Carruth return false; 2862d4215bSChandler Carruth 2962d4215bSChandler Carruth // The ABI is rather complicated on x86, so don't do anything special there. 3062d4215bSChandler Carruth if (T.getArch() == Triple::x86) 3162d4215bSChandler Carruth return false; 3262d4215bSChandler Carruth 3362d4215bSChandler Carruth if (T.isMacOSX() && T.isMacOSXVersionLT(10, 9)) 3462d4215bSChandler Carruth return false; 3562d4215bSChandler Carruth 3662d4215bSChandler Carruth if (T.isiOS() && T.isOSVersionLT(7, 0)) 3762d4215bSChandler Carruth return false; 3862d4215bSChandler Carruth 3962d4215bSChandler Carruth return true; 4062d4215bSChandler Carruth } 4162d4215bSChandler Carruth 4262d4215bSChandler Carruth /// initialize - Initialize the set of available library functions based on the 4362d4215bSChandler Carruth /// specified target triple. This should be carefully written so that a missing 4462d4215bSChandler Carruth /// target triple gets a sane set of defaults. 45c0291865SChandler Carruth static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, 4662d4215bSChandler Carruth const char **StandardNames) { 4762d4215bSChandler Carruth #ifndef NDEBUG 4862d4215bSChandler Carruth // Verify that the StandardNames array is in alphabetical order. 4962d4215bSChandler Carruth for (unsigned F = 1; F < LibFunc::NumLibFuncs; ++F) { 5062d4215bSChandler Carruth if (strcmp(StandardNames[F-1], StandardNames[F]) >= 0) 51c0291865SChandler Carruth llvm_unreachable("TargetLibraryInfoImpl function names must be sorted"); 5262d4215bSChandler Carruth } 5362d4215bSChandler Carruth #endif // !NDEBUG 5462d4215bSChandler Carruth 5562d4215bSChandler Carruth // There are no library implementations of mempcy and memset for AMD gpus and 5662d4215bSChandler Carruth // these can be difficult to lower in the backend. 5762d4215bSChandler Carruth if (T.getArch() == Triple::r600 || 5862d4215bSChandler Carruth T.getArch() == Triple::amdgcn) { 5962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::memcpy); 6062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::memset); 6162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::memset_pattern16); 6262d4215bSChandler Carruth return; 6362d4215bSChandler Carruth } 6462d4215bSChandler Carruth 6562d4215bSChandler Carruth // memset_pattern16 is only available on iOS 3.0 and Mac OS X 10.5 and later. 6662d4215bSChandler Carruth if (T.isMacOSX()) { 6762d4215bSChandler Carruth if (T.isMacOSXVersionLT(10, 5)) 6862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::memset_pattern16); 6962d4215bSChandler Carruth } else if (T.isiOS()) { 7062d4215bSChandler Carruth if (T.isOSVersionLT(3, 0)) 7162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::memset_pattern16); 7262d4215bSChandler Carruth } else { 7362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::memset_pattern16); 7462d4215bSChandler Carruth } 7562d4215bSChandler Carruth 7662d4215bSChandler Carruth if (!hasSinCosPiStret(T)) { 7762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::sinpi); 7862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::sinpif); 7962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::cospi); 8062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::cospif); 8162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::sincospi_stret); 8262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::sincospif_stret); 8362d4215bSChandler Carruth } 8462d4215bSChandler Carruth 8562d4215bSChandler Carruth if (T.isMacOSX() && T.getArch() == Triple::x86 && 8662d4215bSChandler Carruth !T.isMacOSXVersionLT(10, 7)) { 8762d4215bSChandler Carruth // x86-32 OSX has a scheme where fwrite and fputs (and some other functions 8862d4215bSChandler Carruth // we don't care about) have two versions; on recent OSX, the one we want 8962d4215bSChandler Carruth // has a $UNIX2003 suffix. The two implementations are identical except 9062d4215bSChandler Carruth // for the return value in some edge cases. However, we don't want to 9162d4215bSChandler Carruth // generate code that depends on the old symbols. 9262d4215bSChandler Carruth TLI.setAvailableWithName(LibFunc::fwrite, "fwrite$UNIX2003"); 9362d4215bSChandler Carruth TLI.setAvailableWithName(LibFunc::fputs, "fputs$UNIX2003"); 9462d4215bSChandler Carruth } 9562d4215bSChandler Carruth 9662d4215bSChandler Carruth // iprintf and friends are only available on XCore and TCE. 9762d4215bSChandler Carruth if (T.getArch() != Triple::xcore && T.getArch() != Triple::tce) { 9862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::iprintf); 9962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::siprintf); 10062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fiprintf); 10162d4215bSChandler Carruth } 10262d4215bSChandler Carruth 10362d4215bSChandler Carruth if (T.isOSWindows() && !T.isOSCygMing()) { 10462d4215bSChandler Carruth // Win32 does not support long double 10562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::acosl); 10662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::asinl); 10762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::atanl); 10862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::atan2l); 10962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ceill); 11062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::copysignl); 11162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::cosl); 11262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::coshl); 11362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::expl); 11462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fabsf); // Win32 and Win64 both lack fabsf 11562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fabsl); 11662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::floorl); 11762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fmaxl); 11862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fminl); 11962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fmodl); 12062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::frexpl); 12162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ldexpf); 12262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ldexpl); 12362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::logl); 12462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::modfl); 12562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::powl); 12662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::sinl); 12762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::sinhl); 12862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::sqrtl); 12962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::tanl); 13062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::tanhl); 13162d4215bSChandler Carruth 13262d4215bSChandler Carruth // Win32 only has C89 math 13362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::acosh); 13462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::acoshf); 13562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::acoshl); 13662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::asinh); 13762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::asinhf); 13862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::asinhl); 13962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::atanh); 14062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::atanhf); 14162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::atanhl); 14262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::cbrt); 14362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::cbrtf); 14462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::cbrtl); 14562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::exp2); 14662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::exp2f); 14762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::exp2l); 14862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::expm1); 14962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::expm1f); 15062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::expm1l); 15162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::log2); 15262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::log2f); 15362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::log2l); 15462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::log1p); 15562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::log1pf); 15662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::log1pl); 15762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::logb); 15862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::logbf); 15962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::logbl); 16062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::nearbyint); 16162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::nearbyintf); 16262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::nearbyintl); 16362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::rint); 16462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::rintf); 16562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::rintl); 16662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::round); 16762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::roundf); 16862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::roundl); 16962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::trunc); 17062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::truncf); 17162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::truncl); 17262d4215bSChandler Carruth 17362d4215bSChandler Carruth // Win32 provides some C99 math with mangled names 17462d4215bSChandler Carruth TLI.setAvailableWithName(LibFunc::copysign, "_copysign"); 17562d4215bSChandler Carruth 17662d4215bSChandler Carruth if (T.getArch() == Triple::x86) { 17762d4215bSChandler Carruth // Win32 on x86 implements single-precision math functions as macros 17862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::acosf); 17962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::asinf); 18062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::atanf); 18162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::atan2f); 18262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ceilf); 18362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::copysignf); 18462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::cosf); 18562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::coshf); 18662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::expf); 18762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::floorf); 18862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fminf); 18962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fmaxf); 19062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fmodf); 19162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::logf); 19262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::powf); 19362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::sinf); 19462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::sinhf); 19562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::sqrtf); 19662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::tanf); 19762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::tanhf); 19862d4215bSChandler Carruth } 19962d4215bSChandler Carruth 20062d4215bSChandler Carruth // Win32 does *not* provide provide these functions, but they are 20162d4215bSChandler Carruth // generally available on POSIX-compliant systems: 20262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::access); 20362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::bcmp); 20462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::bcopy); 20562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::bzero); 20662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::chmod); 20762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::chown); 20862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::closedir); 20962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ctermid); 21062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fdopen); 21162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ffs); 21262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fileno); 21362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::flockfile); 21462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fseeko); 21562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fstat); 21662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fstatvfs); 21762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ftello); 21862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ftrylockfile); 21962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::funlockfile); 22062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::getc_unlocked); 22162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::getitimer); 22262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::getlogin_r); 22362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::getpwnam); 22462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::gettimeofday); 22562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::htonl); 22662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::htons); 22762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::lchown); 22862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::lstat); 22962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::memccpy); 23062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::mkdir); 23162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ntohl); 23262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ntohs); 23362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::open); 23462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::opendir); 23562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::pclose); 23662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::popen); 23762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::pread); 23862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::pwrite); 23962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::read); 24062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::readlink); 24162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::realpath); 24262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::rmdir); 24362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::setitimer); 24462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::stat); 24562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::statvfs); 24662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::stpcpy); 24762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::stpncpy); 24862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::strcasecmp); 24962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::strncasecmp); 25062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::times); 25162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::uname); 25262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::unlink); 25362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::unsetenv); 25462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::utime); 25562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::utimes); 25662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::write); 25762d4215bSChandler Carruth 25862d4215bSChandler Carruth // Win32 does *not* provide provide these functions, but they are 25962d4215bSChandler Carruth // specified by C99: 26062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::atoll); 26162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::frexpf); 26262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::llabs); 26362d4215bSChandler Carruth } 26462d4215bSChandler Carruth 26562d4215bSChandler Carruth switch (T.getOS()) { 26662d4215bSChandler Carruth case Triple::MacOSX: 26762d4215bSChandler Carruth // exp10 and exp10f are not available on OS X until 10.9 and iOS until 7.0 26862d4215bSChandler Carruth // and their names are __exp10 and __exp10f. exp10l is not available on 26962d4215bSChandler Carruth // OS X or iOS. 27062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::exp10l); 27162d4215bSChandler Carruth if (T.isMacOSXVersionLT(10, 9)) { 27262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::exp10); 27362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::exp10f); 27462d4215bSChandler Carruth } else { 27562d4215bSChandler Carruth TLI.setAvailableWithName(LibFunc::exp10, "__exp10"); 27662d4215bSChandler Carruth TLI.setAvailableWithName(LibFunc::exp10f, "__exp10f"); 27762d4215bSChandler Carruth } 27862d4215bSChandler Carruth break; 27962d4215bSChandler Carruth case Triple::IOS: 28062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::exp10l); 28162d4215bSChandler Carruth if (T.isOSVersionLT(7, 0)) { 28262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::exp10); 28362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::exp10f); 28462d4215bSChandler Carruth } else { 28562d4215bSChandler Carruth TLI.setAvailableWithName(LibFunc::exp10, "__exp10"); 28662d4215bSChandler Carruth TLI.setAvailableWithName(LibFunc::exp10f, "__exp10f"); 28762d4215bSChandler Carruth } 28862d4215bSChandler Carruth break; 28962d4215bSChandler Carruth case Triple::Linux: 29062d4215bSChandler Carruth // exp10, exp10f, exp10l is available on Linux (GLIBC) but are extremely 29162d4215bSChandler Carruth // buggy prior to glibc version 2.18. Until this version is widely deployed 29262d4215bSChandler Carruth // or we have a reasonable detection strategy, we cannot use exp10 reliably 29362d4215bSChandler Carruth // on Linux. 29462d4215bSChandler Carruth // 29562d4215bSChandler Carruth // Fall through to disable all of them. 29662d4215bSChandler Carruth default: 29762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::exp10); 29862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::exp10f); 29962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::exp10l); 30062d4215bSChandler Carruth } 30162d4215bSChandler Carruth 30262d4215bSChandler Carruth // ffsl is available on at least Darwin, Mac OS X, iOS, FreeBSD, and 30362d4215bSChandler Carruth // Linux (GLIBC): 30462d4215bSChandler Carruth // http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man3/ffsl.3.html 30562d4215bSChandler Carruth // http://svn.freebsd.org/base/user/eri/pf45/head/lib/libc/string/ffsl.c 30662d4215bSChandler Carruth // http://www.gnu.org/software/gnulib/manual/html_node/ffsl.html 30762d4215bSChandler Carruth switch (T.getOS()) { 30862d4215bSChandler Carruth case Triple::Darwin: 30962d4215bSChandler Carruth case Triple::MacOSX: 31062d4215bSChandler Carruth case Triple::IOS: 31162d4215bSChandler Carruth case Triple::FreeBSD: 31262d4215bSChandler Carruth case Triple::Linux: 31362d4215bSChandler Carruth break; 31462d4215bSChandler Carruth default: 31562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ffsl); 31662d4215bSChandler Carruth } 31762d4215bSChandler Carruth 31862d4215bSChandler Carruth // ffsll is available on at least FreeBSD and Linux (GLIBC): 31962d4215bSChandler Carruth // http://svn.freebsd.org/base/user/eri/pf45/head/lib/libc/string/ffsll.c 32062d4215bSChandler Carruth // http://www.gnu.org/software/gnulib/manual/html_node/ffsll.html 32162d4215bSChandler Carruth switch (T.getOS()) { 32262d4215bSChandler Carruth case Triple::FreeBSD: 32362d4215bSChandler Carruth case Triple::Linux: 32462d4215bSChandler Carruth break; 32562d4215bSChandler Carruth default: 32662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ffsll); 32762d4215bSChandler Carruth } 32862d4215bSChandler Carruth 32962d4215bSChandler Carruth // The following functions are available on at least Linux: 33062d4215bSChandler Carruth if (!T.isOSLinux()) { 33162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::dunder_strdup); 33262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::dunder_strtok_r); 33362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::dunder_isoc99_scanf); 33462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::dunder_isoc99_sscanf); 33562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::under_IO_getc); 33662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::under_IO_putc); 33762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::memalign); 33862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fopen64); 33962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fseeko64); 34062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fstat64); 34162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fstatvfs64); 34262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ftello64); 34362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::lstat64); 34462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::open64); 34562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::stat64); 34662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::statvfs64); 34762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::tmpfile64); 34862d4215bSChandler Carruth } 34962d4215bSChandler Carruth } 35062d4215bSChandler Carruth 351c0291865SChandler Carruth TargetLibraryInfoImpl::TargetLibraryInfoImpl() { 35262d4215bSChandler Carruth // Default to everything being available. 35362d4215bSChandler Carruth memset(AvailableArray, -1, sizeof(AvailableArray)); 35462d4215bSChandler Carruth 35562d4215bSChandler Carruth initialize(*this, Triple(), StandardNames); 35662d4215bSChandler Carruth } 35762d4215bSChandler Carruth 358c0291865SChandler Carruth TargetLibraryInfoImpl::TargetLibraryInfoImpl(const Triple &T) { 35962d4215bSChandler Carruth // Default to everything being available. 36062d4215bSChandler Carruth memset(AvailableArray, -1, sizeof(AvailableArray)); 36162d4215bSChandler Carruth 36262d4215bSChandler Carruth initialize(*this, T, StandardNames); 36362d4215bSChandler Carruth } 36462d4215bSChandler Carruth 365c0291865SChandler Carruth TargetLibraryInfoImpl::TargetLibraryInfoImpl(const TargetLibraryInfoImpl &TLI) 3668ca43224SChandler Carruth : CustomNames(TLI.CustomNames) { 36762d4215bSChandler Carruth memcpy(AvailableArray, TLI.AvailableArray, sizeof(AvailableArray)); 3688ca43224SChandler Carruth } 3698ca43224SChandler Carruth 370c0291865SChandler Carruth TargetLibraryInfoImpl::TargetLibraryInfoImpl(TargetLibraryInfoImpl &&TLI) 3718ca43224SChandler Carruth : CustomNames(std::move(TLI.CustomNames)) { 3728ca43224SChandler Carruth std::move(std::begin(TLI.AvailableArray), std::end(TLI.AvailableArray), 3738ca43224SChandler Carruth AvailableArray); 3748ca43224SChandler Carruth } 3758ca43224SChandler Carruth 376c0291865SChandler Carruth TargetLibraryInfoImpl &TargetLibraryInfoImpl::operator=(const TargetLibraryInfoImpl &TLI) { 37762d4215bSChandler Carruth CustomNames = TLI.CustomNames; 3788ca43224SChandler Carruth memcpy(AvailableArray, TLI.AvailableArray, sizeof(AvailableArray)); 3798ca43224SChandler Carruth return *this; 3808ca43224SChandler Carruth } 3818ca43224SChandler Carruth 382c0291865SChandler Carruth TargetLibraryInfoImpl &TargetLibraryInfoImpl::operator=(TargetLibraryInfoImpl &&TLI) { 3838ca43224SChandler Carruth CustomNames = std::move(TLI.CustomNames); 3848ca43224SChandler Carruth std::move(std::begin(TLI.AvailableArray), std::end(TLI.AvailableArray), 3858ca43224SChandler Carruth AvailableArray); 3868ca43224SChandler Carruth return *this; 38762d4215bSChandler Carruth } 38862d4215bSChandler Carruth 38921abdf98SMichael Zolotukhin static StringRef sanitizeFunctionName(StringRef funcName) { 39062d4215bSChandler Carruth // Filter out empty names and names containing null bytes, those can't be in 39162d4215bSChandler Carruth // our table. 39262d4215bSChandler Carruth if (funcName.empty() || funcName.find('\0') != StringRef::npos) 39321abdf98SMichael Zolotukhin return StringRef(); 39462d4215bSChandler Carruth 39562d4215bSChandler Carruth // Check for \01 prefix that is used to mangle __asm declarations and 39662d4215bSChandler Carruth // strip it if present. 39762d4215bSChandler Carruth if (funcName.front() == '\01') 39862d4215bSChandler Carruth funcName = funcName.substr(1); 39921abdf98SMichael Zolotukhin return funcName; 40021abdf98SMichael Zolotukhin } 40121abdf98SMichael Zolotukhin 40221abdf98SMichael Zolotukhin bool TargetLibraryInfoImpl::getLibFunc(StringRef funcName, 40321abdf98SMichael Zolotukhin LibFunc::Func &F) const { 40421abdf98SMichael Zolotukhin const char **Start = &StandardNames[0]; 40521abdf98SMichael Zolotukhin const char **End = &StandardNames[LibFunc::NumLibFuncs]; 40621abdf98SMichael Zolotukhin 40721abdf98SMichael Zolotukhin funcName = sanitizeFunctionName(funcName); 40821abdf98SMichael Zolotukhin if (funcName.empty()) 40921abdf98SMichael Zolotukhin return false; 41021abdf98SMichael Zolotukhin 411d3b76a3bSMichael Zolotukhin const char **I = std::lower_bound( 412d3b76a3bSMichael Zolotukhin Start, End, funcName, [](const char *LHS, StringRef RHS) { 413d3b76a3bSMichael Zolotukhin return std::strncmp(LHS, RHS.data(), RHS.size()) < 0; 414d3b76a3bSMichael Zolotukhin }); 41562d4215bSChandler Carruth if (I != End && *I == funcName) { 41662d4215bSChandler Carruth F = (LibFunc::Func)(I - Start); 41762d4215bSChandler Carruth return true; 41862d4215bSChandler Carruth } 41962d4215bSChandler Carruth return false; 42062d4215bSChandler Carruth } 42162d4215bSChandler Carruth 422c0291865SChandler Carruth void TargetLibraryInfoImpl::disableAllFunctions() { 42362d4215bSChandler Carruth memset(AvailableArray, 0, sizeof(AvailableArray)); 42462d4215bSChandler Carruth } 425b98f63dbSChandler Carruth 426c0291865SChandler Carruth TargetLibraryInfo TargetLibraryAnalysis::run(Module &M) { 427c0291865SChandler Carruth if (PresetInfoImpl) 428c0291865SChandler Carruth return TargetLibraryInfo(*PresetInfoImpl); 429c0291865SChandler Carruth 430c0291865SChandler Carruth return TargetLibraryInfo(lookupInfoImpl(Triple(M.getTargetTriple()))); 431c0291865SChandler Carruth } 432c0291865SChandler Carruth 433c0291865SChandler Carruth TargetLibraryInfo TargetLibraryAnalysis::run(Function &F) { 434c0291865SChandler Carruth if (PresetInfoImpl) 435c0291865SChandler Carruth return TargetLibraryInfo(*PresetInfoImpl); 436c0291865SChandler Carruth 437c0291865SChandler Carruth return TargetLibraryInfo( 438c0291865SChandler Carruth lookupInfoImpl(Triple(F.getParent()->getTargetTriple()))); 439c0291865SChandler Carruth } 440c0291865SChandler Carruth 441c0291865SChandler Carruth TargetLibraryInfoImpl &TargetLibraryAnalysis::lookupInfoImpl(Triple T) { 442c0291865SChandler Carruth std::unique_ptr<TargetLibraryInfoImpl> &Impl = 443c0291865SChandler Carruth Impls[T.normalize()]; 444c0291865SChandler Carruth if (!Impl) 445c0291865SChandler Carruth Impl.reset(new TargetLibraryInfoImpl(T)); 446c0291865SChandler Carruth 447c0291865SChandler Carruth return *Impl; 448c0291865SChandler Carruth } 449c0291865SChandler Carruth 450c0291865SChandler Carruth 451b98f63dbSChandler Carruth TargetLibraryInfoWrapperPass::TargetLibraryInfoWrapperPass() 452c0291865SChandler Carruth : ImmutablePass(ID), TLIImpl(), TLI(TLIImpl) { 453b98f63dbSChandler Carruth initializeTargetLibraryInfoWrapperPassPass(*PassRegistry::getPassRegistry()); 454b98f63dbSChandler Carruth } 455b98f63dbSChandler Carruth 456b98f63dbSChandler Carruth TargetLibraryInfoWrapperPass::TargetLibraryInfoWrapperPass(const Triple &T) 457c0291865SChandler Carruth : ImmutablePass(ID), TLIImpl(T), TLI(TLIImpl) { 458b98f63dbSChandler Carruth initializeTargetLibraryInfoWrapperPassPass(*PassRegistry::getPassRegistry()); 459b98f63dbSChandler Carruth } 460b98f63dbSChandler Carruth 461b98f63dbSChandler Carruth TargetLibraryInfoWrapperPass::TargetLibraryInfoWrapperPass( 462c0291865SChandler Carruth const TargetLibraryInfoImpl &TLIImpl) 463c0291865SChandler Carruth : ImmutablePass(ID), TLIImpl(TLIImpl), TLI(this->TLIImpl) { 464b98f63dbSChandler Carruth initializeTargetLibraryInfoWrapperPassPass(*PassRegistry::getPassRegistry()); 465b98f63dbSChandler Carruth } 466b98f63dbSChandler Carruth 4678ca43224SChandler Carruth char TargetLibraryAnalysis::PassID; 4688ca43224SChandler Carruth 469b98f63dbSChandler Carruth // Register the basic pass. 470b98f63dbSChandler Carruth INITIALIZE_PASS(TargetLibraryInfoWrapperPass, "targetlibinfo", 471b98f63dbSChandler Carruth "Target Library Information", false, true) 472b98f63dbSChandler Carruth char TargetLibraryInfoWrapperPass::ID = 0; 473b98f63dbSChandler Carruth 474b98f63dbSChandler Carruth void TargetLibraryInfoWrapperPass::anchor() {} 475