static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) { if (TT.isOSBinFormatMachO()) { if (TT.getArch() == Triple::x86_64) return make_unique<X86_64MachoTargetObjectFile>(); return make_unique<TargetLoweringObjectFileMachO>(); } if (TT.isOSFreeBSD()) return make_unique<X86FreeBSDTargetObjectFile>(); if (TT.isOSLinux() || TT.isOSNaCl()) return make_unique<X86LinuxNaClTargetObjectFile>(); if (TT.isOSFuchsia()) return make_unique<X86FuchsiaTargetObjectFile>(); if (TT.isOSBinFormatELF()) return make_unique<X86ELFTargetObjectFile>(); if (TT.isKnownWindowsMSVCEnvironment() || TT.isWindowsCoreCLREnvironment()) return make_unique<X86WindowsTargetObjectFile>(); if (TT.isOSBinFormatCOFF()) return make_unique<TargetLoweringObjectFileCOFF>(); llvm_unreachable("unknown subtarget type"); }
static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) { if (TT.isOSBinFormatMachO()) { if (TT.getArch() == Triple::x86_64) return llvm::make_unique<X86_64MachoTargetObjectFile>(); return llvm::make_unique<TargetLoweringObjectFileMachO>(); } if (TT.isOSFreeBSD()) return llvm::make_unique<X86FreeBSDTargetObjectFile>(); if (TT.isOSLinux() || TT.isOSNaCl() || TT.isOSIAMCU()) return llvm::make_unique<X86LinuxNaClTargetObjectFile>(); if (TT.isOSSolaris()) return llvm::make_unique<X86SolarisTargetObjectFile>(); if (TT.isOSFuchsia()) return llvm::make_unique<X86FuchsiaTargetObjectFile>(); if (TT.isOSBinFormatELF()) return llvm::make_unique<X86ELFTargetObjectFile>(); if (TT.isOSBinFormatCOFF()) return llvm::make_unique<TargetLoweringObjectFileCOFF>(); llvm_unreachable("unknown subtarget type"); }
void MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T) { switch (T.getArch()) { case Triple::mips: case Triple::mipsel: FDECFIEncoding = dwarf::DW_EH_PE_sdata4; break; case Triple::mips64: case Triple::mips64el: FDECFIEncoding = dwarf::DW_EH_PE_sdata8; break; case Triple::x86_64: FDECFIEncoding = dwarf::DW_EH_PE_pcrel | ((CMModel == CodeModel::Large) ? dwarf::DW_EH_PE_sdata8 : dwarf::DW_EH_PE_sdata4); break; default: FDECFIEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; break; } switch (T.getArch()) { case Triple::arm: case Triple::armeb: case Triple::thumb: case Triple::thumbeb: if (Ctx->getAsmInfo()->getExceptionHandlingType() == ExceptionHandling::ARM) break; // Fallthrough if not using EHABI LLVM_FALLTHROUGH; case Triple::ppc: case Triple::x86: PersonalityEncoding = PositionIndependent ? dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4 : dwarf::DW_EH_PE_absptr; LSDAEncoding = PositionIndependent ? dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4 : dwarf::DW_EH_PE_absptr; TTypeEncoding = PositionIndependent ? dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4 : dwarf::DW_EH_PE_absptr; break; case Triple::x86_64: if (PositionIndependent) { PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | ((CMModel == CodeModel::Small || CMModel == CodeModel::Medium) ? dwarf::DW_EH_PE_sdata4 : dwarf::DW_EH_PE_sdata8); LSDAEncoding = dwarf::DW_EH_PE_pcrel | (CMModel == CodeModel::Small ? dwarf::DW_EH_PE_sdata4 : dwarf::DW_EH_PE_sdata8); TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | ((CMModel == CodeModel::Small || CMModel == CodeModel::Medium) ? dwarf::DW_EH_PE_sdata4 : dwarf::DW_EH_PE_sdata8); } else { PersonalityEncoding = (CMModel == CodeModel::Small || CMModel == CodeModel::Medium) ? dwarf::DW_EH_PE_udata4 : dwarf::DW_EH_PE_absptr; LSDAEncoding = (CMModel == CodeModel::Small) ? dwarf::DW_EH_PE_udata4 : dwarf::DW_EH_PE_absptr; TTypeEncoding = (CMModel == CodeModel::Small) ? dwarf::DW_EH_PE_udata4 : dwarf::DW_EH_PE_absptr; } break; case Triple::hexagon: PersonalityEncoding = dwarf::DW_EH_PE_absptr; LSDAEncoding = dwarf::DW_EH_PE_absptr; FDECFIEncoding = dwarf::DW_EH_PE_absptr; TTypeEncoding = dwarf::DW_EH_PE_absptr; if (PositionIndependent) { PersonalityEncoding |= dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel; LSDAEncoding |= dwarf::DW_EH_PE_pcrel; FDECFIEncoding |= dwarf::DW_EH_PE_pcrel; TTypeEncoding |= dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel; } break; case Triple::aarch64: case Triple::aarch64_be: // The small model guarantees static code/data size < 4GB, but not where it // will be in memory. Most of these could end up >2GB away so even a signed // pc-relative 32-bit address is insufficient, theoretically. if (PositionIndependent) { PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8; LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8; TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8; } else { PersonalityEncoding = dwarf::DW_EH_PE_absptr; LSDAEncoding = dwarf::DW_EH_PE_absptr; TTypeEncoding = dwarf::DW_EH_PE_absptr; } break; case Triple::lanai: LSDAEncoding = dwarf::DW_EH_PE_absptr; PersonalityEncoding = dwarf::DW_EH_PE_absptr; TTypeEncoding = dwarf::DW_EH_PE_absptr; break; case Triple::mips: case Triple::mipsel: case Triple::mips64: case Triple::mips64el: // MIPS uses indirect pointer to refer personality functions and types, so // that the eh_frame section can be read-only. DW.ref.personality will be // generated for relocation. PersonalityEncoding = dwarf::DW_EH_PE_indirect; // FIXME: The N64 ABI probably ought to use DW_EH_PE_sdata8 but we can't // identify N64 from just a triple. TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; // We don't support PC-relative LSDA references in GAS so we use the default // DW_EH_PE_absptr for those. // FreeBSD must be explicit about the data size and using pcrel since it's // assembler/linker won't do the automatic conversion that the Linux tools // do. if (T.isOSFreeBSD()) { PersonalityEncoding |= dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; } break; case Triple::ppc64: case Triple::ppc64le: PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8; LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8; TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8; break; case Triple::sparcel: case Triple::sparc: if (PositionIndependent) { LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; } else { LSDAEncoding = dwarf::DW_EH_PE_absptr; PersonalityEncoding = dwarf::DW_EH_PE_absptr; TTypeEncoding = dwarf::DW_EH_PE_absptr; } break; case Triple::sparcv9: LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; if (PositionIndependent) { PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; } else { PersonalityEncoding = dwarf::DW_EH_PE_absptr; TTypeEncoding = dwarf::DW_EH_PE_absptr; } break; case Triple::systemz: // All currently-defined code models guarantee that 4-byte PC-relative // values will be in range. if (PositionIndependent) { PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; } else { PersonalityEncoding = dwarf::DW_EH_PE_absptr; LSDAEncoding = dwarf::DW_EH_PE_absptr; TTypeEncoding = dwarf::DW_EH_PE_absptr; } break; default: break; } unsigned EHSectionType = T.getArch() == Triple::x86_64 ? ELF::SHT_X86_64_UNWIND : ELF::SHT_PROGBITS; // Solaris requires different flags for .eh_frame to seemingly every other // platform. unsigned EHSectionFlags = ELF::SHF_ALLOC; if (T.isOSSolaris() && T.getArch() != Triple::x86_64) EHSectionFlags |= ELF::SHF_WRITE; // ELF BSSSection = Ctx->getELFSection(".bss", ELF::SHT_NOBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC); TextSection = Ctx->getELFSection(".text", ELF::SHT_PROGBITS, ELF::SHF_EXECINSTR | ELF::SHF_ALLOC); DataSection = Ctx->getELFSection(".data", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC); ReadOnlySection = Ctx->getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC); TLSDataSection = Ctx->getELFSection(".tdata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_TLS | ELF::SHF_WRITE); TLSBSSSection = Ctx->getELFSection( ".tbss", ELF::SHT_NOBITS, ELF::SHF_ALLOC | ELF::SHF_TLS | ELF::SHF_WRITE); DataRelROSection = Ctx->getELFSection(".data.rel.ro", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_WRITE); MergeableConst4Section = Ctx->getELFSection(".rodata.cst4", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_MERGE, 4, ""); MergeableConst8Section = Ctx->getELFSection(".rodata.cst8", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_MERGE, 8, ""); MergeableConst16Section = Ctx->getELFSection(".rodata.cst16", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_MERGE, 16, ""); MergeableConst32Section = Ctx->getELFSection(".rodata.cst32", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_MERGE, 32, ""); // Exception Handling Sections. // FIXME: We're emitting LSDA info into a readonly section on ELF, even though // it contains relocatable pointers. In PIC mode, this is probably a big // runtime hit for C++ apps. Either the contents of the LSDA need to be // adjusted or this should be a data section. LSDASection = Ctx->getELFSection(".gcc_except_table", ELF::SHT_PROGBITS, ELF::SHF_ALLOC); COFFDebugSymbolsSection = nullptr; COFFDebugTypesSection = nullptr; // Debug Info Sections. DwarfAbbrevSection = Ctx->getELFSection(".debug_abbrev", ELF::SHT_PROGBITS, 0, "section_abbrev"); DwarfInfoSection = Ctx->getELFSection(".debug_info", ELF::SHT_PROGBITS, 0, "section_info"); DwarfLineSection = Ctx->getELFSection(".debug_line", ELF::SHT_PROGBITS, 0); DwarfFrameSection = Ctx->getELFSection(".debug_frame", ELF::SHT_PROGBITS, 0); DwarfPubNamesSection = Ctx->getELFSection(".debug_pubnames", ELF::SHT_PROGBITS, 0); DwarfPubTypesSection = Ctx->getELFSection(".debug_pubtypes", ELF::SHT_PROGBITS, 0); DwarfGnuPubNamesSection = Ctx->getELFSection(".debug_gnu_pubnames", ELF::SHT_PROGBITS, 0); DwarfGnuPubTypesSection = Ctx->getELFSection(".debug_gnu_pubtypes", ELF::SHT_PROGBITS, 0); DwarfStrSection = Ctx->getELFSection(".debug_str", ELF::SHT_PROGBITS, ELF::SHF_MERGE | ELF::SHF_STRINGS, 1, ""); DwarfLocSection = Ctx->getELFSection(".debug_loc", ELF::SHT_PROGBITS, 0); DwarfARangesSection = Ctx->getELFSection(".debug_aranges", ELF::SHT_PROGBITS, 0); DwarfRangesSection = Ctx->getELFSection(".debug_ranges", ELF::SHT_PROGBITS, 0, "debug_range"); DwarfMacinfoSection = Ctx->getELFSection(".debug_macinfo", ELF::SHT_PROGBITS, 0, "debug_macinfo"); // DWARF5 Experimental Debug Info // Accelerator Tables DwarfAccelNamesSection = Ctx->getELFSection(".apple_names", ELF::SHT_PROGBITS, 0, "names_begin"); DwarfAccelObjCSection = Ctx->getELFSection(".apple_objc", ELF::SHT_PROGBITS, 0, "objc_begin"); DwarfAccelNamespaceSection = Ctx->getELFSection( ".apple_namespaces", ELF::SHT_PROGBITS, 0, "namespac_begin"); DwarfAccelTypesSection = Ctx->getELFSection(".apple_types", ELF::SHT_PROGBITS, 0, "types_begin"); // Fission Sections DwarfInfoDWOSection = Ctx->getELFSection(".debug_info.dwo", ELF::SHT_PROGBITS, 0); DwarfTypesDWOSection = Ctx->getELFSection(".debug_types.dwo", ELF::SHT_PROGBITS, 0); DwarfAbbrevDWOSection = Ctx->getELFSection(".debug_abbrev.dwo", ELF::SHT_PROGBITS, 0); DwarfStrDWOSection = Ctx->getELFSection(".debug_str.dwo", ELF::SHT_PROGBITS, ELF::SHF_MERGE | ELF::SHF_STRINGS, 1, ""); DwarfLineDWOSection = Ctx->getELFSection(".debug_line.dwo", ELF::SHT_PROGBITS, 0); DwarfLocDWOSection = Ctx->getELFSection(".debug_loc.dwo", ELF::SHT_PROGBITS, 0, "skel_loc"); DwarfStrOffDWOSection = Ctx->getELFSection(".debug_str_offsets.dwo", ELF::SHT_PROGBITS, 0); DwarfAddrSection = Ctx->getELFSection(".debug_addr", ELF::SHT_PROGBITS, 0, "addr_sec"); // DWP Sections DwarfCUIndexSection = Ctx->getELFSection(".debug_cu_index", ELF::SHT_PROGBITS, 0); DwarfTUIndexSection = Ctx->getELFSection(".debug_tu_index", ELF::SHT_PROGBITS, 0); StackMapSection = Ctx->getELFSection(".llvm_stackmaps", ELF::SHT_PROGBITS, ELF::SHF_ALLOC); FaultMapSection = Ctx->getELFSection(".llvm_faultmaps", ELF::SHT_PROGBITS, ELF::SHF_ALLOC); EHFrameSection = Ctx->getELFSection(".eh_frame", EHSectionType, EHSectionFlags); }
/// 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. static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, ArrayRef<const char *> 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; }) && "TargetLibraryInfoImpl function names must be sorted"); if (T.getArch() == Triple::r600 || T.getArch() == Triple::amdgcn) { TLI.setUnavailable(LibFunc::ldexp); TLI.setUnavailable(LibFunc::ldexpf); TLI.setUnavailable(LibFunc::ldexpl); } // There are no library implementations of mempcy and memset for AMD gpus and // these can be difficult to lower in the backend. if (T.getArch() == Triple::r600 || T.getArch() == Triple::amdgcn) { 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. // All versions of watchOS support it. if (T.isMacOSX()) { if (T.isMacOSXVersionLT(10, 5)) TLI.setUnavailable(LibFunc::memset_pattern16); } else if (T.isiOS()) { if (T.isOSVersionLT(3, 0)) TLI.setUnavailable(LibFunc::memset_pattern16); } else if (!T.isWatchOS()) { 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 // we don't care about) have two versions; on recent OSX, the one we want // has a $UNIX2003 suffix. The two implementations are identical except // for the return value in some edge cases. However, we don't want to // generate code that depends on the old symbols. TLI.setAvailableWithName(LibFunc::fwrite, "fwrite$UNIX2003"); TLI.setAvailableWithName(LibFunc::fputs, "fputs$UNIX2003"); } // iprintf and friends are only available on XCore and TCE. if (T.getArch() != Triple::xcore && T.getArch() != Triple::tce) { TLI.setUnavailable(LibFunc::iprintf); TLI.setUnavailable(LibFunc::siprintf); TLI.setUnavailable(LibFunc::fiprintf); } if (T.isOSWindows() && !T.isOSCygMing()) { // Win32 does not support long double TLI.setUnavailable(LibFunc::acosl); TLI.setUnavailable(LibFunc::asinl); TLI.setUnavailable(LibFunc::atanl); TLI.setUnavailable(LibFunc::atan2l); TLI.setUnavailable(LibFunc::ceill); TLI.setUnavailable(LibFunc::copysignl); TLI.setUnavailable(LibFunc::cosl); TLI.setUnavailable(LibFunc::coshl); TLI.setUnavailable(LibFunc::expl); 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); TLI.setUnavailable(LibFunc::sinl); TLI.setUnavailable(LibFunc::sinhl); TLI.setUnavailable(LibFunc::sqrtl); TLI.setUnavailable(LibFunc::tanl); TLI.setUnavailable(LibFunc::tanhl); // Win32 only has C89 math TLI.setUnavailable(LibFunc::acosh); TLI.setUnavailable(LibFunc::acoshf); TLI.setUnavailable(LibFunc::acoshl); TLI.setUnavailable(LibFunc::asinh); TLI.setUnavailable(LibFunc::asinhf); TLI.setUnavailable(LibFunc::asinhl); TLI.setUnavailable(LibFunc::atanh); TLI.setUnavailable(LibFunc::atanhf); TLI.setUnavailable(LibFunc::atanhl); TLI.setUnavailable(LibFunc::cbrt); TLI.setUnavailable(LibFunc::cbrtf); TLI.setUnavailable(LibFunc::cbrtl); TLI.setUnavailable(LibFunc::exp2); TLI.setUnavailable(LibFunc::exp2f); TLI.setUnavailable(LibFunc::exp2l); TLI.setUnavailable(LibFunc::expm1); TLI.setUnavailable(LibFunc::expm1f); TLI.setUnavailable(LibFunc::expm1l); TLI.setUnavailable(LibFunc::log2); TLI.setUnavailable(LibFunc::log2f); TLI.setUnavailable(LibFunc::log2l); TLI.setUnavailable(LibFunc::log1p); TLI.setUnavailable(LibFunc::log1pf); TLI.setUnavailable(LibFunc::log1pl); TLI.setUnavailable(LibFunc::logb); TLI.setUnavailable(LibFunc::logbf); TLI.setUnavailable(LibFunc::logbl); TLI.setUnavailable(LibFunc::nearbyint); TLI.setUnavailable(LibFunc::nearbyintf); TLI.setUnavailable(LibFunc::nearbyintl); TLI.setUnavailable(LibFunc::rint); TLI.setUnavailable(LibFunc::rintf); TLI.setUnavailable(LibFunc::rintl); TLI.setUnavailable(LibFunc::round); TLI.setUnavailable(LibFunc::roundf); TLI.setUnavailable(LibFunc::roundl); TLI.setUnavailable(LibFunc::trunc); TLI.setUnavailable(LibFunc::truncf); TLI.setUnavailable(LibFunc::truncl); // Win32 provides some C99 math with mangled names TLI.setAvailableWithName(LibFunc::copysign, "_copysign"); if (T.getArch() == Triple::x86) { // Win32 on x86 implements single-precision math functions as macros TLI.setUnavailable(LibFunc::acosf); TLI.setUnavailable(LibFunc::asinf); TLI.setUnavailable(LibFunc::atanf); TLI.setUnavailable(LibFunc::atan2f); TLI.setUnavailable(LibFunc::ceilf); TLI.setUnavailable(LibFunc::copysignf); TLI.setUnavailable(LibFunc::cosf); 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); TLI.setUnavailable(LibFunc::sinf); TLI.setUnavailable(LibFunc::sinhf); TLI.setUnavailable(LibFunc::sqrtf); TLI.setUnavailable(LibFunc::tanf); TLI.setUnavailable(LibFunc::tanhf); } // Win32 does *not* provide provide these functions, but they are // generally available on POSIX-compliant systems: TLI.setUnavailable(LibFunc::access); 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::getc_unlocked); 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); // Win32 does *not* provide provide these functions, but they are // specified by C99: TLI.setUnavailable(LibFunc::atoll); TLI.setUnavailable(LibFunc::frexpf); 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: case Triple::TvOS: case Triple::WatchOS: TLI.setUnavailable(LibFunc::exp10l); if (!T.isWatchOS() && (T.isOSVersionLT(7, 0) || (T.isOSVersionLT(9, 0) && (T.getArch() == Triple::x86 || T.getArch() == Triple::x86_64)))) { 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 // http://svn.freebsd.org/base/head/lib/libc/string/ffsl.c // http://www.gnu.org/software/gnulib/manual/html_node/ffsl.html switch (T.getOS()) { case Triple::Darwin: case Triple::MacOSX: case Triple::IOS: case Triple::TvOS: case Triple::WatchOS: case Triple::FreeBSD: case Triple::Linux: break; default: TLI.setUnavailable(LibFunc::ffsl); } // ffsll is available on at least FreeBSD and Linux (GLIBC): // http://svn.freebsd.org/base/head/lib/libc/string/ffsll.c // http://www.gnu.org/software/gnulib/manual/html_node/ffsll.html switch (T.getOS()) { case Triple::Darwin: case Triple::MacOSX: case Triple::IOS: case Triple::TvOS: case Triple::WatchOS: case Triple::FreeBSD: case Triple::Linux: break; default: TLI.setUnavailable(LibFunc::ffsll); } // The following functions are available on at least FreeBSD: // http://svn.freebsd.org/base/head/lib/libc/string/fls.c // http://svn.freebsd.org/base/head/lib/libc/string/flsl.c // http://svn.freebsd.org/base/head/lib/libc/string/flsll.c if (!T.isOSFreeBSD()) { TLI.setUnavailable(LibFunc::fls); TLI.setUnavailable(LibFunc::flsl); TLI.setUnavailable(LibFunc::flsll); } // The following functions are available on at least Linux: if (!T.isOSLinux()) { TLI.setUnavailable(LibFunc::dunder_strdup); TLI.setUnavailable(LibFunc::dunder_strtok_r); TLI.setUnavailable(LibFunc::dunder_isoc99_scanf); TLI.setUnavailable(LibFunc::dunder_isoc99_sscanf); TLI.setUnavailable(LibFunc::under_IO_getc); TLI.setUnavailable(LibFunc::under_IO_putc); TLI.setUnavailable(LibFunc::memalign); TLI.setUnavailable(LibFunc::fopen64); TLI.setUnavailable(LibFunc::fseeko64); TLI.setUnavailable(LibFunc::fstat64); TLI.setUnavailable(LibFunc::fstatvfs64); TLI.setUnavailable(LibFunc::ftello64); TLI.setUnavailable(LibFunc::lstat64); TLI.setUnavailable(LibFunc::open64); TLI.setUnavailable(LibFunc::stat64); TLI.setUnavailable(LibFunc::statvfs64); TLI.setUnavailable(LibFunc::tmpfile64); } // As currently implemented in clang, NVPTX code has no standard library to // speak of. Headers provide a standard-ish library implementation, but many // of the signatures are wrong -- for example, many libm functions are not // extern "C". // // libdevice, an IR library provided by nvidia, is linked in by the front-end, // but only used functions are provided to llvm. Moreover, most of the // functions in libdevice don't map precisely to standard library functions. // // FIXME: Having no standard library prevents e.g. many fastmath // optimizations, so this situation should be fixed. if (T.isNVPTX()) { TLI.disableAllFunctions(); TLI.setAvailable(LibFunc::nvvm_reflect); } else { TLI.setUnavailable(LibFunc::nvvm_reflect); } TLI.addVectorizableFunctionsFromVecLib(ClVectorLibrary); }