sfantao updated this revision to Diff 62523.
sfantao marked an inline comment as done.
sfantao added a comment.
- Use llvm::sys::path::replace_extension to deal with the extension of the
linker script.
http://reviews.llvm.org/D21847
Files:
lib/Driver/Driver.cpp
lib/Driver/Tools.cpp
test/Driver/openmp-offload.c
Index: test/Driver/openmp-offload.c
===================================================================
--- test/Driver/openmp-offload.c
+++ test/Driver/openmp-offload.c
@@ -138,3 +138,95 @@
// CHK-PHASES-FILES: 38: assembler, {37}, object, (device-openmp)
// CHK-PHASES-FILES: 39: linker, {26, 32, 38}, image, (device-openmp)
// CHK-PHASES-FILES: 40: offload, "host-openmp (powerpc64-ibm-linux-gnu)" {11}, "device-openmp (x86_64-pc-linux-gnu)" {25}, "device-openmp (powerpc64-ibm-linux-gnu)" {39}, image
+
+
+/// ###########################################################################
+
+/// Check of the commands passed to each tool when using valid OpenMP targets.
+/// Here we also check that offloading does not break the use of integrated
+/// assembler. It does however preclude the merge of the host compile and
+/// backend phases. There are also two offloading specific options:
+/// -fopenmp-is-device: will tell the frontend that it will generate code for a
+/// target.
+/// -fopenmp-host-ir-file-path: specifies the host IR file that can be loaded by
+/// the target code generation to gather information about which declaration
+/// really need to be emitted.
+///
+// RUN: %clang -### -fopenmp -o %t.out -target powerpc64le-linux -fopenmp-targets=powerpc64le-ibm-linux-gnu,x86_64-pc-linux-gnu %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHK-COMMANDS %s
+// Run the save temp test in a temporary folder as the linker script will be
+// created there.
+// RUN: cd %T && \
+// RUN: %clang -### -fopenmp -o %t.out -target powerpc64le-linux -fopenmp-targets=powerpc64le-ibm-linux-gnu,x86_64-pc-linux-gnu %s -save-temps 2>&1 \
+// RUN: | FileCheck -check-prefix=CHK-COMMANDS-ST %s
+// RUN: FileCheck -check-prefix=CHK-LKS %s --input-file %t.lk
+//
+// Generate host BC file.
+//
+// CHK-COMMANDS: clang{{.*}}" "-cc1" "-triple" "powerpc64le--linux" "-emit-llvm-bc" {{.*}}"-o" "[[HOSTBC:.+\.bc]]" "-x" "c" "[[INPUT:.+\.c]]" "-fopenmp-targets=powerpc64le-ibm-linux-gnu,x86_64-pc-linux-gnu"
+// CHK-COMMANDS-ST: clang-3.9" "-cc1" "-triple" "powerpc64le--linux" "-E" {{.*}}"-fopenmp" {{.*}}"-o" "[[HOSTPP:.+\.i]]" "-x" "c" "[[INPUT:.+\.c]]"
+// CHK-COMMANDS-ST: clang-3.9" "-cc1" "-triple" "powerpc64le--linux" "-emit-llvm-bc" {{.*}}"-fopenmp" {{.*}}"-o" "[[HOSTBC:.+\.bc]]" "-x" "cpp-output" "[[HOSTPP]]" "-fopenmp-targets=powerpc64le-ibm-linux-gnu,x86_64-pc-linux-gnu"
+
+//
+// Compile for the powerpc device.
+/
+// CHK-COMMANDS: clang{{.*}}" "-cc1" "-triple" "powerpc64le-ibm-linux-gnu" "-emit-obj" {{.*}}"-fopenmp" {{.*}}"-o" "[[T1OBJ:.+\.o]]" "-x" "c" "[[INPUT]]" "-fopenmp-is-device" "-fopenmp-host-ir-file-path" "[[HOSTBC]]"
+// CHK-COMMANDS: ld" {{.*}}"-o" "[[T1BIN:.+\.out]]" {{.*}}"[[T1OBJ]]"
+// CHK-COMMANDS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-ibm-linux-gnu" "-E" {{.*}}"-fopenmp" {{.*}}"-o" "[[T1PP:.+\.i]]" "-x" "c" "[[INPUT]]"
+// CHK-COMMANDS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-ibm-linux-gnu" "-emit-llvm-bc" {{.*}}"-fopenmp" {{.*}}"-o" "[[T1BC:.+\.bc]]" "-x" "cpp-output" "[[T1PP]]" "-fopenmp-is-device" "-fopenmp-host-ir-file-path" "[[HOSTBC]]"
+// CHK-COMMANDS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-ibm-linux-gnu" "-S" {{.*}}"-fopenmp" {{.*}}"-o" "[[T1ASM:.+\.s]]" "-x" "ir" "[[T1BC]]"
+// CHK-COMMANDS-ST: clang{{.*}}" "-cc1as" "-triple" "powerpc64le-ibm-linux-gnu" "-filetype" "obj" {{.*}}"-o" "[[T1OBJ:.+\.o]]" "[[T1ASM]]"
+// CHK-COMMANDS-ST: ld" {{.*}}"-o" "[[T1BIN:.+\.out-device-openmp-powerpc64le-ibm-linux-gnu]]" {{.*}}[[T1OBJ]]
+
+//
+// Compile for the x86 device.
+//
+// CHK-COMMANDS: clang{{.*}}" "-cc1" "-triple" "x86_64-pc-linux-gnu" "-emit-obj" {{.*}}"-fopenmp" {{.*}}"-o" "[[T2OBJ:.+\.o]]" "-x" "c" "[[INPUT]]" "-fopenmp-is-device" "-fopenmp-host-ir-file-path" "[[HOSTBC]]"
+// CHK-COMMANDS: ld" {{.*}}"-o" "[[T2BIN:.+\.out]]" {{.*}}"[[T2OBJ]]"
+// CHK-COMMANDS-ST: clang{{.*}}" "-cc1" "-triple" "x86_64-pc-linux-gnu" "-E" {{.*}}"-fopenmp" {{.*}}"-o" "[[T2PP:.+\.i]]" "-x" "c" "[[INPUT]]"
+// CHK-COMMANDS-ST: clang{{.*}}" "-cc1" "-triple" "x86_64-pc-linux-gnu" "-emit-llvm-bc" {{.*}}"-fopenmp" {{.*}}"-o" "[[T2BC:.+\.bc]]" "-x" "cpp-output" "[[T2PP]]" "-fopenmp-is-device" "-fopenmp-host-ir-file-path" "[[HOSTBC]]"
+// CHK-COMMANDS-ST: clang{{.*}}" "-cc1" "-triple" "x86_64-pc-linux-gnu" "-S" {{.*}}"-fopenmp" {{.*}}"-o" "[[T2ASM:.+\.s]]" "-x" "ir" "[[T2BC]]"
+// CHK-COMMANDS-ST: clang{{.*}}" "-cc1as" "-triple" "x86_64-pc-linux-gnu" "-filetype" "obj" {{.*}}"-o" "[[T2OBJ:.+\.o]]" "[[T2ASM]]"
+// CHK-COMMANDS-ST: ld" {{.*}}"-o" "[[T2BIN:.+\.out-device-openmp-x86_64-pc-linux-gnu]]" {{.*}}[[T2OBJ]]
+
+//
+// Generate host object from the BC file and link using the linker script.
+//
+// CHK-COMMANDS: clang{{.*}}" "-cc1" "-triple" "powerpc64le--linux" "-emit-obj" {{.*}}"-fopenmp" {{.*}}"-o" "[[HOSTOBJ:.+\.o]]" "-x" "ir" "[[HOSTBC]]"
+// CHK-COMMANDS: ld" {{.*}}"-o" "[[HOSTBIN:.+\.out]]" {{.*}}"-lomptarget" {{.*}}"-T" "[[HOSTLK:.+\.lk]]"
+// CHK-COMMANDS-ST: clang-3.9" "-cc1" "-triple" "powerpc64le--linux" "-S" {{.*}}"-fopenmp" {{.*}}"-o" "[[HOSTASM:.+\.s]]" "-x" "ir" "[[HOSTBC]]"
+// CHK-COMMANDS-ST: clang-3.9" "-cc1as" "-triple" "powerpc64le--linux" "-filetype" "obj" {{.*}}"-o" [[HOSTOBJ:.+\.o]]" [[HOSTASM:.+\.s]]
+// CHK-COMMANDS-ST: ld" {{.*}}"-o" "[[HOSTBIN:.+\.out]]" {{.*}}"-lomptarget" {{.*}}"-T" "[[HOSTLK:.+\.lk]]"
+
+//
+// Check the linker script contains what we expect.
+//
+// CHK-LKS: TARGET(binary)
+// CHK-LKS: INPUT({{.+}}.out-device-openmp-powerpc64le-ibm-linux-gnu)
+// CHK-LKS: INPUT({{.+}}.out-device-openmp-x86_64-pc-linux-gnu)
+// CHK-LKS: SECTIONS
+// CHK-LKS: {
+// CHK-LKS: .omp_offloading :
+// CHK-LKS: ALIGN(0x10)
+// CHK-LKS: {
+// CHK-LKS: . = ALIGN(0x10);
+// CHK-LKS: PROVIDE_HIDDEN(.omp_offloading.img_start.powerpc64le-ibm-linux-gnu = .);
+// CHK-LKS: {{.+}}.out-device-openmp-powerpc64le-ibm-linux-gnu
+// CHK-LKS: PROVIDE_HIDDEN(.omp_offloading.img_end.powerpc64le-ibm-linux-gnu = .);
+// CHK-LKS: . = ALIGN(0x10);
+// CHK-LKS: PROVIDE_HIDDEN(.omp_offloading.img_start.x86_64-pc-linux-gnu = .);
+// CHK-LKS: {{.+}}.out-device-openmp-x86_64-pc-linux-gnu
+// CHK-LKS: PROVIDE_HIDDEN(.omp_offloading.img_end.x86_64-pc-linux-gnu = .);
+// CHK-LKS: }
+// CHK-LKS: .omp_offloading.entries :
+// CHK-LKS: ALIGN(0x10)
+// CHK-LKS: SUBALIGN(0x01)
+// CHK-LKS: {
+// CHK-LKS: PROVIDE_HIDDEN(.omp_offloading.entries_begin = .);
+// CHK-LKS: *(.omp_offloading.entries)
+// CHK-LKS: PROVIDE_HIDDEN(.omp_offloading.entries_end = .);
+// CHK-LKS: }
+// CHK-LKS: }
+// CHK-LKS: INSERT BEFORE .data
+
+
Index: lib/Driver/Tools.cpp
===================================================================
--- lib/Driver/Tools.cpp
+++ lib/Driver/Tools.cpp
@@ -225,14 +225,23 @@
}
static void AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs,
- const ArgList &Args, ArgStringList &CmdArgs) {
+ const ArgList &Args, ArgStringList &CmdArgs,
+ const JobAction &JA) {
const Driver &D = TC.getDriver();
// Add extra linker input arguments which are not treated as inputs
// (constructed via -Xarch_).
Args.AddAllArgValues(CmdArgs, options::OPT_Zlinker_input);
for (const auto &II : Inputs) {
+ // If the current tool chain refers to an OpenMP offloading host, we should
+ // ignore inputs that refer to OpenMP offloading devices - they will be
+ // embedded recurring to a proper linker script.
+ if (auto *IA = II.getAction())
+ if (JA.isHostOffloading(Action::OFK_OpenMP) &&
+ IA->isDeviceOffloading(Action::OFK_OpenMP))
+ continue;
+
if (!TC.HasNativeLLVMSupport() && types::isLLVMIR(II.getType()))
// Don't try to pass LLVM inputs unless we have native support.
D.Diag(diag::err_drv_no_linker_llvm_support) << TC.getTripleString();
@@ -266,6 +275,112 @@
addDirectoryList(Args, CmdArgs, "-L", "LIBRARY_PATH");
}
+/// \brief 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()));
+ }
+
+ // Open script file in order to write 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;
+ }
+
+ // 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.
+ Lksf << "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;
+ Lksf << "INPUT(" << II.getFilename() << ")\n";
+ }
+ }
+
+ assert(DTC == OpenMPToolChains.second &&
+ "Less device inputs than device toolchains??");
+
+ Lksf << "SECTIONS\n";
+ Lksf << "{\n";
+ Lksf << " .omp_offloading :\n";
+ Lksf << " ALIGN(0x10)\n";
+ Lksf << " {\n";
+
+ for (auto &BI : InputBinaryInfo) {
+ Lksf << " . = ALIGN(0x10);\n";
+ Lksf << " PROVIDE_HIDDEN(.omp_offloading.img_start." << BI.first
+ << " = .);\n";
+ Lksf << " " << BI.second << "\n";
+ Lksf << " PROVIDE_HIDDEN(.omp_offloading.img_end." << BI.first
+ << " = .);\n";
+ }
+
+ Lksf << " }\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.
+ Lksf << " .omp_offloading.entries :\n";
+ Lksf << " ALIGN(0x10)\n";
+ Lksf << " SUBALIGN(0x01)\n";
+ Lksf << " {\n";
+ Lksf << " PROVIDE_HIDDEN(.omp_offloading.entries_begin = .);\n";
+ Lksf << " *(.omp_offloading.entries)\n";
+ Lksf << " PROVIDE_HIDDEN(.omp_offloading.entries_end = .);\n";
+ Lksf << " }\n";
+ Lksf << "}\n";
+ Lksf << "INSERT BEFORE .data\n";
+
+ Lksf.close();
+
+ CmdArgs.push_back("-T");
+ CmdArgs.push_back(LKS);
+}
+
/// \brief Determine whether Objective-C automated reference counting is
/// enabled.
static bool isObjCAutoRefCount(const ArgList &Args) {
@@ -3745,10 +3860,14 @@
assert(Inputs.size() >= 1 && "Must have at least one input.");
const InputInfo &Input = Inputs[0];
// CUDA compilation may have multiple inputs (source file + results of
- // device-side compilations). All other jobs are expected to have exactly one
+ // device-side compilations). OpenMP device jobs also take the host IR as a
+ // second input. All other jobs are expected to have exactly one
// input.
bool IsCuda = JA.isOffloading(Action::OFK_Cuda);
- assert((IsCuda || Inputs.size() == 1) && "Unable to handle multiple inputs.");
+ bool IsOpenMPDevice = JA.isDeviceOffloading(Action::OFK_OpenMP);
+ assert((IsCuda || (IsOpenMPDevice && Inputs.size() == 2) ||
+ Inputs.size() == 1) &&
+ "Unable to handle multiple inputs.");
// C++ is not supported for IAMCU.
if (IsIAMCU && types::isCXX(Input.getType()))
@@ -5923,6 +6042,36 @@
CmdArgs.push_back(I->getFilename());
}
+ // OpenMP offloading device jobs take the argument -fopenmp-host-ir-file-path
+ // to specify the result of the compile phase on the host, so the meaningful
+ // device declarations can be identified. Also, -fopenmp-is-device is passed
+ // along to tell the frontend that it is generating code for a device, so that
+ // only the relevant declarations are emitted.
+ if (IsOpenMPDevice && Inputs.size() == 2) {
+ CmdArgs.push_back("-fopenmp-is-device");
+ CmdArgs.push_back("-fopenmp-host-ir-file-path");
+ CmdArgs.push_back(Args.MakeArgString(Inputs.back().getFilename()));
+ }
+
+ // For all the host OpenMP offloading compile jobs we need to pass the targets
+ // information using -fopenmp-targets= option.
+ if (isa<CompileJobAction>(JA) && JA.isHostOffloading(Action::OFK_OpenMP)) {
+ SmallString<128> TargetInfo("-fopenmp-targets=");
+
+ Arg *Tgts = Args.getLastArg(options::OPT_fopenmp_targets_EQ);
+ assert(Tgts && Tgts->getNumValues() &&
+ "OpenMP offloading has to have targets specified.");
+ for (unsigned i = 0; i < Tgts->getNumValues(); ++i) {
+ if (i)
+ TargetInfo += ',';
+ // We need to get the string from the triple because it may be not exactly
+ // the same as the one we get directly from the arguments.
+ llvm::Triple T(Tgts->getValue(i));
+ TargetInfo += T.getTriple();
+ }
+ CmdArgs.push_back(Args.MakeArgString(TargetInfo.str()));
+ }
+
bool WholeProgramVTables =
Args.hasFlag(options::OPT_fwhole_program_vtables,
options::OPT_fno_whole_program_vtables, false);
@@ -6897,7 +7046,7 @@
{options::OPT_T_Group, options::OPT_e, options::OPT_s,
options::OPT_t, options::OPT_u_Group});
- AddLinkerInputs(HTC, Inputs, Args, CmdArgs);
+ AddLinkerInputs(HTC, Inputs, Args, CmdArgs, JA);
//----------------------------------------------------------------------------
// Libraries
@@ -6956,7 +7105,7 @@
std::string Linker = getToolChain().GetProgramPath(getShortName());
ArgStringList CmdArgs;
- AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
+ AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
CmdArgs.push_back("-shared");
CmdArgs.push_back("-o");
CmdArgs.push_back(Output.getFilename());
@@ -7019,7 +7168,7 @@
CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o")));
}
- AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
+ AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
if (D.CCCIsCXX())
@@ -7363,7 +7512,7 @@
if (D.isUsingLTO())
AddGoldPlugin(ToolChain, Args, CmdArgs, D.getLTOMode() == LTOK_Thin);
- AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
+ AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
if (D.CCCIsCXX())
@@ -7739,7 +7888,7 @@
Args.AddAllArgs(CmdArgs, options::OPT_L);
- AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
+ AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
// Build the input file for -filelist (list of linker input files) in case we
// need it later
for (const auto &II : Inputs) {
@@ -7957,7 +8106,7 @@
Args.AddAllArgs(CmdArgs, {options::OPT_L, options::OPT_T_Group,
options::OPT_e, options::OPT_r});
- AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
+ AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
if (getToolChain().getDriver().CCCIsCXX())
@@ -8130,7 +8279,7 @@
options::OPT_e, options::OPT_s, options::OPT_t,
options::OPT_Z_Flag, options::OPT_r});
- AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
+ AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
if (D.CCCIsCXX()) {
@@ -8249,7 +8398,7 @@
Args.AddAllArgs(CmdArgs,
{options::OPT_L, options::OPT_T_Group, options::OPT_e});
- AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
+ AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
if (D.CCCIsCXX()) {
@@ -8515,7 +8664,7 @@
AddGoldPlugin(ToolChain, Args, CmdArgs, D.getLTOMode() == LTOK_Thin);
bool NeedsSanitizerDeps = addSanitizerRuntimes(ToolChain, Args, CmdArgs);
- AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
+ AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
addOpenMPRuntime(CmdArgs, ToolChain, Args);
@@ -8812,7 +8961,7 @@
Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag);
Args.AddAllArgs(CmdArgs, options::OPT_r);
- AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
+ AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
unsigned Major, Minor, Micro;
getToolChain().getTriple().getOSVersion(Major, Minor, Micro);
@@ -9355,7 +9504,7 @@
CmdArgs.push_back("--no-demangle");
bool NeedsSanitizerDeps = addSanitizerRuntimes(ToolChain, Args, CmdArgs);
- AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
+ AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
// The profile runtime also needs access to system libraries.
getToolChain().addProfileRTLibs(Args, CmdArgs);
@@ -9409,6 +9558,8 @@
// Already diagnosed.
break;
}
+ if (JA.isHostOffloading(Action::OFK_OpenMP))
+ CmdArgs.push_back("-lomptarget");
}
AddRunTimeLibs(ToolChain, D, CmdArgs, Args);
@@ -9454,6 +9605,9 @@
}
}
+ // Add OpenMP offloading linker script args if required.
+ AddOpenMPLinkerScript(getToolChain(), C, Output, Inputs, Args, CmdArgs, JA);
+
C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
}
@@ -9563,7 +9717,7 @@
if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
CmdArgs.push_back("--no-demangle");
- AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
+ AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
if (D.CCCIsCXX() &&
!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
@@ -9675,7 +9829,7 @@
Args.AddAllArgs(CmdArgs,
{options::OPT_L, options::OPT_T_Group, options::OPT_e});
- AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
+ AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
getToolChain().addProfileRTLibs(Args, CmdArgs);
@@ -9796,7 +9950,7 @@
Args.AddAllArgs(CmdArgs,
{options::OPT_L, options::OPT_T_Group, options::OPT_e});
- AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
+ AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
CmdArgs.push_back("-L/usr/lib/gcc50");
@@ -10318,7 +10472,7 @@
Args.AddAllArgs(CmdArgs, options::OPT_L);
TC.AddFilePathLibArgs(Args, CmdArgs);
- AddLinkerInputs(TC, Inputs, Args, CmdArgs);
+ AddLinkerInputs(TC, Inputs, Args, CmdArgs, JA);
// TODO: Add ASan stuff here
@@ -10442,7 +10596,7 @@
false))
CmdArgs.push_back("-fexceptions");
- AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
+ AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("xcc"));
C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
@@ -10596,7 +10750,7 @@
Args.AddAllArgs(CmdArgs, options::OPT_L);
TC.AddFilePathLibArgs(Args, CmdArgs);
- AddLinkerInputs(TC, Inputs, Args, CmdArgs);
+ AddLinkerInputs(TC, Inputs, Args, CmdArgs, JA);
if (D.CCCIsCXX() && !Args.hasArg(options::OPT_nostdlib) &&
!Args.hasArg(options::OPT_nodefaultlibs)) {
@@ -10777,7 +10931,7 @@
TC.AddFilePathLibArgs(Args, CmdArgs);
- AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
+ AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
if (UseDefaultLibs) {
if (C.getDriver().CCCIsCXX())
@@ -10886,7 +11040,7 @@
if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
CmdArgs.push_back("--no-demangle");
- AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
+ AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
if (Args.hasArg(options::OPT_pthread)) {
CmdArgs.push_back("-lpthread");
@@ -10982,7 +11136,7 @@
if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
CmdArgs.push_back("--no-demangle");
- AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
+ AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
// For PS4, we always want to pass libm, libstdc++ and libkernel
Index: lib/Driver/Driver.cpp
===================================================================
--- lib/Driver/Driver.cpp
+++ lib/Driver/Driver.cpp
@@ -2815,11 +2815,15 @@
bool BuildForOffloadDevice) const {
// The bound arch is not necessarily represented in the toolchain's triple --
// for example, armv7 and armv7s both map to the same triple -- so we need
- // both in our map.
+ // both in our map. Also, we need to add the offloading device kind, as the
+ // same tool chain can be used for host and device for some programming
+ // models, e.g. OpenMP.
std::string TriplePlusArch = TC->getTriple().normalize();
if (BoundArch) {
TriplePlusArch += "-";
TriplePlusArch += BoundArch;
+ TriplePlusArch += "-";
+ TriplePlusArch += A->getOffloadingKindPrefix();
}
std::pair<const Action *, std::string> ActionTC = {A, TriplePlusArch};
auto CachedResult = CachedResults.find(ActionTC);
@@ -3128,14 +3132,14 @@
// clang-cl uses BaseName for the executable name.
NamedOutput =
MakeCLOutputFilename(C.getArgs(), "", BaseName, types::TY_Image);
- } else if (MultipleArchs && BoundArch) {
+ } else {
SmallString<128> Output(getDefaultImageName());
Output += JA.getOffloadingFileNamePrefix(NormalizedTriple);
- Output += "-";
- Output.append(BoundArch);
+ if (MultipleArchs && BoundArch) {
+ Output += "-";
+ Output.append(BoundArch);
+ }
NamedOutput = C.getArgs().MakeArgString(Output.c_str());
- } else {
- NamedOutput = getDefaultImageName();
}
} else if (JA.getType() == types::TY_PCH && IsCLMode()) {
NamedOutput = C.getArgs().MakeArgString(GetClPchPath(C, BaseName).c_str());
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits