summaryrefslogtreecommitdiff
path: root/gnu
diff options
context:
space:
mode:
authorPatrick Wildt <patrick@cvs.openbsd.org>2017-10-04 20:27:51 +0000
committerPatrick Wildt <patrick@cvs.openbsd.org>2017-10-04 20:27:51 +0000
commitc96400fe961862b82a4ff9f9bab3c9b3e315619a (patch)
tree4e7acf3ffe1b5c94473d7de4843a79e637e80235 /gnu
parent0ae9e80a2df400099b299b7f5dd85aeaf4136e0c (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.cpp221
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()) ||