[Driver][OpenMP] Add support to create jobs for bundling actions.

Summary: This patch adds the support to create a job for the `OffloadBundlingAction` which will invoke the `clang-offload-bundler` tool.

Reviewers: echristo, tra, jlebar, ABataev, hfinkel

Subscribers: whchung, mehdi_amini, cfe-commits, Hahnfeld, andreybokhanko, arpith-jacob, carlo.bertolli, caomhin

Differential Revision: https://reviews.llvm.org/D21856

llvm-svn: 285325
This commit is contained in:
Samuel Antao 2016-10-27 18:04:42 +00:00
parent fab4f37ef7
commit 7cab8f1466
7 changed files with 141 additions and 2 deletions

View File

@ -160,6 +160,8 @@ public:
/// files for each offloading kind.
std::string
getOffloadingFileNamePrefix(llvm::StringRef NormalizedTriple) const;
/// Return a string containing a offload kind name.
static StringRef GetOffloadKindName(OffloadKind Kind);
/// Set the device offload info of this action and propagate it to its
/// dependences.

View File

@ -85,10 +85,12 @@ private:
mutable std::unique_ptr<Tool> Clang;
mutable std::unique_ptr<Tool> Assemble;
mutable std::unique_ptr<Tool> Link;
mutable std::unique_ptr<Tool> OffloadBundler;
Tool *getClang() const;
Tool *getAssemble() const;
Tool *getLink() const;
Tool *getClangAs() const;
Tool *getOffloadBundler() const;
mutable std::unique_ptr<SanitizerArgs> SanitizerArguments;

View File

@ -9,6 +9,7 @@
#include "clang/Driver/Action.h"
#include "clang/Driver/ToolChain.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Regex.h"
@ -128,6 +129,22 @@ Action::getOffloadingFileNamePrefix(llvm::StringRef NormalizedTriple) const {
return Res;
}
/// Return a string with the offload kind name. If that is not defined, we
/// assume 'host'.
llvm::StringRef Action::GetOffloadKindName(OffloadKind Kind) {
switch (Kind) {
case OFK_None:
case OFK_Host:
return "host";
case OFK_Cuda:
return "cuda";
case OFK_OpenMP:
return "openmp";
// TODO: Add other programming models here.
}
}
void InputAction::anchor() {}
InputAction::InputAction(const Arg &_Input, types::ID _Type)

View File

