Skip to content

Commit

Permalink
[SYCL] Add driver support for fat archives
Browse files Browse the repository at this point in the history
Signed-off-by: Michael Toguchi <michael.d.toguchi@intel.com>
  • Loading branch information
mdtoguchi authored and vladimirlaz committed Apr 4, 2019
1 parent e8ac887 commit d50139d
Show file tree
Hide file tree
Showing 8 changed files with 118 additions and 12 deletions.
1 change: 1 addition & 0 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -1554,6 +1554,7 @@ def fobjc_nonfragile_abi : Flag<["-"], "fobjc-nonfragile-abi">, Group<f_Group>;
def fno_objc_nonfragile_abi : Flag<["-"], "fno-objc-nonfragile-abi">, Group<f_Group>;

def fobjc_sender_dependent_dispatch : Flag<["-"], "fobjc-sender-dependent-dispatch">, Group<f_Group>;
def foffload_static_lib_EQ : CommaJoined<["-"], "foffload-static-lib=">, Flags<[DriverOption]>;
def fomit_frame_pointer : Flag<["-"], "fomit-frame-pointer">, Group<f_Group>;
def fopenmp : Flag<["-"], "fopenmp">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused]>,
HelpText<"Parse OpenMP pragmas and generate parallel code.">;
Expand Down
11 changes: 11 additions & 0 deletions clang/lib/Driver/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3131,6 +3131,17 @@ class OffloadingActionBuilder final {
// If this is an unbundling action use it as is for each SYCL toolchain.
if (auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) {
SYCLDeviceActions.clear();
auto *IA = cast<InputAction>(UA->getInputs().back());
std::string FileName = IA->getInputArg().getAsString(Args);
// Check if the type of the file is the same as the action. Do not
// unbundle it if it is not. Do not unbundle .so files, for example,
// which are not object files.
if (IA->getType() == types::TY_Object &&
(!llvm::sys::path::has_extension(FileName) ||
types::lookupTypeForExtension(
llvm::sys::path::extension(FileName).drop_front()) !=
types::TY_Object))
return ABRT_Inactive;
for (unsigned I = 0; I < ToolChains.size(); ++I) {
SYCLDeviceActions.push_back(UA);
UA->registerDependentActionInfo(
Expand Down
31 changes: 28 additions & 3 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6308,10 +6308,35 @@ void OffloadBundler::ConstructJobMultipleOutputs(

assert(Inputs.size() == 1 && "Expecting to unbundle a single file!");
InputInfo Input = Inputs.front();
const char *TypeArg = types::getTypeTempSuffix(Input.getType());
const char *InputFileName = Input.getFilename();

// For objects, we have initial support for fat archives (archives which
// contain bundled objects). We will perform partial linking against the
// object and specific offload target archives which will be sent to the
// unbundler to produce a list of target objects.
if (Input.getType() == types::TY_Object &&
TCArgs.hasArg(options::OPT_foffload_static_lib_EQ)) {
TypeArg = "oo";
ArgStringList LinkArgs;
LinkArgs.push_back("-r");
LinkArgs.push_back("-o");
std::string TmpName =
C.getDriver().GetTemporaryPath(
llvm::sys::path::stem(Input.getFilename()).str() + "-prelink", "o");
InputFileName = C.addTempFile(C.getArgs().MakeArgString(TmpName));
LinkArgs.push_back(InputFileName);
// Input files consist of fat libraries and the object to be unbundled.
LinkArgs.push_back(Input.getFilename());
for (const auto& A :
TCArgs.getAllArgValues(options::OPT_foffload_static_lib_EQ))
LinkArgs.push_back(TCArgs.MakeArgString(A));
const char *Exec = TCArgs.MakeArgString(getToolChain().GetLinkerPath());
C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, LinkArgs, Inputs));
}

// Get the type.
CmdArgs.push_back(TCArgs.MakeArgString(
Twine("-type=") + types::getTypeTempSuffix(Input.getType())));
CmdArgs.push_back(TCArgs.MakeArgString(Twine("-type=") + TypeArg));

// Get the targets.
SmallString<128> Triples;
Expand All @@ -6336,7 +6361,7 @@ void OffloadBundler::ConstructJobMultipleOutputs(

// Get bundled file command.
CmdArgs.push_back(
TCArgs.MakeArgString(Twine("-inputs=") + Input.getFilename()));
TCArgs.MakeArgString(Twine("-inputs=") + InputFileName));

// Get unbundled files command.
SmallString<128> UB;
Expand Down
28 changes: 27 additions & 1 deletion clang/lib/Driver/ToolChains/Gnu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,33 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,

bool NeedsSanitizerDeps = addSanitizerRuntimes(ToolChain, Args, CmdArgs);
bool NeedsXRayDeps = addXRayRuntime(ToolChain, Args, CmdArgs);
AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
// When offloading, the input file(s) could be from unbundled partially
// linked archives. The unbundled information is a list of files and not
// an actual object/archive. Take that list and pass those to the linker
// instead of the original object.
if (JA.isDeviceOffloading(Action::OFK_OpenMP) &&
Args.hasArg(options::OPT_foffload_static_lib_EQ)) {
InputInfoList UpdatedInputs;
// Go through the Inputs to the link. When an object is encountered, we
// know it is an unbundled generated list.
// FIXME - properly add objects from list to be removed when compilation is
// complete.
for (const auto &II : Inputs) {
if (II.getType() == types::TY_Object) {
// Read each line of the generated unbundle file and add them to the
// link.
std::string FileName(II.getFilename());
const char * ArgFile = C.getArgs().MakeArgString("@" + FileName);
auto CurInput = InputInfo(types::TY_Object, ArgFile, ArgFile);
UpdatedInputs.push_back(CurInput);
} else
UpdatedInputs.push_back(II);
}
AddLinkerInputs(ToolChain, UpdatedInputs, Args, CmdArgs, JA);
}
else
AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);

// The profile runtime also needs access to system libraries.
getToolChain().addProfileRTLibs(Args, CmdArgs);

Expand Down
35 changes: 27 additions & 8 deletions clang/lib/Driver/ToolChains/SYCL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,31 @@ const char *SYCL::Linker::constructLLVMSpirvCommand(Compilation &C,
}

const char *SYCL::Linker::constructLLVMLinkCommand(
Compilation &C, const JobAction &JA, StringRef SubArchName,
StringRef OutputFilePrefix,
Compilation &C, const JobAction &JA, const ArgList &Args,
StringRef SubArchName, StringRef OutputFilePrefix,
const llvm::opt::ArgStringList &InputFiles) const {
ArgStringList CmdArgs;
// Add the input bc's created by compile step.
for (const auto &II : InputFiles)
CmdArgs.push_back(II);
// When offloading, the input file(s) could be from unbundled partially
// linked archives. The unbundled information is a list of files and not
// an actual object/archive. Take that list and pass those to the linker
// instead of the original object.
if (JA.isDeviceOffloading(Action::OFK_SYCL) &&
Args.hasArg(options::OPT_foffload_static_lib_EQ)) {
// Go through the Inputs to the link. When an object is encountered, we
// know it is an unbundled generated list.
// FIXME - properly add objects from list to be removed when compilation is
// complete.
for (const auto &II : InputFiles) {
// Read each line of the generated unbundle file and add them to the link.
std::string FileName(II);
CmdArgs.push_back(C.getArgs().MakeArgString("@" + FileName));
}
}
else
for (const auto &II : InputFiles)
CmdArgs.push_back(II);

// Add an intermediate output file.
CmdArgs.push_back("-o");
SmallString<128> TmpName(C.getDriver().GetTemporaryPath(
Expand All @@ -77,7 +95,7 @@ const char *SYCL::Linker::constructLLVMLinkCommand(
void SYCL::Linker::constructLlcCommand(Compilation &C, const JobAction &JA,
const InputInfo &Output, const char *InputFileName) const {
// Construct llc command.
// The output is an object file
// The output is an object file.
ArgStringList LlcArgs{"-filetype=obj", "-o", Output.getFilename(),
InputFileName};
SmallString<128> LlcPath(C.getDriver().Dir);
Expand All @@ -88,7 +106,7 @@ void SYCL::Linker::constructLlcCommand(Compilation &C, const JobAction &JA,

// For SYCL the inputs of the linker job are SPIR-V binaries and output is
// a single SPIR-V binary. Input can also be bitcode when specified by
// the user
// the user.
void SYCL::Linker::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output,
const InputInfoList &Inputs,
Expand All @@ -112,7 +130,8 @@ void SYCL::Linker::ConstructJob(Compilation &C, const JobAction &JA,
if (!II.isFilename())
continue;
if (Args.hasFlag(options::OPT_fsycl_use_bitcode,
options::OPT_fno_sycl_use_bitcode, true))
options::OPT_fno_sycl_use_bitcode, true) ||
Args.hasArg(options::OPT_foffload_static_lib_EQ))
SpirvInputs.push_back(II.getFilename());
else {
const char *LLVMSpirvOutputFile =
Expand All @@ -122,7 +141,7 @@ void SYCL::Linker::ConstructJob(Compilation &C, const JobAction &JA,
}
}
const char *LLVMLinkOutputFile =
constructLLVMLinkCommand(C, JA, SubArchName, Prefix, SpirvInputs);
constructLLVMLinkCommand(C, JA, Args, SubArchName, Prefix, SpirvInputs);
constructLLVMSpirvCommand(C, JA, Output, Prefix, false, LLVMLinkOutputFile);
}

Expand Down
1 change: 1 addition & 0 deletions clang/lib/Driver/ToolChains/SYCL.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class LLVM_LIBRARY_VISIBILITY Linker : public Tool {
bool isBc, const char *InputFile) const;
/// \return llvm-link output file name.
const char *constructLLVMLinkCommand(Compilation &C, const JobAction &JA,
const llvm::opt::ArgList &Args,
llvm::StringRef SubArchName,
llvm::StringRef OutputFilePrefix,
const llvm::opt::ArgStringList &InputFiles) const;
Expand Down
11 changes: 11 additions & 0 deletions clang/test/Driver/openmp-offload.c
Original file line number Diff line number Diff line change
Expand Up @@ -655,3 +655,14 @@
// RUN: | FileCheck -check-prefix=CHK-FOPENMP-IS-DEVICE %s

// CHK-FOPENMP-IS-DEVICE: clang{{.*}} "-aux-triple" "powerpc64le-unknown-linux" {{.*}}.c" "-fopenmp-is-device" "-fopenmp-host-ir-file-path"

/// ###########################################################################

/// test behaviors of -foffload-static-lib=<lib>
// RUN: touch %t.a
// RUN: touch %t.o
// RUN: %clang -fopenmp -fopenmp-targets=x86_64-pc-linux-gnu -foffload-static-lib=%t.a -### %t.o 2>&1 \
// RUN: | FileCheck %s -check-prefix=FOFFLOAD_STATIC_LIB
// FOFFLOAD_STATIC_LIB: ld{{(.exe)?}}" "-r" "-o" {{.*}} "[[INPUT:.+\.o]]"
// FOFFLOAD_STATIC_LIB: clang-offload-bundler{{.*}} "-type=oo"
// FOFFLOAD_STATIC_LIB: ld{{.*}} "@{{.*}}"
12 changes: 12 additions & 0 deletions clang/test/Driver/sycl-offload.c
Original file line number Diff line number Diff line change
Expand Up @@ -277,3 +277,15 @@
// RUN: %clang -fsycl -target x86_64-unknown-linux-gnu %s -o %t -### 2>&1 | FileCheck -check-prefix=CHECK-LD-SYCL %s
// CHECK-LD-SYCL: "{{.*}}ld{{(.exe)?}}"
// CHECK-LD-SYCL: "-lsycl"

/// ###########################################################################

/// test behaviors of -foffload-static-lib=<lib>
// RUN: touch %t.a
// RUN: touch %t.o
// RUN: %clang -fsycl -foffload-static-lib=%t.a -### %t.o 2>&1 \
// RUN: | FileCheck %s -check-prefix=FOFFLOAD_STATIC_LIB
// FOFFLOAD_STATIC_LIB: ld{{(.exe)?}}" "-r" "-o" {{.*}} "[[INPUT:.+\.o]]"
// FOFFLOAD_STATIC_LIB: clang-offload-bundler{{.*}} "-type=oo"
// FOFFLOAD_STATIC_LIB: llvm-link{{.*}} "@{{.*}}"

0 comments on commit d50139d

Please sign in to comment.