Skip to content

Commit d50139d

Browse files
mdtoguchivladimirlaz
authored andcommitted
[SYCL] Add driver support for fat archives
Signed-off-by: Michael Toguchi <michael.d.toguchi@intel.com>
1 parent e8ac887 commit d50139d

File tree

8 files changed

+118
-12
lines changed

8 files changed

+118
-12
lines changed

clang/include/clang/Driver/Options.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1554,6 +1554,7 @@ def fobjc_nonfragile_abi : Flag<["-"], "fobjc-nonfragile-abi">, Group<f_Group>;
15541554
def fno_objc_nonfragile_abi : Flag<["-"], "fno-objc-nonfragile-abi">, Group<f_Group>;
15551555

15561556
def fobjc_sender_dependent_dispatch : Flag<["-"], "fobjc-sender-dependent-dispatch">, Group<f_Group>;
1557+
def foffload_static_lib_EQ : CommaJoined<["-"], "foffload-static-lib=">, Flags<[DriverOption]>;
15571558
def fomit_frame_pointer : Flag<["-"], "fomit-frame-pointer">, Group<f_Group>;
15581559
def fopenmp : Flag<["-"], "fopenmp">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused]>,
15591560
HelpText<"Parse OpenMP pragmas and generate parallel code.">;

clang/lib/Driver/Driver.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3131,6 +3131,17 @@ class OffloadingActionBuilder final {
31313131
// If this is an unbundling action use it as is for each SYCL toolchain.
31323132
if (auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) {
31333133
SYCLDeviceActions.clear();
3134+
auto *IA = cast<InputAction>(UA->getInputs().back());
3135+
std::string FileName = IA->getInputArg().getAsString(Args);
3136+
// Check if the type of the file is the same as the action. Do not
3137+
// unbundle it if it is not. Do not unbundle .so files, for example,
3138+
// which are not object files.
3139+
if (IA->getType() == types::TY_Object &&
3140+
(!llvm::sys::path::has_extension(FileName) ||
3141+
types::lookupTypeForExtension(
3142+
llvm::sys::path::extension(FileName).drop_front()) !=
3143+
types::TY_Object))
3144+
return ABRT_Inactive;
31343145
for (unsigned I = 0; I < ToolChains.size(); ++I) {
31353146
SYCLDeviceActions.push_back(UA);
31363147
UA->registerDependentActionInfo(

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6308,10 +6308,35 @@ void OffloadBundler::ConstructJobMultipleOutputs(
63086308

63096309
assert(Inputs.size() == 1 && "Expecting to unbundle a single file!");
63106310
InputInfo Input = Inputs.front();
6311+
const char *TypeArg = types::getTypeTempSuffix(Input.getType());
6312+
const char *InputFileName = Input.getFilename();
6313+
6314+
// For objects, we have initial support for fat archives (archives which
6315+
// contain bundled objects). We will perform partial linking against the
6316+
// object and specific offload target archives which will be sent to the
6317+
// unbundler to produce a list of target objects.
6318+
if (Input.getType() == types::TY_Object &&
6319+
TCArgs.hasArg(options::OPT_foffload_static_lib_EQ)) {
6320+
TypeArg = "oo";
6321+
ArgStringList LinkArgs;
6322+
LinkArgs.push_back("-r");
6323+
LinkArgs.push_back("-o");
6324+
std::string TmpName =
6325+
C.getDriver().GetTemporaryPath(
6326+
llvm::sys::path::stem(Input.getFilename()).str() + "-prelink", "o");
6327+
InputFileName = C.addTempFile(C.getArgs().MakeArgString(TmpName));
6328+
LinkArgs.push_back(InputFileName);
6329+
// Input files consist of fat libraries and the object to be unbundled.
6330+
LinkArgs.push_back(Input.getFilename());
6331+
for (const auto& A :
6332+
TCArgs.getAllArgValues(options::OPT_foffload_static_lib_EQ))
6333+
LinkArgs.push_back(TCArgs.MakeArgString(A));
6334+
const char *Exec = TCArgs.MakeArgString(getToolChain().GetLinkerPath());
6335+
C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, LinkArgs, Inputs));
6336+
}
63116337

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

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

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

63416366
// Get unbundled files command.
63426367
SmallString<128> UB;

clang/lib/Driver/ToolChains/Gnu.cpp

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,33 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
476476

477477
bool NeedsSanitizerDeps = addSanitizerRuntimes(ToolChain, Args, CmdArgs);
478478
bool NeedsXRayDeps = addXRayRuntime(ToolChain, Args, CmdArgs);
479-
AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
479+
// When offloading, the input file(s) could be from unbundled partially
480+
// linked archives. The unbundled information is a list of files and not
481+
// an actual object/archive. Take that list and pass those to the linker
482+
// instead of the original object.
483+
if (JA.isDeviceOffloading(Action::OFK_OpenMP) &&
484+
Args.hasArg(options::OPT_foffload_static_lib_EQ)) {
485+
InputInfoList UpdatedInputs;
486+
// Go through the Inputs to the link. When an object is encountered, we
487+
// know it is an unbundled generated list.
488+
// FIXME - properly add objects from list to be removed when compilation is
489+
// complete.
490+
for (const auto &II : Inputs) {
491+
if (II.getType() == types::TY_Object) {
492+
// Read each line of the generated unbundle file and add them to the
493+
// link.
494+
std::string FileName(II.getFilename());
495+
const char * ArgFile = C.getArgs().MakeArgString("@" + FileName);
496+
auto CurInput = InputInfo(types::TY_Object, ArgFile, ArgFile);
497+
UpdatedInputs.push_back(CurInput);
498+
} else
499+
UpdatedInputs.push_back(II);
500+
}
501+
AddLinkerInputs(ToolChain, UpdatedInputs, Args, CmdArgs, JA);
502+
}
503+
else
504+
AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
505+
480506
// The profile runtime also needs access to system libraries.
481507
getToolChain().addProfileRTLibs(Args, CmdArgs);
482508

clang/lib/Driver/ToolChains/SYCL.cpp

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,31 @@ const char *SYCL::Linker::constructLLVMSpirvCommand(Compilation &C,
5353
}
5454

5555
const char *SYCL::Linker::constructLLVMLinkCommand(
56-
Compilation &C, const JobAction &JA, StringRef SubArchName,
57-
StringRef OutputFilePrefix,
56+
Compilation &C, const JobAction &JA, const ArgList &Args,
57+
StringRef SubArchName, StringRef OutputFilePrefix,
5858
const llvm::opt::ArgStringList &InputFiles) const {
5959
ArgStringList CmdArgs;
6060
// Add the input bc's created by compile step.
61-
for (const auto &II : InputFiles)
62-
CmdArgs.push_back(II);
61+
// When offloading, the input file(s) could be from unbundled partially
62+
// linked archives. The unbundled information is a list of files and not
63+
// an actual object/archive. Take that list and pass those to the linker
64+
// instead of the original object.
65+
if (JA.isDeviceOffloading(Action::OFK_SYCL) &&
66+
Args.hasArg(options::OPT_foffload_static_lib_EQ)) {
67+
// Go through the Inputs to the link. When an object is encountered, we
68+
// know it is an unbundled generated list.
69+
// FIXME - properly add objects from list to be removed when compilation is
70+
// complete.
71+
for (const auto &II : InputFiles) {
72+
// Read each line of the generated unbundle file and add them to the link.
73+
std::string FileName(II);
74+
CmdArgs.push_back(C.getArgs().MakeArgString("@" + FileName));
75+
}
76+
}
77+
else
78+
for (const auto &II : InputFiles)
79+
CmdArgs.push_back(II);
80+
6381
// Add an intermediate output file.
6482
CmdArgs.push_back("-o");
6583
SmallString<128> TmpName(C.getDriver().GetTemporaryPath(
@@ -77,7 +95,7 @@ const char *SYCL::Linker::constructLLVMLinkCommand(
7795
void SYCL::Linker::constructLlcCommand(Compilation &C, const JobAction &JA,
7896
const InputInfo &Output, const char *InputFileName) const {
7997
// Construct llc command.
80-
// The output is an object file
98+
// The output is an object file.
8199
ArgStringList LlcArgs{"-filetype=obj", "-o", Output.getFilename(),
82100
InputFileName};
83101
SmallString<128> LlcPath(C.getDriver().Dir);
@@ -88,7 +106,7 @@ void SYCL::Linker::constructLlcCommand(Compilation &C, const JobAction &JA,
88106

89107
// For SYCL the inputs of the linker job are SPIR-V binaries and output is
90108
// a single SPIR-V binary. Input can also be bitcode when specified by
91-
// the user
109+
// the user.
92110
void SYCL::Linker::ConstructJob(Compilation &C, const JobAction &JA,
93111
const InputInfo &Output,
94112
const InputInfoList &Inputs,
@@ -112,7 +130,8 @@ void SYCL::Linker::ConstructJob(Compilation &C, const JobAction &JA,
112130
if (!II.isFilename())
113131
continue;
114132
if (Args.hasFlag(options::OPT_fsycl_use_bitcode,
115-
options::OPT_fno_sycl_use_bitcode, true))
133+
options::OPT_fno_sycl_use_bitcode, true) ||
134+
Args.hasArg(options::OPT_foffload_static_lib_EQ))
116135
SpirvInputs.push_back(II.getFilename());
117136
else {
118137
const char *LLVMSpirvOutputFile =
@@ -122,7 +141,7 @@ void SYCL::Linker::ConstructJob(Compilation &C, const JobAction &JA,
122141
}
123142
}
124143
const char *LLVMLinkOutputFile =
125-
constructLLVMLinkCommand(C, JA, SubArchName, Prefix, SpirvInputs);
144+
constructLLVMLinkCommand(C, JA, Args, SubArchName, Prefix, SpirvInputs);
126145
constructLLVMSpirvCommand(C, JA, Output, Prefix, false, LLVMLinkOutputFile);
127146
}
128147

clang/lib/Driver/ToolChains/SYCL.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ class LLVM_LIBRARY_VISIBILITY Linker : public Tool {
3939
bool isBc, const char *InputFile) const;
4040
/// \return llvm-link output file name.
4141
const char *constructLLVMLinkCommand(Compilation &C, const JobAction &JA,
42+
const llvm::opt::ArgList &Args,
4243
llvm::StringRef SubArchName,
4344
llvm::StringRef OutputFilePrefix,
4445
const llvm::opt::ArgStringList &InputFiles) const;

clang/test/Driver/openmp-offload.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -655,3 +655,14 @@
655655
// RUN: | FileCheck -check-prefix=CHK-FOPENMP-IS-DEVICE %s
656656

657657
// CHK-FOPENMP-IS-DEVICE: clang{{.*}} "-aux-triple" "powerpc64le-unknown-linux" {{.*}}.c" "-fopenmp-is-device" "-fopenmp-host-ir-file-path"
658+
659+
/// ###########################################################################
660+
661+
/// test behaviors of -foffload-static-lib=<lib>
662+
// RUN: touch %t.a
663+
// RUN: touch %t.o
664+
// RUN: %clang -fopenmp -fopenmp-targets=x86_64-pc-linux-gnu -foffload-static-lib=%t.a -### %t.o 2>&1 \
665+
// RUN: | FileCheck %s -check-prefix=FOFFLOAD_STATIC_LIB
666+
// FOFFLOAD_STATIC_LIB: ld{{(.exe)?}}" "-r" "-o" {{.*}} "[[INPUT:.+\.o]]"
667+
// FOFFLOAD_STATIC_LIB: clang-offload-bundler{{.*}} "-type=oo"
668+
// FOFFLOAD_STATIC_LIB: ld{{.*}} "@{{.*}}"

clang/test/Driver/sycl-offload.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,3 +277,15 @@
277277
// RUN: %clang -fsycl -target x86_64-unknown-linux-gnu %s -o %t -### 2>&1 | FileCheck -check-prefix=CHECK-LD-SYCL %s
278278
// CHECK-LD-SYCL: "{{.*}}ld{{(.exe)?}}"
279279
// CHECK-LD-SYCL: "-lsycl"
280+
281+
/// ###########################################################################
282+
283+
/// test behaviors of -foffload-static-lib=<lib>
284+
// RUN: touch %t.a
285+
// RUN: touch %t.o
286+
// RUN: %clang -fsycl -foffload-static-lib=%t.a -### %t.o 2>&1 \
287+
// RUN: | FileCheck %s -check-prefix=FOFFLOAD_STATIC_LIB
288+
// FOFFLOAD_STATIC_LIB: ld{{(.exe)?}}" "-r" "-o" {{.*}} "[[INPUT:.+\.o]]"
289+
// FOFFLOAD_STATIC_LIB: clang-offload-bundler{{.*}} "-type=oo"
290+
// FOFFLOAD_STATIC_LIB: llvm-link{{.*}} "@{{.*}}"
291+

0 commit comments

Comments
 (0)