diff options
author | Patrick Wildt <patrick@cvs.openbsd.org> | 2017-10-04 20:27:51 +0000 |
---|---|---|
committer | Patrick Wildt <patrick@cvs.openbsd.org> | 2017-10-04 20:27:51 +0000 |
commit | c96400fe961862b82a4ff9f9bab3c9b3e315619a (patch) | |
tree | 4e7acf3ffe1b5c94473d7de4843a79e637e80235 /gnu | |
parent | 0ae9e80a2df400099b299b7f5dd85aeaf4136e0c (diff) |
Import LLVM 5.0.0 release including clang, lld and lldb.
Diffstat (limited to 'gnu')
-rw-r--r-- | gnu/llvm/tools/clang/lib/Driver/ToolChains/Gnu.cpp | 221 |
1 files changed, 156 insertions, 65 deletions
diff --git a/gnu/llvm/tools/clang/lib/Driver/ToolChains/Gnu.cpp b/gnu/llvm/tools/clang/lib/Driver/ToolChains/Gnu.cpp index 7845781f12c..72a9f85ba38 100644 --- a/gnu/llvm/tools/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/gnu/llvm/tools/clang/lib/Driver/ToolChains/Gnu.cpp @@ -11,7 +11,6 @@ #include "Linux.h" #include "Arch/ARM.h" #include "Arch/Mips.h" -#include "Arch/PPC.h" #include "Arch/Sparc.h" #include "Arch/SystemZ.h" #include "CommonArgs.h" @@ -42,22 +41,6 @@ static bool forwardToGCC(const Option &O) { !O.hasFlag(options::DriverOption) && !O.hasFlag(options::LinkerInput); } -// Switch CPU names not recognized by GNU assembler to a close CPU that it does -// recognize, instead of a lower march from being picked in the absence of a cpu -// flag. -static void normalizeCPUNamesForAssembler(const ArgList &Args, - ArgStringList &CmdArgs) { - if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) { - StringRef CPUArg(A->getValue()); - if (CPUArg.equals_lower("krait")) - CmdArgs.push_back("-mcpu=cortex-a15"); - else if(CPUArg.equals_lower("kryo")) - CmdArgs.push_back("-mcpu=cortex-a57"); - else - Args.AddLastArg(CmdArgs, options::OPT_mcpu_EQ); - } -} - void tools::gcc::Common::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, @@ -220,12 +203,133 @@ void tools::gcc::Linker::RenderExtraToolArgs(const JobAction &JA, // The types are (hopefully) good enough. } +/// Add OpenMP linker script arguments at the end of the argument list so that +/// the fat binary is built by embedding each of the device images into the +/// host. The linker script also defines a few symbols required by the code +/// generation so that the images can be easily retrieved at runtime by the +/// offloading library. This should be used only in tool chains that support +/// linker scripts. +static void AddOpenMPLinkerScript(const ToolChain &TC, Compilation &C, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, ArgStringList &CmdArgs, + const JobAction &JA) { + + // If this is not an OpenMP host toolchain, we don't need to do anything. + if (!JA.isHostOffloading(Action::OFK_OpenMP)) + return; + + // Create temporary linker script. Keep it if save-temps is enabled. + const char *LKS; + SmallString<256> Name = llvm::sys::path::filename(Output.getFilename()); + if (C.getDriver().isSaveTempsEnabled()) { + llvm::sys::path::replace_extension(Name, "lk"); + LKS = C.getArgs().MakeArgString(Name.c_str()); + } else { + llvm::sys::path::replace_extension(Name, ""); + Name = C.getDriver().GetTemporaryPath(Name, "lk"); + LKS = C.addTempFile(C.getArgs().MakeArgString(Name.c_str())); + } + + // Add linker script option to the command. + CmdArgs.push_back("-T"); + CmdArgs.push_back(LKS); + + // Create a buffer to write the contents of the linker script. + std::string LksBuffer; + llvm::raw_string_ostream LksStream(LksBuffer); + + // Get the OpenMP offload tool chains so that we can extract the triple + // associated with each device input. + auto OpenMPToolChains = C.getOffloadToolChains<Action::OFK_OpenMP>(); + assert(OpenMPToolChains.first != OpenMPToolChains.second && + "No OpenMP toolchains??"); + + // Track the input file name and device triple in order to build the script, + // inserting binaries in the designated sections. + SmallVector<std::pair<std::string, const char *>, 8> InputBinaryInfo; + + // Add commands to embed target binaries. We ensure that each section and + // image is 16-byte aligned. This is not mandatory, but increases the + // likelihood of data to be aligned with a cache block in several main host + // machines. + LksStream << "/*\n"; + LksStream << " OpenMP Offload Linker Script\n"; + LksStream << " *** Automatically generated by Clang ***\n"; + LksStream << "*/\n"; + LksStream << "TARGET(binary)\n"; + auto DTC = OpenMPToolChains.first; + for (auto &II : Inputs) { + const Action *A = II.getAction(); + // Is this a device linking action? + if (A && isa<LinkJobAction>(A) && + A->isDeviceOffloading(Action::OFK_OpenMP)) { + assert(DTC != OpenMPToolChains.second && + "More device inputs than device toolchains??"); + InputBinaryInfo.push_back(std::make_pair( + DTC->second->getTriple().normalize(), II.getFilename())); + ++DTC; + LksStream << "INPUT(" << II.getFilename() << ")\n"; + } + } + + assert(DTC == OpenMPToolChains.second && + "Less device inputs than device toolchains??"); + + LksStream << "SECTIONS\n"; + LksStream << "{\n"; + + // Put each target binary into a separate section. + for (const auto &BI : InputBinaryInfo) { + LksStream << " .omp_offloading." << BI.first << " :\n"; + LksStream << " ALIGN(0x10)\n"; + LksStream << " {\n"; + LksStream << " PROVIDE_HIDDEN(.omp_offloading.img_start." << BI.first + << " = .);\n"; + LksStream << " " << BI.second << "\n"; + LksStream << " PROVIDE_HIDDEN(.omp_offloading.img_end." << BI.first + << " = .);\n"; + LksStream << " }\n"; + } + + // Add commands to define host entries begin and end. We use 1-byte subalign + // so that the linker does not add any padding and the elements in this + // section form an array. + LksStream << " .omp_offloading.entries :\n"; + LksStream << " ALIGN(0x10)\n"; + LksStream << " SUBALIGN(0x01)\n"; + LksStream << " {\n"; + LksStream << " PROVIDE_HIDDEN(.omp_offloading.entries_begin = .);\n"; + LksStream << " *(.omp_offloading.entries)\n"; + LksStream << " PROVIDE_HIDDEN(.omp_offloading.entries_end = .);\n"; + LksStream << " }\n"; + LksStream << "}\n"; + LksStream << "INSERT BEFORE .data\n"; + LksStream.flush(); + + // Dump the contents of the linker script if the user requested that. We + // support this option to enable testing of behavior with -###. + if (C.getArgs().hasArg(options::OPT_fopenmp_dump_offload_linker_script)) + llvm::errs() << LksBuffer; + + // If this is a dry run, do not create the linker script file. + if (C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) + return; + + // Open script file and write the contents. + std::error_code EC; + llvm::raw_fd_ostream Lksf(LKS, EC, llvm::sys::fs::F_None); + + if (EC) { + C.getDriver().Diag(clang::diag::err_unable_to_make_temp) << EC.message(); + return; + } + + Lksf << LksBuffer; +} + static bool addXRayRuntime(const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs) { - // Do not add the XRay runtime to shared libraries. - if (Args.hasArg(options::OPT_shared)) - return false; - if (Args.hasFlag(options::OPT_fxray_instrument, options::OPT_fnoxray_instrument, false)) { CmdArgs.push_back("-whole-archive"); @@ -233,7 +337,6 @@ static bool addXRayRuntime(const ToolChain &TC, const ArgList &Args, CmdArgs.push_back("-no-whole-archive"); return true; } - return false; } @@ -244,8 +347,7 @@ static void linkXRayRuntimeDeps(const ToolChain &TC, const ArgList &Args, CmdArgs.push_back("-lrt"); CmdArgs.push_back("-lm"); - if (TC.getTriple().getOS() != llvm::Triple::FreeBSD && - TC.getTriple().getOS() != llvm::Triple::NetBSD) + if (TC.getTriple().getOS() != llvm::Triple::FreeBSD) CmdArgs.push_back("-ldl"); } @@ -299,17 +401,6 @@ static const char *getLDMOption(const llvm::Triple &T, const ArgList &Args) { } } -static bool getPIE(const ArgList &Args, const toolchains::Linux &ToolChain) { - if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_static)) - return false; - - Arg *A = Args.getLastArg(options::OPT_pie, options::OPT_no_pie, - options::OPT_nopie); - if (!A) - return ToolChain.isPIEDefault(); - return A->getOption().matches(options::OPT_pie); -} - void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, @@ -324,7 +415,9 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, const llvm::Triple::ArchType Arch = ToolChain.getArch(); const bool isAndroid = ToolChain.getTriple().isAndroid(); const bool IsIAMCU = ToolChain.getTriple().isOSIAMCU(); - const bool IsPIE = getPIE(Args, ToolChain); + const bool IsPIE = + !Args.hasArg(options::OPT_shared) && !Args.hasArg(options::OPT_static) && + (Args.hasArg(options::OPT_pie) || ToolChain.isPIEDefault()); const bool HasCRTBeginEndFiles = ToolChain.getTriple().hasEnvironment() || (ToolChain.getTriple().getVendor() != llvm::Triple::MipsTechnologies); @@ -467,15 +560,13 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, if (D.CCCIsCXX() && !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) { - if (ToolChain.ShouldLinkCXXStdlib(Args)) { - bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) && - !Args.hasArg(options::OPT_static); - if (OnlyLibstdcxxStatic) - CmdArgs.push_back("-Bstatic"); - ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs); - if (OnlyLibstdcxxStatic) - CmdArgs.push_back("-Bdynamic"); - } + bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) && + !Args.hasArg(options::OPT_static); + if (OnlyLibstdcxxStatic) + CmdArgs.push_back("-Bstatic"); + ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs); + if (OnlyLibstdcxxStatic) + CmdArgs.push_back("-Bdynamic"); CmdArgs.push_back("-lm"); } // Silence warnings when linking C code with a C++ '-stdlib' argument. @@ -602,28 +693,22 @@ void tools::gnutools::Assembler::ConstructJob(Compilation &C, else CmdArgs.push_back("--64"); break; - case llvm::Triple::ppc: { + case llvm::Triple::ppc: CmdArgs.push_back("-a32"); CmdArgs.push_back("-mppc"); - CmdArgs.push_back( - ppc::getPPCAsmModeForCPU(getCPUName(Args, getToolChain().getTriple()))); + CmdArgs.push_back("-many"); break; - } - case llvm::Triple::ppc64: { + case llvm::Triple::ppc64: CmdArgs.push_back("-a64"); CmdArgs.push_back("-mppc64"); - CmdArgs.push_back( - ppc::getPPCAsmModeForCPU(getCPUName(Args, getToolChain().getTriple()))); + CmdArgs.push_back("-many"); break; - } - case llvm::Triple::ppc64le: { + case llvm::Triple::ppc64le: CmdArgs.push_back("-a64"); CmdArgs.push_back("-mppc64"); + CmdArgs.push_back("-many"); CmdArgs.push_back("-mlittle-endian"); - CmdArgs.push_back( - ppc::getPPCAsmModeForCPU(getCPUName(Args, getToolChain().getTriple()))); break; - } case llvm::Triple::sparc: case llvm::Triple::sparcel: { CmdArgs.push_back("-32"); @@ -669,16 +754,23 @@ void tools::gnutools::Assembler::ConstructJob(Compilation &C, } Args.AddLastArg(CmdArgs, options::OPT_march_EQ); - normalizeCPUNamesForAssembler(Args, CmdArgs); + // FIXME: remove krait check when GNU tools support krait cpu + // for now replace it with -mcpu=cortex-a15 to avoid a lower + // march from being picked in the absence of a cpu flag. + Arg *A; + if ((A = Args.getLastArg(options::OPT_mcpu_EQ)) && + StringRef(A->getValue()).equals_lower("krait")) + CmdArgs.push_back("-mcpu=cortex-a15"); + else + Args.AddLastArg(CmdArgs, options::OPT_mcpu_EQ); Args.AddLastArg(CmdArgs, options::OPT_mfpu_EQ); break; } case llvm::Triple::aarch64: case llvm::Triple::aarch64_be: { Args.AddLastArg(CmdArgs, options::OPT_march_EQ); - normalizeCPUNamesForAssembler(Args, CmdArgs); - + Args.AddLastArg(CmdArgs, options::OPT_mcpu_EQ); break; } case llvm::Triple::mips: @@ -1335,12 +1427,12 @@ bool clang::driver::findMIPSMultilibs(const Driver &D, if (TargetTriple.getVendor() == llvm::Triple::MipsTechnologies && TargetTriple.getOS() == llvm::Triple::Linux && - TargetTriple.isGNUEnvironment()) + TargetTriple.getEnvironment() == llvm::Triple::GNU) return findMipsMtiMultilibs(Flags, NonExistent, Result); if (TargetTriple.getVendor() == llvm::Triple::ImaginationTechnologies && TargetTriple.getOS() == llvm::Triple::Linux && - TargetTriple.isGNUEnvironment()) + TargetTriple.getEnvironment() == llvm::Triple::GNU) return findMipsImgMultilibs(Flags, NonExistent, Result); if (findMipsCsMultilibs(Flags, NonExistent, Result)) @@ -1390,7 +1482,7 @@ static void findAndroidArmMultilibs(const Driver &D, bool IsV7SubArch = TargetTriple.getSubArch() == llvm::Triple::ARMSubArch_v7; bool IsThumbMode = IsThumbArch || Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, false) || - (IsArmArch && llvm::ARM::parseArchISA(Arch) == llvm::ARM::ISAKind::THUMB); + (IsArmArch && llvm::ARM::parseArchISA(Arch) == llvm::ARM::IK_THUMB); bool IsArmV7Mode = (IsArmArch || IsThumbArch) && (llvm::ARM::parseArchVersion(Arch) == 7 || (IsArmArch && Arch == "" && IsV7SubArch)); @@ -2376,8 +2468,7 @@ void Generic_ELF::addClangTargetOptions(const ArgList &DriverArgs, getTriple().getArch() == llvm::Triple::aarch64 || getTriple().getArch() == llvm::Triple::aarch64_be || (getTriple().getOS() == llvm::Triple::Linux && - ((!GCCInstallation.isValid() || !V.isOlderThan(4, 7, 0)) || - getTriple().isAndroid())) || + (!V.isOlderThan(4, 7, 0) || getTriple().isAndroid())) || getTriple().getOS() == llvm::Triple::NaCl || (getTriple().getVendor() == llvm::Triple::MipsTechnologies && !getTriple().hasEnvironment()) || |