Skip to content

Commit

Permalink
[Driver][OpenMP] Add support to create jobs for bundling actions.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Samuel Antao committed Oct 27, 2016
1 parent fab4f37 commit 7cab8f1
Show file tree
Hide file tree
Showing 7 changed files with 141 additions and 2 deletions.
2 changes: 2 additions & 0 deletions clang/include/clang/Driver/Action.h
Expand Up @@ -160,6 +160,8 @@ class Action {
/// 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.
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/Driver/ToolChain.h
Expand Up @@ -85,10 +85,12 @@ class ToolChain {
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;

Expand Down
17 changes: 17 additions & 0 deletions clang/lib/Driver/Action.cpp
Expand Up @@ -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"
Expand Down Expand Up @@ -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)
Expand Down
9 changes: 7 additions & 2 deletions clang/lib/Driver/ToolChain.cpp
Expand Up @@ -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:
Expand Down Expand Up @@ -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.");
Expand Down
66 changes: 66 additions & 0 deletions clang/lib/Driver/Tools.cpp
Expand Up @@ -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,
Expand Down
13 changes: 13 additions & 0 deletions clang/lib/Driver/Tools.h
Expand Up @@ -137,6 +137,19 @@ class LLVM_LIBRARY_VISIBILITY ClangAs : public Tool {
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 {
Expand Down
34 changes: 34 additions & 0 deletions clang/test/Driver/openmp-offload.c
Expand Up @@ -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]]"

0 comments on commit 7cab8f1

Please sign in to comment.