@ -239,6 +239,12 @@ Tool *ToolChain::getLink() const {
return Link.get();
}
Tool *ToolChain::getOffloadBundler() const {
if (!OffloadBundler)
OffloadBundler.reset(new tools::OffloadBundler(*this));
return OffloadBundler.get();
}
Tool *ToolChain::getTool(Action::ActionClass AC) const {
switch (AC) {
case Action::AssembleJobClass:
@ -266,8 +272,7 @@ Tool *ToolChain::getTool(Action::ActionClass AC) const {
case Action::OffloadBundlingJobClass:
case Action::OffloadUnbundlingJobClass:
// FIXME: Add a tool for the bundling actions.
return nullptr;
return getOffloadBundler();
}
llvm_unreachable("Invalid tool kind.");

View File

@ -7053,6 +7053,72 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
SplitDebugName(Args, Input));
}
void OffloadBundler::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output,
const InputInfoList &Inputs,
const llvm::opt::ArgList &TCArgs,
const char *LinkingOutput) const {
assert(isa<OffloadBundlingJobAction>(JA) && "Expecting bundling job!");
// The bundling command looks like this:
// clang-offload-bundler -type=bc
// -targets=host-triple,openmp-triple1,openmp-triple2
// -outputs=input_file
// -inputs=unbundle_file_host,unbundle_file_tgt1,unbundle_file_tgt2"
ArgStringList CmdArgs;
// Get the type.
CmdArgs.push_back(TCArgs.MakeArgString(
Twine("-type=") + types::getTypeTempSuffix(Output.getType())));
assert(JA.getInputs().size() == Inputs.size() &&
"Not have inputs for all dependence actions??");
// Get the targets.
SmallString<128> Triples;
Triples += "-targets=";
for (unsigned I = 0; I < Inputs.size(); ++I) {
if (I)
Triples += ',';
Action::OffloadKind CurKind = Action::OFK_Host;
const ToolChain *CurTC = &getToolChain();
const Action *CurDep = JA.getInputs()[I];
if (const auto *OA = dyn_cast<OffloadAction>(CurDep)) {
OA->doOnEachDependence([&](Action *A, const ToolChain *TC, const char *) {
CurKind = A->getOffloadingDeviceKind();
CurTC = TC;
});
}
Triples += Action::GetOffloadKindName(CurKind);
Triples += '-';
Triples += CurTC->getTriple().normalize();
}
CmdArgs.push_back(TCArgs.MakeArgString(Triples));
// Get bundled file command.
CmdArgs.push_back(
TCArgs.MakeArgString(Twine("-outputs=") + Output.getFilename()));
// Get unbundled files command.
SmallString<128> UB;
UB += "-inputs=";
for (unsigned I = 0; I < Inputs.size(); ++I) {
if (I)
UB += ',';
UB += Inputs[I].getFilename();
}
CmdArgs.push_back(TCArgs.MakeArgString(UB));
// All the inputs are encoded as commands.
C.addCommand(llvm::make_unique<Command>(
JA, *this,
TCArgs.MakeArgString(getToolChain().GetProgramPath(getShortName())),
CmdArgs, None));
}
void GnuTool::anchor() {}
void gcc::Common::ConstructJob(Compilation &C, const JobAction &JA,

View File

@ -137,6 +137,19 @@ public:
const char *LinkingOutput) const override;
};
/// Offload bundler tool.
class LLVM_LIBRARY_VISIBILITY OffloadBundler final : public Tool {
public:
OffloadBundler(const ToolChain &TC)
: Tool("offload bundler", "clang-offload-bundler", TC) {}
bool hasIntegratedCPP() const override { return false; }
void ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output, const InputInfoList &Inputs,
const llvm::opt::ArgList &TCArgs,
const char *LinkingOutput) const override;
};
/// \brief Base class for all GNU tools that provide the same behavior when
/// it comes to response files support
class LLVM_LIBRARY_VISIBILITY GnuTool : public Tool {

View File

@ -355,3 +355,37 @@
// CHK-UBUACTIONS: 14: assembler, {13}, object, (host-openmp)
// CHK-UBUACTIONS: 15: clang-offload-bundler, {7, 12, 14}, object, (host-openmp)
/// ###########################################################################
/// Check separate compilation with offloading - bundling jobs construct
// RUN: %clang -### -fopenmp -c -o %t.o -lsomelib -target powerpc64le-linux -fopenmp-targets=powerpc64le-ibm-linux-gnu,x86_64-pc-linux-gnu %s 2>&1 \
// RUN: | FileCheck -check-prefix=CHK-BUJOBS %s
// RUN: %clang -### -fopenmp -c -o %t.o -lsomelib -target powerpc64le-linux -fopenmp-targets=powerpc64le-ibm-linux-gnu,x86_64-pc-linux-gnu %s -save-temps 2>&1 \
// RUN: | FileCheck -check-prefix=CHK-BUJOBS-ST %s
// Create host BC.
// CHK-BUJOBS: clang{{.*}}" "-cc1" "-triple" "powerpc64le--linux" "-emit-llvm-bc" {{.*}}"-fopenmp" {{.*}}"-o" "[[HOSTBC:.+\.bc]]" "-x" "c" "[[INPUT:.+\.c]]" "-fopenmp-targets=powerpc64le-ibm-linux-gnu,x86_64-pc-linux-gnu"
// CHK-BUJOBS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le--linux" "-E" {{.*}}"-fopenmp" {{.*}}"-o" "[[HOSTPP:.+\.i]]" "-x" "c" "[[INPUT:.+\.c]]"
// CHK-BUJOBS-ST: clang{{.*}}" "-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"
// Create target 1 object.
// CHK-BUJOBS: 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-BUJOBS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-ibm-linux-gnu" "-E" {{.*}}"-fopenmp" {{.*}}"-o" "[[T1PP:.+\.i]]" "-x" "c" "[[INPUT]]"
// CHK-BUJOBS-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-BUJOBS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-ibm-linux-gnu" "-S" {{.*}}"-fopenmp" {{.*}}"-o" "[[T1ASM:.+\.s]]" "-x" "ir" "[[T1BC]]"
// CHK-BUJOBS-ST: clang{{.*}}" "-cc1as" "-triple" "powerpc64le-ibm-linux-gnu" "-filetype" "obj" {{.*}}"-o" "[[T1OBJ:.+\.o]]" "[[T1ASM]]"
// Create target 2 object.
// CHK-BUJOBS: 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-BUJOBS-ST: clang{{.*}}" "-cc1" "-triple" "x86_64-pc-linux-gnu" "-E" {{.*}}"-fopenmp" {{.*}}"-o" "[[T2PP:.+\.i]]" "-x" "c" "[[INPUT]]"
// CHK-BUJOBS-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-BUJOBS-ST: clang{{.*}}" "-cc1" "-triple" "x86_64-pc-linux-gnu" "-S" {{.*}}"-fopenmp" {{.*}}"-o" "[[T2ASM:.+\.s]]" "-x" "ir" "[[T2BC]]"
// CHK-BUJOBS-ST: clang{{.*}}" "-cc1as" "-triple" "x86_64-pc-linux-gnu" "-filetype" "obj" {{.*}}"-o" "[[T2OBJ:.+\.o]]" "[[T2ASM]]"
// Create host object and bundle.
// CHK-BUJOBS: clang{{.*}}" "-cc1" "-triple" "powerpc64le--linux" "-emit-obj" {{.*}}"-fopenmp" {{.*}}"-o" "[[HOSTOBJ:.+\.o]]" "-x" "ir" "[[HOSTBC]]"
// CHK-BUJOBS: clang-offload-bundler" "-type=o" "-targets=openmp-powerpc64le-ibm-linux-gnu,openmp-x86_64-pc-linux-gnu,host-powerpc64le--linux" "-outputs=[[RES:.+\.o]]" "-inputs=[[T1OBJ]],[[T2OBJ]],[[HOSTOBJ]]"
// CHK-BUJOBS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le--linux" "-S" {{.*}}"-fopenmp" {{.*}}"-o" "[[HOSTASM:.+\.s]]" "-x" "ir" "[[HOSTBC]]"
// CHK-BUJOBS-ST: clang{{.*}}" "-cc1as" "-triple" "powerpc64le--linux" "-filetype" "obj" {{.*}}"-o" "[[HOSTOBJ:.+\.o]]" "[[HOSTASM]]"
// CHK-BUJOBS-ST: clang-offload-bundler" "-type=o" "-targets=openmp-powerpc64le-ibm-linux-gnu,openmp-x86_64-pc-linux-gnu,host-powerpc64le--linux" "-outputs=[[RES:.+\.o]]" "-inputs=[[T1OBJ]],[[T2OBJ]],[[HOSTOBJ]]"