Skip to content

Commit cb3a5d7

Browse files
authored
[Driver][SYCL][FPGA] Improve host object retention for fsycl-link (#2431)
When compiling for -fsycl-link=early to -fsycl-link=image, the host object was lost in the shuffle. We want that to stick around. We do this by wrapping the host object before putting it into the device archive. When needed in subsequent compilations, we unbundle the host object.
1 parent 2bb0cf7 commit cb3a5d7

File tree

3 files changed

+71
-20
lines changed

3 files changed

+71
-20
lines changed

clang/lib/Driver/Driver.cpp

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5138,14 +5138,33 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
51385138

51395139
// For an FPGA archive, we add the unbundling step above to take care of
51405140
// the device side, but also unbundle here to extract the host side
5141-
for (const auto &LI : LinkerInputs) {
5141+
bool EarlyLink = false;
5142+
if (const Arg *A = Args.getLastArg(options::OPT_fsycl_link_EQ))
5143+
EarlyLink = A->getValue() == StringRef("early");
5144+
for (auto &LI : LinkerInputs) {
51425145
Action *UnbundlerInput = nullptr;
5146+
auto wrapObject = [&] {
5147+
if (EarlyLink && Args.hasArg(options::OPT_fintelfpga)) {
5148+
// Only wrap the object with -fsycl-link=early
5149+
auto *BC = C.MakeAction<OffloadWrapperJobAction>(LI, types::TY_LLVM_BC);
5150+
auto *ASM = C.MakeAction<BackendJobAction>(BC, types::TY_PP_Asm);
5151+
LI = C.MakeAction<AssembleJobAction>(ASM, types::TY_Object);
5152+
}
5153+
};
51435154
if (auto *IA = dyn_cast<InputAction>(LI)) {
51445155
if (IA->getType() == types::TY_FPGA_AOCR ||
51455156
IA->getType() == types::TY_FPGA_AOCX) {
51465157
// Add to unbundler.
51475158
UnbundlerInput = LI;
5159+
} else {
5160+
std::string FileName = IA->getInputArg().getAsString(Args);
5161+
if ((IA->getType() == types::TY_Object && !isObjectFile(FileName)) ||
5162+
IA->getInputArg().getOption().hasFlag(options::LinkerInput))
5163+
continue;
5164+
wrapObject();
51485165
}
5166+
} else {
5167+
wrapObject();
51495168
}
51505169
if (UnbundlerInput && !PL.empty()) {
51515170
if (auto *IA = dyn_cast<InputAction>(UnbundlerInput)) {
@@ -6159,8 +6178,6 @@ InputInfo Driver::BuildJobsForActionNoCache(
61596178
OffloadingPrefix += "-wrapper";
61606179
if (Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o))
61616180
BaseInput = FinalOutput->getValue();
6162-
else
6163-
BaseInput = getDefaultImageName();
61646181
}
61656182
}
61666183
Result = InputInfo(A, GetNamedOutputPath(C, *JA, BaseInput, BoundArch,

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7699,6 +7699,30 @@ void OffloadWrapper::ConstructJob(Compilation &C, const JobAction &JA,
76997699
assert(JA.getInputs().size() == Inputs.size() &&
77007700
"Not have inputs for all dependence actions??");
77017701

7702+
// For FPGA, we wrap the host objects before archiving them when using
7703+
// -fsycl-link. This allows for better extraction control from the
7704+
// archive when we need the host objects for subsequent compilations.
7705+
if (OffloadingKind == Action::OFK_None &&
7706+
C.getArgs().hasArg(options::OPT_fintelfpga) &&
7707+
C.getArgs().hasArg(options::OPT_fsycl_link_EQ)) {
7708+
7709+
// Add offload targets and inputs.
7710+
CmdArgs.push_back(C.getArgs().MakeArgString(
7711+
Twine("-kind=") + Action::GetOffloadKindName(OffloadingKind)));
7712+
CmdArgs.push_back(
7713+
TCArgs.MakeArgString(Twine("-target=") + Triple.getTriple()));
7714+
7715+
// Add input.
7716+
assert(Inputs[0].isFilename() && "Invalid input.");
7717+
CmdArgs.push_back(TCArgs.MakeArgString(Inputs[0].getFilename()));
7718+
7719+
C.addCommand(std::make_unique<Command>(
7720+
JA, *this, ResponseFileSupport::None(),
7721+
TCArgs.MakeArgString(getToolChain().GetProgramPath(getShortName())),
7722+
CmdArgs, Inputs));
7723+
return;
7724+
}
7725+
77027726
// Add offload targets and inputs.
77037727
for (unsigned I = 0; I < Inputs.size(); ++I) {
77047728
// Get input's Offload Kind and ToolChain.

clang/test/Driver/sycl-offload-intelfpga.cpp

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,12 @@
3535
// CHK-FPGA-LINK: llvm-spirv{{.*}} "-o" "[[OUTPUT3:.+\.spv]]" "-spirv-max-version=1.1" "-spirv-debug-info-version=legacy" "-spirv-ext=+all,-SPV_INTEL_usm_storage_classes" "[[OUTPUT2]]"
3636
// CHK-FPGA-EARLY: aoc{{.*}} "-o" "[[OUTPUT4:.+\.aocr]]" "[[OUTPUT3]]" "-sycl" "-rtl"
3737
// CHK-FPGA-IMAGE: aoc{{.*}} "-o" "[[OUTPUT5:.+\.aocx]]" "[[OUTPUT3]]" "-sycl"
38-
// CHK-FPGA-LINK: llvm-ar{{.*}} "cr" "libfoo.a" "[[INPUT]]"
38+
// CHK-FPGA-LINK: clang-offload-wrapper{{.*}} "-o=[[WRAPOUT:.+\.bc]]" "-host=x86_64-unknown-linux-gnu" {{.*}} "-kind=sycl"
39+
// CHK-FPGA-LINK: llc{{.*}} "-o" "[[OBJOUTDEV:.+\.o]]" "[[WRAPOUT]]"
40+
// CHK-FPGA-EARLY: clang-offload-wrapper{{.*}} "-host" "x86_64-unknown-linux-gnu" "-o" "[[WRAPOUTHOST:.+\.bc]]" "-kind=host"
41+
// CHK-FPGA-EARLY: clang{{.*}} "-o" "[[OBJOUT:.+\.o]]" {{.*}} "[[WRAPOUTHOST]]"
42+
// CHK-FPGA-EARLY: llvm-ar{{.*}} "cr" "libfoo.a" "[[OBJOUT]]" "[[OBJOUTDEV]]"
43+
// CHK-FPGA-IMAGE: llvm-ar{{.*}} "cr" "libfoo.a" "[[INPUT]]" "[[OBJOUTDEV]]"
3944

4045
// Output designation should not be used for unbundling step
4146
// RUN: touch %t.o
@@ -60,7 +65,11 @@
6065
// CHK-FPGA-LINK-WIN: sycl-post-link{{.*}} "-ir-output-only" "-spec-const=default" "-o" "[[OUTPUT2:.+\.bc]]" "[[OUTPUT2_1]]"
6166
// CHK-FPGA-LINK-WIN: llvm-spirv{{.*}} "-o" "[[OUTPUT3:.+\.spv]]" "-spirv-max-version=1.1" "-spirv-debug-info-version=legacy" "-spirv-ext=+all,-SPV_INTEL_usm_storage_classes" "[[OUTPUT2]]"
6267
// CHK-FPGA-LINK-WIN: aoc{{.*}} "-o" "[[OUTPUT5:.+\.aocr]]" "[[OUTPUT3]]" "-sycl" "-rtl"
63-
// CHK-FPGA-LINK-WIN: lib.exe{{.*}} "[[INPUT]]" {{.*}} "-OUT:libfoo.lib"
68+
// CHK-FPGA-LINK-WIN: clang-offload-wrapper{{.*}} "-o=[[WRAPOUT:.+\.bc]]" {{.*}} "-kind=sycl"
69+
// CHK-FPGA-LINK-WIN: llc{{.*}} "-o" "[[OBJOUTDEV:.+\.obj]]" "[[WRAPOUT]]"
70+
// CHK-FPGA-LINK-WIN: clang-offload-wrapper{{.*}} "-o" "[[WRAPOUTHOST:.+\.bc]]" "-kind=host"
71+
// CHK-FPGA-LINK-WIN: clang{{.*}} "-o" "[[OBJOUT:.+\.obj]]" {{.*}} "[[WRAPOUTHOST]]"
72+
// CHK-FPGA-LINK-WIN: lib.exe{{.*}} "[[OBJOUT]]" "[[OBJOUTDEV]]" {{.*}} "-OUT:libfoo.lib"
6473

6574
/// Check -fintelfpga -fsycl-link with an FPGA archive
6675
// Create the dummy archive
@@ -83,7 +92,7 @@
8392
// CHK-FPGA-LINK-LIB-EARLY: clang-offload-wrapper{{.*}} "-host=x86_64-unknown-linux-gnu" "-target=fpga_aocr-intel-unknown-sycldevice" "-kind=sycl" "[[OUTPUT4]]"
8493
// CHK-FPGA-LINK-LIB: llc{{.*}} "-filetype=obj" "-o" "[[OUTPUT5:.+\.o]]"
8594
// CHK-FPGA-LINK-LIB: clang-offload-bundler{{.*}} "-type=aoo" "-targets=host-x86_64-unknown-linux-gnu" "-inputs=[[INPUT]]" "-outputs=[[OUTPUT1:.+\.txt]]" "-unbundle"
86-
// CHK-FPGA-LINK-LIB: llvm-ar{{.*}} "cr" {{.*}} "@[[OUTPUT1]]"
95+
// CHK-FPGA-LINK-LIB-IMAGE: llvm-ar{{.*}} "cr" {{.*}} "@[[OUTPUT1]]"
8796

8897
/// Check the warning's emission for -fsycl-link's appending behavior
8998
// RUN: touch dummy.a
@@ -186,28 +195,29 @@
186195
/// -fintelfpga -fsycl-link from source
187196
// RUN: touch %t.cpp
188197
// RUN: %clangxx -### -target x86_64-unknown-linux-gnu -fsycl -fno-sycl-device-lib=all -fintelfpga -fsycl-link=early %t.cpp -ccc-print-phases 2>&1 \
189-
// RUN: | FileCheck -check-prefixes=CHK-FPGA-LINK-SRC,CHK-FPGA-LINK-SRC-DEFAULT %s
190-
// RUN: %clang_cl -### -target x86_64-unknown-linux-gnu -fsycl -fno-sycl-device-lib=all -fintelfpga -fsycl-link=early %t.cpp -ccc-print-phases 2>&1 \
191-
// RUN: | FileCheck -check-prefixes=CHK-FPGA-LINK-SRC,CHK-FPGA-LINK-SRC-CL %s
198+
// RUN: | FileCheck -check-prefixes=CHK-FPGA-LINK-SRC %s
199+
// RUN: %clang_cl -### --target=x86_64-unknown-linux-gnu -fsycl -fno-sycl-device-lib=all -fintelfpga -fsycl-link=early %t.cpp -ccc-print-phases 2>&1 \
200+
// RUN: | FileCheck -check-prefixes=CHK-FPGA-LINK-SRC %s
192201
// CHK-FPGA-LINK-SRC: 0: input, "[[INPUT:.+\.cpp]]", c++, (host-sycl)
193202
// CHK-FPGA-LINK-SRC: 1: preprocessor, {0}, c++-cpp-output, (host-sycl)
194203
// CHK-FPGA-LINK-SRC: 2: input, "[[INPUT]]", c++, (device-sycl)
195204
// CHK-FPGA-LINK-SRC: 3: preprocessor, {2}, c++-cpp-output, (device-sycl)
196205
// CHK-FPGA-LINK-SRC: 4: compiler, {3}, sycl-header, (device-sycl)
197-
// CHK-FPGA-LINK-SRC-DEFAULT: 5: offload, "host-sycl (x86_64-unknown-linux-gnu)" {1}, "device-sycl (spir64_fpga-unknown-unknown-sycldevice)" {4}, c++-cpp-output
198-
// CHK-FPGA-LINK-SRC-CL: 5: offload, "host-sycl (x86_64-pc-windows-msvc)" {1}, "device-sycl (spir64_fpga-unknown-unknown-sycldevice)" {4}, c++-cpp-output
206+
// CHK-FPGA-LINK-SRC: 5: offload, "host-sycl (x86_64-unknown-linux-gnu)" {1}, "device-sycl (spir64_fpga-unknown-unknown-sycldevice)" {4}, c++-cpp-output
199207
// CHK-FPGA-LINK-SRC: 6: compiler, {5}, ir, (host-sycl)
200208
// CHK-FPGA-LINK-SRC: 7: backend, {6}, assembler, (host-sycl)
201209
// CHK-FPGA-LINK-SRC: 8: assembler, {7}, object, (host-sycl)
202-
// CHK-FPGA-LINK-SRC: 9: linker, {8}, archive, (host-sycl)
203-
// CHK-FPGA-LINK-SRC: 10: compiler, {3}, ir, (device-sycl)
204-
// CHK-FPGA-LINK-SRC: 11: linker, {10}, ir, (device-sycl)
205-
// CHK-FPGA-LINK-SRC: 12: sycl-post-link, {11}, ir, (device-sycl)
206-
// CHK-FPGA-LINK-SRC: 13: llvm-spirv, {12}, spirv, (device-sycl)
207-
// CHK-FPGA-LINK-SRC: 14: backend-compiler, {13}, fpga_aocr, (device-sycl)
208-
// CHK-FPGA-LINK-SRC: 15: clang-offload-wrapper, {14}, object, (device-sycl)
209-
// CHK-FPGA-LINK-SRC-DEFAULT: 16: offload, "host-sycl (x86_64-unknown-linux-gnu)" {9}, "device-sycl (spir64_fpga-unknown-unknown-sycldevice)" {15}, archive
210-
// CHK-FPGA-LINK-SRC-CL: 16: offload, "host-sycl (x86_64-pc-windows-msvc)" {9}, "device-sycl (spir64_fpga-unknown-unknown-sycldevice)" {15}, archive
210+
// CHK-FPGA-LINK-SRC: 9: clang-offload-wrapper, {8}, ir, (host-sycl)
211+
// CHK-FPGA-LINK-SRC: 10: backend, {9}, assembler, (host-sycl)
212+
// CHK-FPGA-LINK-SRC: 11: assembler, {10}, object, (host-sycl)
213+
// CHK-FPGA-LINK-SRC: 12: linker, {11}, archive, (host-sycl)
214+
// CHK-FPGA-LINK-SRC: 13: compiler, {3}, ir, (device-sycl)
215+
// CHK-FPGA-LINK-SRC: 14: linker, {13}, ir, (device-sycl)
216+
// CHK-FPGA-LINK-SRC: 15: sycl-post-link, {14}, ir, (device-sycl)
217+
// CHK-FPGA-LINK-SRC: 16: llvm-spirv, {15}, spirv, (device-sycl)
218+
// CHK-FPGA-LINK-SRC: 17: backend-compiler, {16}, fpga_aocr, (device-sycl)
219+
// CHK-FPGA-LINK-SRC: 18: clang-offload-wrapper, {17}, object, (device-sycl)
220+
// CHK-FPGA-LINK-SRC: 19: offload, "host-sycl (x86_64-unknown-linux-gnu)" {12}, "device-sycl (spir64_fpga-unknown-unknown-sycldevice)" {18}, archive
211221

212222
/// -fintelfpga with -reuse-exe=
213223
// RUN: touch %t.cpp

0 commit comments

Comments
 (0)