Skip to content

Commit 0b9e33e

Browse files
committed
[Driver][SYCL][FPGA] Enable dependency file usage from static archives for FPGA
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 82893b2 commit 0b9e33e

File tree

8 files changed

+133
-26
lines changed

8 files changed

+133
-26
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
@@ -3612,6 +3612,9 @@ class OffloadingActionBuilder final {
36123612
/// List of objects to extract FPGA dependency info from
36133613
ActionList FPGAObjectInputs;
36143614

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

@@ -4060,15 +4063,19 @@ class OffloadingActionBuilder final {
40604063
// triple calls for it (provided a valid subarch).
40614064
ActionList BEInputs;
40624065
BEInputs.push_back(BuildCodeAction);
4063-
for (Action *A : FPGAObjectInputs) {
4064-
// Send any known objects through the unbundler to grab the
4065-
// dependency file associated.
4066+
auto unbundleAdd = [&](Action *A, types::ID T) {
40664067
ActionList AL;
40674068
AL.push_back(A);
4068-
Action *UnbundleAction = C.MakeAction<OffloadUnbundlingJobAction>(
4069-
AL, types::TY_FPGA_Dependencies);
4069+
Action *UnbundleAction =
4070+
C.MakeAction<OffloadUnbundlingJobAction>(AL, T);
40704071
BEInputs.push_back(UnbundleAction);
4071-
}
4072+
};
4073+
// Send any known objects/archives through the unbundler to grab the
4074+
// dependency file associated.
4075+
for (Action *A : FPGAObjectInputs)
4076+
unbundleAdd(A, types::TY_FPGA_Dependencies);
4077+
for (Action *A : FPGAArchiveInputs)
4078+
unbundleAdd(A, types::TY_FPGA_Dependencies_List);
40724079
for (const auto &A : DeviceLibObjects)
40734080
BEInputs.push_back(A);
40744081
BuildCodeAction =
@@ -4193,6 +4200,7 @@ class OffloadingActionBuilder final {
41934200
Arg *SYCLAddTargets = Args.getLastArg(options::OPT_fsycl_add_targets_EQ);
41944201
bool HasValidSYCLRuntime = C.getInputArgs().hasFlag(options::OPT_fsycl,
41954202
options::OPT_fno_sycl, false);
4203+
bool SYCLfpgaTriple = false;
41964204
if (SYCLTargets || SYCLAddTargets) {
41974205
if (SYCLTargets) {
41984206
llvm::StringMap<StringRef> FoundNormalizedTriples;
@@ -4210,6 +4218,8 @@ class OffloadingActionBuilder final {
42104218
FoundNormalizedTriples[NormalizedName] = Val;
42114219

42124220
SYCLTripleList.push_back(TT);
4221+
if (TT.getSubArch() == llvm::Triple::SPIRSubArch_fpga)
4222+
SYCLfpgaTriple = true;
42134223
}
42144224
}
42154225
if (SYCLAddTargets) {
@@ -4233,13 +4243,30 @@ class OffloadingActionBuilder final {
42334243
const char *SYCLTargetArch = SYCLfpga ? "spir64_fpga" : "spir64";
42344244
SYCLTripleList.push_back(
42354245
C.getDriver().MakeSYCLDeviceTriple(SYCLTargetArch));
4246+
if (SYCLfpga)
4247+
SYCLfpgaTriple = true;
42364248
}
42374249

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

4255+
// Populate FPGA static archives that could contain dep files to be
4256+
// incorporated into the aoc compilation
4257+
if (SYCLfpgaTriple) {
4258+
SmallVector<const char *, 16> LinkArgs(getLinkerArgs(C, Args));
4259+
for (const StringRef &LA : LinkArgs) {
4260+
if (isStaticArchiveFile(LA) && hasOffloadSections(C, LA, Args)) {
4261+
const llvm::opt::OptTable &Opts = C.getDriver().getOpts();
4262+
Arg *InputArg = MakeInputArg(Args, Opts, Args.MakeArgString(LA));
4263+
Action *Current =
4264+
C.MakeAction<InputAction>(*InputArg, types::TY_Archive);
4265+
FPGAArchiveInputs.push_back(Current);
4266+
}
4267+
}
4268+
}
4269+
42434270
DeviceLinkerInputs.resize(ToolChains.size());
42444271
return initializeGpuArchMap();
42454272
}
@@ -5975,12 +6002,14 @@ InputInfo Driver::BuildJobsForActionNoCache(
59756002
// Do a check for a dependency file unbundle for FPGA. This is out of line
59766003
// from a regular unbundle, so just create and return the name of the
59776004
// unbundled file.
5978-
if (JA->getType() == types::TY_FPGA_Dependencies) {
6005+
if (JA->getType() == types::TY_FPGA_Dependencies ||
6006+
JA->getType() == types::TY_FPGA_Dependencies_List) {
6007+
std::string Ext(types::getTypeTempSuffix(JA->getType()));
59796008
std::string TmpFileName =
5980-
C.getDriver().GetTemporaryPath(llvm::sys::path::stem(BaseInput), "d");
6009+
C.getDriver().GetTemporaryPath(llvm::sys::path::stem(BaseInput), Ext);
59816010
const char *TmpFile =
59826011
C.addTempFile(C.getArgs().MakeArgString(TmpFileName));
5983-
Result = InputInfo(types::TY_FPGA_Dependencies, TmpFile, TmpFile);
6012+
Result = InputInfo(JA->getType(), TmpFile, TmpFile);
59846013
UnbundlingResults.push_back(Result);
59856014
} else {
59866015
// 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
@@ -7378,7 +7378,8 @@ void OffloadBundler::ConstructJobMultipleOutputs(
73787378
bool IsMSVCEnv =
73797379
C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment();
73807380
types::ID InputType(Input.getType());
7381-
bool IsFPGADepUnbundle = (JA.getType() == types::TY_FPGA_Dependencies);
7381+
bool IsFPGADepUnbundle = JA.getType() == types::TY_FPGA_Dependencies;
7382+
bool IsFPGADepLibUnbundle = JA.getType() == types::TY_FPGA_Dependencies_List;
73827383
bool IsArchiveUnbundle =
73837384
(!IsMSVCEnv && C.getDriver().getOffloadStaticLibSeen() &&
73847385
(types::isArchive(InputType) || InputType == types::TY_Object));
@@ -7394,7 +7395,7 @@ void OffloadBundler::ConstructJobMultipleOutputs(
73947395
else
73957396
TypeArg = "aoo";
73967397
}
7397-
if (InputType == types::TY_FPGA_AOCO ||
7398+
if (InputType == types::TY_FPGA_AOCO || IsFPGADepLibUnbundle ||
73987399
(IsMSVCEnv && types::isArchive(InputType)))
73997400
TypeArg = "aoo";
74007401
if (IsFPGADepUnbundle)
@@ -7453,7 +7454,7 @@ void OffloadBundler::ConstructJobMultipleOutputs(
74537454
Triples += Dep.DependentBoundArch;
74547455
}
74557456
}
7456-
if (IsFPGADepUnbundle) {
7457+
if (IsFPGADepUnbundle || IsFPGADepLibUnbundle) {
74577458
// TODO - We are currently using the target triple inputs to slot a location
74587459
// of the dependency information into the bundle. It would be good to
74597460
// separate this out to an explicit option in the bundler for the dependency
@@ -7474,7 +7475,7 @@ void OffloadBundler::ConstructJobMultipleOutputs(
74747475
// When dealing with -fintelfpga, there is an additional unbundle step
74757476
// that occurs for the dependency file. In that case, do not use the
74767477
// dependent information, but just the output file.
7477-
if (IsFPGADepUnbundle)
7478+
if (IsFPGADepUnbundle || IsFPGADepLibUnbundle)
74787479
UB += Outputs[0].getFilename();
74797480
else {
74807481
for (unsigned I = 0; I < Outputs.size(); ++I) {

clang/lib/Driver/ToolChains/SYCL.cpp

+7-2
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,8 @@ void SYCL::fpga::BackendCompiler::ConstructJob(Compilation &C,
225225
// Add any FPGA library lists. These come in as special tempfile lists.
226226
CmdArgs.push_back(Args.MakeArgString(Twine("-library-list=") +
227227
Filename));
228-
else if (II.getType() == types::TY_FPGA_Dependencies)
228+
else if (II.getType() == types::TY_FPGA_Dependencies ||
229+
II.getType() == types::TY_FPGA_Dependencies_List)
229230
FPGADepFiles.push_back(II);
230231
else
231232
CmdArgs.push_back(C.getArgs().MakeArgString(Filename));
@@ -277,9 +278,13 @@ void SYCL::fpga::BackendCompiler::ConstructJob(Compilation &C,
277278
if (!FPGADepFiles.empty()) {
278279
SmallString<128> DepOpt("-dep-files=");
279280
for (unsigned I = 0; I < FPGADepFiles.size(); ++I) {
281+
SmallString<64> FileName;
282+
if (FPGADepFiles[I].getType() == types::TY_FPGA_Dependencies_List)
283+
FileName += "@";
284+
FileName += FPGADepFiles[I].getFilename();
280285
if (I)
281286
DepOpt += ',';
282-
DepOpt += FPGADepFiles[I].getFilename();
287+
DepOpt += FileName;
283288
}
284289
CmdArgs.push_back(C.getArgs().MakeArgString(DepOpt));
285290
}
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)