Skip to content

Commit f253851

Browse files
authored
[Driver][SYCL][FPGA] Enable dependency file usage from static archives (#2443)
When performing compilations for FPGA, we want to be sure to take advantage of dependency information that could be part of the fat static archives.
1 parent cd98358 commit f253851

File tree

8 files changed

+130
-25
lines changed

8 files changed

+130
-25
lines changed

clang/include/clang/Driver/Types.def

+1
Original file line numberDiff line numberDiff line change
@@ -111,4 +111,5 @@ TYPE("fpga_aocx", FPGA_AOCX, INVALID, "aocx", phases
111111
TYPE("fpga_aocr", FPGA_AOCR, INVALID, "aocr", phases::Compile, phases::Backend, phases::Assemble, phases::Link)
112112
TYPE("fpga_aoco", FPGA_AOCO, INVALID, "aoco", phases::Compile, phases::Backend, phases::Assemble, phases::Link)
113113
TYPE("fpga_dependencies", FPGA_Dependencies, INVALID, "d", phases::Compile, phases::Backend, phases::Assemble, phases::Link)
114+
TYPE("fpga_dependencies_list", FPGA_Dependencies_List, INVALID, "txt", phases::Compile, phases::Backend, phases::Assemble, phases::Link)
114115
TYPE("none", Nothing, INVALID, nullptr, phases::Compile, phases::Backend, phases::Assemble, phases::Link)

clang/lib/Driver/Compilation.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,8 @@ bool Compilation::CleanupFileList(const TempFileList &Files,
150150
// Temporary file lists contain files that need to be cleaned. The
151151
// file containing the information is also removed
152152
if (File.second == types::TY_Tempfilelist ||
153-
File.second == types::TY_Tempfiletable) {
153+
File.second == types::TY_Tempfiletable ||
154+
File.second == types::TY_FPGA_Dependencies_List) {
154155
// These are temporary files and need to be removed.
155156
bool IsTable = File.second == types::TY_Tempfiletable;
156157

clang/lib/Driver/Driver.cpp

+38-9
Original file line numberDiff line numberDiff line change
@@ -3613,6 +3613,9 @@ class OffloadingActionBuilder final {
36133613
/// List of objects to extract FPGA dependency info from
36143614
ActionList FPGAObjectInputs;
36153615

3616+
/// List of static archives to extract FPGA dependency info from
3617+
ActionList FPGAArchiveInputs;
3618+
36163619
/// List of CUDA architectures to use in this compilation with NVPTX targets.
36173620
SmallVector<CudaArch, 8> GpuArchList;
36183621

@@ -4061,15 +4064,19 @@ class OffloadingActionBuilder final {
40614064
// triple calls for it (provided a valid subarch).
40624065
ActionList BEInputs;
40634066
BEInputs.push_back(BuildCodeAction);
4064-
for (Action *A : FPGAObjectInputs) {
4065-
// Send any known objects through the unbundler to grab the
4066-
// dependency file associated.
4067+
auto unbundleAdd = [&](Action *A, types::ID T) {
40674068
ActionList AL;
40684069
AL.push_back(A);
4069-
Action *UnbundleAction = C.MakeAction<OffloadUnbundlingJobAction>(
4070-
AL, types::TY_FPGA_Dependencies);
4070+
Action *UnbundleAction =
4071+
C.MakeAction<OffloadUnbundlingJobAction>(AL, T);
40714072
BEInputs.push_back(UnbundleAction);
4072-
}
4073+
};
4074+
// Send any known objects/archives through the unbundler to grab the
4075+
// dependency file associated.
4076+
for (Action *A : FPGAObjectInputs)
4077+
unbundleAdd(A, types::TY_FPGA_Dependencies);
4078+
for (Action *A : FPGAArchiveInputs)
4079+
unbundleAdd(A, types::TY_FPGA_Dependencies_List);
40734080
for (const auto &A : DeviceLibObjects)
40744081
BEInputs.push_back(A);
40754082
BuildCodeAction =
@@ -4194,6 +4201,7 @@ class OffloadingActionBuilder final {
41944201
Arg *SYCLAddTargets = Args.getLastArg(options::OPT_fsycl_add_targets_EQ);
41954202
bool HasValidSYCLRuntime = C.getInputArgs().hasFlag(options::OPT_fsycl,
41964203
options::OPT_fno_sycl, false);
4204+
bool SYCLfpgaTriple = false;
41974205
if (SYCLTargets || SYCLAddTargets) {
41984206
if (SYCLTargets) {
41994207
llvm::StringMap<StringRef> FoundNormalizedTriples;
@@ -4211,6 +4219,8 @@ class OffloadingActionBuilder final {
42114219
FoundNormalizedTriples[NormalizedName] = Val;
42124220

42134221
SYCLTripleList.push_back(TT);
4222+
if (TT.getSubArch() == llvm::Triple::SPIRSubArch_fpga)
4223+
SYCLfpgaTriple = true;
42144224
}
42154225
}
42164226
if (SYCLAddTargets) {
@@ -4234,13 +4244,30 @@ class OffloadingActionBuilder final {
42344244
const char *SYCLTargetArch = SYCLfpga ? "spir64_fpga" : "spir64";
42354245
SYCLTripleList.push_back(
42364246
C.getDriver().MakeSYCLDeviceTriple(SYCLTargetArch));
4247+
if (SYCLfpga)
4248+
SYCLfpgaTriple = true;
42374249
}
42384250

42394251
// Set the FPGA output type based on command line (-fsycl-link).
42404252
if (auto * A = C.getInputArgs().getLastArg(options::OPT_fsycl_link_EQ))
42414253
FPGAOutType = (A->getValue() == StringRef("early"))
42424254
? types::TY_FPGA_AOCR : types::TY_FPGA_AOCX;
42434255

4256+
// Populate FPGA static archives that could contain dep files to be
4257+
// incorporated into the aoc compilation
4258+
if (SYCLfpgaTriple) {
4259+
SmallVector<const char *, 16> LinkArgs(getLinkerArgs(C, Args));
4260+
for (const StringRef &LA : LinkArgs) {
4261+
if (isStaticArchiveFile(LA) && hasOffloadSections(C, LA, Args)) {
4262+
const llvm::opt::OptTable &Opts = C.getDriver().getOpts();
4263+
Arg *InputArg = MakeInputArg(Args, Opts, Args.MakeArgString(LA));
4264+
Action *Current =
4265+
C.MakeAction<InputAction>(*InputArg, types::TY_Archive);
4266+
FPGAArchiveInputs.push_back(Current);
4267+
}
4268+
}
4269+
}
4270+
42444271
DeviceLinkerInputs.resize(ToolChains.size());
42454272
return initializeGpuArchMap();
42464273
}
@@ -5976,12 +6003,14 @@ InputInfo Driver::BuildJobsForActionNoCache(
59766003
// Do a check for a dependency file unbundle for FPGA. This is out of line
59776004
// from a regular unbundle, so just create and return the name of the
59786005
// unbundled file.
5979-
if (JA->getType() == types::TY_FPGA_Dependencies) {
6006+
if (JA->getType() == types::TY_FPGA_Dependencies ||
6007+
JA->getType() == types::TY_FPGA_Dependencies_List) {
6008+
std::string Ext(types::getTypeTempSuffix(JA->getType()));
59806009
std::string TmpFileName =
5981-
C.getDriver().GetTemporaryPath(llvm::sys::path::stem(BaseInput), "d");
6010+
C.getDriver().GetTemporaryPath(llvm::sys::path::stem(BaseInput), Ext);
59826011
const char *TmpFile =
59836012
C.addTempFile(C.getArgs().MakeArgString(TmpFileName));
5984-
Result = InputInfo(types::TY_FPGA_Dependencies, TmpFile, TmpFile);
6013+
Result = InputInfo(JA->getType(), TmpFile, TmpFile);
59856014
UnbundlingResults.push_back(Result);
59866015
} else {
59876016
// Now that we have all the results generated, select the one that should

clang/lib/Driver/ToolChains/Clang.cpp

+5-4
Original file line numberDiff line numberDiff line change
@@ -7401,7 +7401,8 @@ void OffloadBundler::ConstructJobMultipleOutputs(
74017401
bool IsMSVCEnv =
74027402
C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment();
74037403
types::ID InputType(Input.getType());
7404-
bool IsFPGADepUnbundle = (JA.getType() == types::TY_FPGA_Dependencies);
7404+
bool IsFPGADepUnbundle = JA.getType() == types::TY_FPGA_Dependencies;
7405+
bool IsFPGADepLibUnbundle = JA.getType() == types::TY_FPGA_Dependencies_List;
74057406
bool IsArchiveUnbundle =
74067407
(!IsMSVCEnv && C.getDriver().getOffloadStaticLibSeen() &&
74077408
(types::isArchive(InputType) || InputType == types::TY_Object));
@@ -7417,7 +7418,7 @@ void OffloadBundler::ConstructJobMultipleOutputs(
74177418
else
74187419
TypeArg = "aoo";
74197420
}
7420-
if (InputType == types::TY_FPGA_AOCO ||
7421+
if (InputType == types::TY_FPGA_AOCO || IsFPGADepLibUnbundle ||
74217422
(IsMSVCEnv && types::isArchive(InputType)))
74227423
TypeArg = "aoo";
74237424
if (IsFPGADepUnbundle)
@@ -7476,7 +7477,7 @@ void OffloadBundler::ConstructJobMultipleOutputs(
74767477
Triples += Dep.DependentBoundArch;
74777478
}
74787479
}
7479-
if (IsFPGADepUnbundle) {
7480+
if (IsFPGADepUnbundle || IsFPGADepLibUnbundle) {
74807481
// TODO - We are currently using the target triple inputs to slot a location
74817482
// of the dependency information into the bundle. It would be good to
74827483
// separate this out to an explicit option in the bundler for the dependency
@@ -7497,7 +7498,7 @@ void OffloadBundler::ConstructJobMultipleOutputs(
74977498
// When dealing with -fintelfpga, there is an additional unbundle step
74987499
// that occurs for the dependency file. In that case, do not use the
74997500
// dependent information, but just the output file.
7500-
if (IsFPGADepUnbundle)
7501+
if (IsFPGADepUnbundle || IsFPGADepLibUnbundle)
75017502
UB += Outputs[0].getFilename();
75027503
else {
75037504
for (unsigned I = 0; I < Outputs.size(); ++I) {

clang/lib/Driver/ToolChains/SYCL.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,8 @@ void SYCL::fpga::BackendCompiler::ConstructJob(Compilation &C,
233233
// Add any FPGA library lists. These come in as special tempfile lists.
234234
CmdArgs.push_back(Args.MakeArgString(Twine("-library-list=") +
235235
Filename));
236-
else if (II.getType() == types::TY_FPGA_Dependencies)
236+
else if (II.getType() == types::TY_FPGA_Dependencies ||
237+
II.getType() == types::TY_FPGA_Dependencies_List)
237238
FPGADepFiles.push_back(II);
238239
else
239240
CmdArgs.push_back(C.getArgs().MakeArgString(Filename));
@@ -287,6 +288,8 @@ void SYCL::fpga::BackendCompiler::ConstructJob(Compilation &C,
287288
for (unsigned I = 0; I < FPGADepFiles.size(); ++I) {
288289
if (I)
289290
DepOpt += ',';
291+
if (FPGADepFiles[I].getType() == types::TY_FPGA_Dependencies_List)
292+
DepOpt += "@";
290293
DepOpt += FPGADepFiles[I].getFilename();
291294
}
292295
CmdArgs.push_back(C.getArgs().MakeArgString(DepOpt));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
///
2+
/// tests specific to -fintelfpga -fsycl w/ static libs
3+
///
4+
// REQUIRES: clang-driver
5+
// REQUIRES: system-windows
6+
7+
// make dummy archive
8+
// Build a fat static lib that will be used for all tests
9+
// RUN: echo "void foo(void) {}" > %t1.cpp
10+
// RUN: %clang_cl --target=x86_64-pc-windows-msvc -fsycl -fintelfpga %t1.cpp -c -o %t1_bundle.obj
11+
// RUN: lib -out:%t.lib %t1_bundle.obj
12+
13+
/// Check phases with static lib
14+
// RUN: %clang_cl --target=x86_64-pc-windows-msvc -fsycl -fintelfpga %t.lib -ccc-print-phases 2>&1 \
15+
// RUN: | FileCheck -check-prefix=CHECK_PHASES %s
16+
// CHECK_PHASES: 0: input, "[[INPUT:.+\.lib]]", object, (host-sycl)
17+
// CHECK_PHASES: 1: linker, {0}, image, (host-sycl)
18+
// CHECK_PHASES: 2: input, "[[INPUT]]", archive
19+
// CHECK_PHASES: 3: clang-offload-unbundler, {2}, archive
20+
// CHECK_PHASES: 4: linker, {3}, ir, (device-sycl)
21+
// CHECK_PHASES: 5: sycl-post-link, {4}, ir, (device-sycl)
22+
// CHECK_PHASES: 6: llvm-spirv, {5}, spirv, (device-sycl)
23+
// CHECK_PHASES: 7: input, "[[INPUT]]", archive
24+
// CHECK_PHASES: 8: clang-offload-unbundler, {7}, fpga_dependencies_list
25+
// CHECK_PHASES: 9: backend-compiler, {6, 8}, fpga_aocx, (device-sycl)
26+
// CHECK_PHASES: 10: clang-offload-wrapper, {9}, object, (device-sycl)
27+
// CHECK_PHASES: 11: offload, "host-sycl (x86_64-pc-windows-msvc)" {1}, "device-sycl (spir64_fpga-unknown-unknown-sycldevice)" {10}, image
28+
29+
/// Check for unbundle and use of deps in static lib
30+
// RUN: %clang_cl --target=x86_64-pc-windows-msvc -fsycl -fintelfpga %t.lib -### 2>&1 \
31+
// RUN: | FileCheck -check-prefix=CHECK_UNBUNDLE %s
32+
// CHECK_UNBUNDLE: clang-offload-bundler" "-type=aoo" "-targets=sycl-fpga_dep" "-inputs={{.*}}" "-outputs=[[DEPFILES:.+\.txt]]" "-unbundle"
33+
// CHECK_UNBUNDLE: aoc{{.*}} "-dep-files=@[[DEPFILES]]"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
///
2+
/// tests specific to -fintelfpga -fsycl w/ static libs
3+
///
4+
// REQUIRES: clang-driver
5+
6+
// make dummy archive
7+
// Build a fat static lib that will be used for all tests
8+
// RUN: echo "void foo(void) {}" > %t1.cpp
9+
// RUN: %clangxx -target x86_64-unknown-linux-gnu -fintelfpga -fsycl %t1.cpp -c -o %t1_bundle.o
10+
// RUN: llvm-ar cr %t.a %t1_bundle.o
11+
12+
/// Check phases with static lib
13+
// RUN: %clangxx -target x86_64-unknown-linux-gnu -fsycl -fintelfpga %t.a -ccc-print-phases 2>&1 \
14+
// RUN: | FileCheck -check-prefix=CHECK_PHASES %s
15+
// CHECK_PHASES: 0: input, "[[INPUT:.+\.a]]", object, (host-sycl)
16+
// CHECK_PHASES: 1: linker, {0}, image, (host-sycl)
17+
// CHECK_PHASES: 2: input, "[[INPUT]]", archive
18+
// CHECK_PHASES: 3: partial-link, {2}, object
19+
// CHECK_PHASES: 4: clang-offload-unbundler, {3}, object
20+
// CHECK_PHASES: 5: linker, {4}, ir, (device-sycl)
21+
// CHECK_PHASES: 6: sycl-post-link, {5}, ir, (device-sycl)
22+
// CHECK_PHASES: 7: llvm-spirv, {6}, spirv, (device-sycl)
23+
// CHECK_PHASES: 8: input, "[[INPUT]]", archive
24+
// CHECK_PHASES: 9: clang-offload-unbundler, {8}, fpga_dependencies_list
25+
// CHECK_PHASES: 10: backend-compiler, {7, 9}, fpga_aocx, (device-sycl)
26+
// CHECK_PHASES: 11: clang-offload-wrapper, {10}, object, (device-sycl)
27+
// CHECK_PHASES: 12: offload, "host-sycl (x86_64-unknown-linux-gnu)" {1}, "device-sycl (spir64_fpga-unknown-unknown-sycldevice)" {11}, image
28+
29+
/// Check for unbundle and use of deps in static lib
30+
// RUN: %clangxx -target x86_64-unknown-linux-gnu -fsycl -fintelfpga %t.a -### 2>&1 \
31+
// RUN: | FileCheck -check-prefix=CHECK_UNBUNDLE %s
32+
// CHECK_UNBUNDLE: clang-offload-bundler" "-type=aoo" "-targets=sycl-fpga_dep" "-inputs={{.*}}" "-outputs=[[DEPFILES:.+\.txt]]" "-unbundle"
33+
// CHECK_UNBUNDLE: aoc{{.*}} "-dep-files=@[[DEPFILES]]"

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

+14-10
Original file line numberDiff line numberDiff line change
@@ -368,11 +368,13 @@
368368
// CHK-FPGA-AOCO-PHASES: 15: linker, {11, 14}, ir, (device-sycl)
369369
// CHK-FPGA-AOCO-PHASES: 16: sycl-post-link, {15}, ir, (device-sycl)
370370
// CHK-FPGA-AOCO-PHASES: 17: llvm-spirv, {16}, spirv, (device-sycl)
371-
// CHK-FPGA-AOCO-PHASES: 18: input, "[[INPUTA]]", fpga_aoco
372-
// CHK-FPGA-AOCO-PHASES: 19: clang-offload-unbundler, {18}, fpga_aoco
373-
// CHK-FPGA-AOCO-PHASES: 20: backend-compiler, {17, 19}, fpga_aocx, (device-sycl)
374-
// CHK-FPGA-AOCO-PHASES: 21: clang-offload-wrapper, {20}, object, (device-sycl)
375-
// CHK-FPGA-AOCO-PHASES: 22: offload, "host-sycl (x86_64-unknown-linux-gnu)" {10}, "device-sycl (spir64_fpga-unknown-unknown-sycldevice)" {21}, image
371+
// CHK-FPGA-AOCO-PHASES: 18: input, "[[INPUTA]]", archive
372+
// CHK-FPGA-AOCO-PHASES: 19: clang-offload-unbundler, {18}, fpga_dependencies_list
373+
// CHK-FPGA-AOCO-PHASES: 20: input, "[[INPUTA]]", fpga_aoco
374+
// CHK-FPGA-AOCO-PHASES: 21: clang-offload-unbundler, {20}, fpga_aoco
375+
// CHK-FPGA-AOCO-PHASES: 22: backend-compiler, {17, 19, 21}, fpga_aocx, (device-sycl)
376+
// CHK-FPGA-AOCO-PHASES: 23: clang-offload-wrapper, {22}, object, (device-sycl)
377+
// CHK-FPGA-AOCO-PHASES: 24: offload, "host-sycl (x86_64-unknown-linux-gnu)" {10}, "device-sycl (spir64_fpga-unknown-unknown-sycldevice)" {23}, image
376378

377379
/// FPGA AOCO Windows phases check
378380
// RUN: %clang_cl -fsycl -fintelfpga -foffload-static-lib=%t_aoco_cl.a %s -### -ccc-print-phases 2>&1 \
@@ -394,11 +396,13 @@
394396
// CHK-FPGA-AOCO-PHASES-WIN: 14: linker, {11, 13}, ir, (device-sycl)
395397
// CHK-FPGA-AOCO-PHASES-WIN: 15: sycl-post-link, {14}, ir, (device-sycl)
396398
// CHK-FPGA-AOCO-PHASES-WIN: 16: llvm-spirv, {15}, spirv, (device-sycl)
397-
// CHK-FPGA-AOCO-PHASES-WIN: 17: input, "[[INPUTA]]", fpga_aoco
398-
// CHK-FPGA-AOCO-PHASES-WIN: 18: clang-offload-unbundler, {17}, fpga_aoco
399-
// CHK-FPGA-AOCO-PHASES-WIN: 19: backend-compiler, {16, 18}, fpga_aocx, (device-sycl)
400-
// CHK-FPGA-AOCO-PHASES-WIN: 20: clang-offload-wrapper, {19}, object, (device-sycl)
401-
// CHK-FPGA-AOCO-PHASES-WIN: 21: offload, "host-sycl (x86_64-pc-windows-msvc)" {10}, "device-sycl (spir64_fpga-unknown-unknown-sycldevice)" {20}, image
399+
// CHK-FPGA-AOCO-PHASES-WIN: 17: input, "[[INPUTA]]", archive
400+
// CHK-FPGA-AOCO-PHASES-WIN: 18: clang-offload-unbundler, {17}, fpga_dependencies_list
401+
// CHK-FPGA-AOCO-PHASES-WIN: 19: input, "[[INPUTA]]", fpga_aoco
402+
// CHK-FPGA-AOCO-PHASES-WIN: 20: clang-offload-unbundler, {19}, fpga_aoco
403+
// CHK-FPGA-AOCO-PHASES-WIN: 21: backend-compiler, {16, 18, 20}, fpga_aocx, (device-sycl)
404+
// CHK-FPGA-AOCO-PHASES-WIN: 22: clang-offload-wrapper, {21}, object, (device-sycl)
405+
// CHK-FPGA-AOCO-PHASES-WIN: 23: offload, "host-sycl (x86_64-pc-windows-msvc)" {10}, "device-sycl (spir64_fpga-unknown-unknown-sycldevice)" {22}, image
402406

403407
/// aoco test, checking tools
404408
// RUN: %clangxx -target x86_64-unknown-linux-gnu -fsycl -fintelfpga -foffload-static-lib=%t_aoco.a -### %s 2>&1 \

0 commit comments

Comments
 (0)