Skip to content

Commit 96ce6ea

Browse files
[Driver] Dump device code during SYCL offloading. (#11132)
This PR enables users to dump the device code generated during the SYCL compilation into a user provided directory. The new option added is : -fsycl-dump-device-code=/path/to/directory/ **Example usage:** If somebody runs : `clang++ -fsycl -fsycl-dump-device-code=/path/to/directory test.cpp` the `*.spv` files generated during device compilation show up in `/path/to/directory/`
1 parent 3c7762a commit 96ce6ea

File tree

6 files changed

+83
-3
lines changed

6 files changed

+83
-3
lines changed

clang/include/clang/Driver/Driver.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ class Driver {
7979

8080
IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS;
8181

82+
bool DumpDeviceCode;
83+
8284
enum DriverMode {
8385
GCCMode,
8486
GXXMode,
@@ -420,6 +422,7 @@ class Driver {
420422
return Dir.c_str();
421423
}
422424
void setInstalledDir(StringRef Value) { InstalledDir = std::string(Value); }
425+
bool isDumpDeviceCodeEnabled() const { return DumpDeviceCode; }
423426

424427
bool isSaveTempsEnabled() const { return SaveTemps != SaveTempsNone; }
425428
bool isSaveTempsObj() const { return SaveTemps == SaveTempsObj; }

clang/include/clang/Driver/Options.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5532,6 +5532,9 @@ def regcall4 : Flag<["-"], "regcall4">, Group<m_Group>,
55325532
Visibility<[ClangOption, CC1Option]>,
55335533
HelpText<"Set __regcall4 as a default calling convention to respect __regcall ABI v.4">,
55345534
MarshallingInfoFlag<LangOpts<"RegCall4">>;
5535+
def fsycl_dump_device_code_EQ : Joined<["-"], "fsycl-dump-device-code=">, Flags<[NoXarchOption]>,
5536+
Visibility<[ClangOption, CLOption]>,
5537+
HelpText<"Dump device code into the user provided directory.">;
55355538
def save_temps_EQ : Joined<["-", "--"], "save-temps=">, Flags<[NoXarchOption]>,
55365539
Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
55375540
HelpText<"Save intermediate compilation results.">;

clang/lib/Driver/Compilation.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "llvm/Option/OptSpecifier.h"
2222
#include "llvm/Option/Option.h"
2323
#include "llvm/Support/FileSystem.h"
24+
#include "llvm/Support/Path.h"
2425
#include "llvm/Support/SimpleTable.h"
2526
#include "llvm/Support/raw_ostream.h"
2627
#include "llvm/TargetParser/Triple.h"
@@ -126,6 +127,20 @@ bool Compilation::CleanupFile(const char *File, bool IssueErrors) const {
126127
// Don't try to remove files which we don't have write access to (but may be
127128
// able to remove), or non-regular files. Underlying tools may have
128129
// intentionally not overwritten them.
130+
131+
// Save the device code files(spv files) only if -fsycl-dump-device-code
132+
// option is enabled.
133+
if (TheDriver.isDumpDeviceCodeEnabled()) {
134+
Arg *DumpDeviceCodeArg =
135+
getArgs().getLastArg(options::OPT_fsycl_dump_device_code_EQ);
136+
std::string ExpectedDir =
137+
DumpDeviceCodeArg ? DumpDeviceCodeArg->getValue() : "";
138+
std::string ActualFile(File);
139+
if (ActualFile.find(ExpectedDir) != std::string::npos &&
140+
llvm::sys::path::extension(ActualFile).equals(".spv"))
141+
return false;
142+
}
143+
129144
if (!llvm::sys::fs::can_write(File) || !llvm::sys::fs::is_regular_file(File))
130145
return true;
131146

@@ -145,7 +160,7 @@ bool Compilation::CleanupFile(const char *File, bool IssueErrors) const {
145160
bool Compilation::CleanupFileList(const TempFileList &Files,
146161
bool IssueErrors) const {
147162
bool Success = true;
148-
for (const auto &File: Files) {
163+
for (const auto &File : Files) {
149164
// Temporary file lists contain files that need to be cleaned. The
150165
// file containing the information is also removed
151166
if (File.second == types::TY_Tempfilelist ||
@@ -161,6 +176,7 @@ bool Compilation::CleanupFileList(const TempFileList &Files,
161176
Success = false;
162177
continue;
163178
}
179+
164180
std::vector<std::string> TmpFileNames;
165181
T->get()->linearize(TmpFileNames);
166182

@@ -172,7 +188,7 @@ bool Compilation::CleanupFileList(const TempFileList &Files,
172188
} else {
173189
std::ifstream ListFile(File.first);
174190
std::string TmpFileName;
175-
while (std::getline(ListFile, TmpFileName) && !TmpFileName.empty())
191+
while (std::getline(ListFile, TmpFileName))
176192
Success &= CleanupFile(TmpFileName.c_str(), IssueErrors);
177193
}
178194
}

clang/lib/Driver/Driver.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ Driver::Driver(StringRef ClangExecutable, StringRef TargetTriple,
199199
DiagnosticsEngine &Diags, std::string Title,
200200
IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS)
201201
: Diags(Diags), VFS(std::move(VFS)), Mode(GCCMode),
202-
SaveTemps(SaveTempsNone), BitcodeEmbed(EmbedNone),
202+
SaveTemps(SaveTempsNone), DumpDeviceCode(false), BitcodeEmbed(EmbedNone),
203203
Offload(OffloadHostDevice), CXX20HeaderType(HeaderMode_None),
204204
ModulesModeCXX20(false), LTOMode(LTOK_None), OffloadLTOMode(LTOK_None),
205205
ClangExecutable(ClangExecutable), SysRoot(DEFAULT_SYSROOT),
@@ -1705,6 +1705,9 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) {
17051705
.Default(SaveTempsCwd);
17061706
}
17071707

1708+
if (Args.getLastArg(options::OPT_fsycl_dump_device_code_EQ))
1709+
DumpDeviceCode = true;
1710+
17081711
if (const Arg *A = Args.getLastArg(options::OPT_offload_host_only,
17091712
options::OPT_offload_device_only,
17101713
options::OPT_offload_host_device)) {

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10184,6 +10184,26 @@ void SPIRVTranslator::ConstructJob(Compilation &C, const JobAction &JA,
1018410184
TCArgs.MakeArgString("--out-file-list=" + OutputFileName));
1018510185
ForeachArgs.push_back(
1018610186
TCArgs.MakeArgString("--out-replace=" + OutputFileName));
10187+
// If fsycl-dump-device-code is passed, put the output files from llvm-spirv
10188+
// into the path provided in fsycl-dump-device-code.
10189+
if (C.getDriver().isDumpDeviceCodeEnabled()) {
10190+
SmallString<128> OutputDir;
10191+
10192+
Arg *DumpDeviceCodeArg =
10193+
C.getArgs().getLastArg(options::OPT_fsycl_dump_device_code_EQ);
10194+
10195+
OutputDir = (DumpDeviceCodeArg ? DumpDeviceCodeArg->getValue() : "");
10196+
10197+
// If the output directory path is empty, put the llvm-spirv output in the
10198+
// current directory.
10199+
if (OutputDir.empty())
10200+
llvm::sys::path::native(OutputDir = "./");
10201+
else
10202+
OutputDir.append(llvm::sys::path::get_separator());
10203+
ForeachArgs.push_back(
10204+
C.getArgs().MakeArgString("--out-dir=" + OutputDir));
10205+
}
10206+
1018710207
StringRef ParallelJobs =
1018810208
TCArgs.getLastArgValue(options::OPT_fsycl_max_parallel_jobs_EQ);
1018910209
if (!ParallelJobs.empty())
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// SYCL offloading tests using -fsycl-dump-device-code
2+
3+
// Verify that -fsycl-dump-device-code puts the device code (.spv files)
4+
// in the user provided directory.
5+
6+
// Linux
7+
// clang -fsycl -target x86_64-unknown-linux-gnu
8+
// RUN: %clang -fsycl -fno-sycl-instrument-device-code -fno-sycl-device-lib=all -target x86_64-unknown-linux-gnu -fsycl-dump-device-code=/user/input/path %s -### 2>&1 \
9+
// RUN: | FileCheck %s --check-prefixes=CHK-FSYCL-DUMP-DEVICE-CODE
10+
11+
// clang -fsycl -fsycl-targets=spir64-unknown-unknown
12+
// RUN: %clang -fsycl -fsycl-targets=spir64-unknown-unknown -target x86_64-unknown-linux-gnu -fsycl-dump-device-code=/user/input/path %s -### 2>&1 \
13+
// RUN: | FileCheck %s --check-prefixes=CHK-FSYCL-DUMP-DEVICE-CODE
14+
15+
// clang --driver-mode=g++
16+
// RUN: %clangxx -fsycl -fsycl-targets=spir64-unknown-unknown -target x86_64-unknown-linux-gnu -fsycl-dump-device-code=/user/input/path %s -### 2>&1 \
17+
// RUN: | FileCheck %s --check-prefixes=CHK-FSYCL-DUMP-DEVICE-CODE
18+
19+
// Windows
20+
// RUN: %clang_cl -fsycl -fsycl-dump-device-code=/user/input/path %s -### 2>&1 \
21+
// RUN: | FileCheck %s --check-prefixes=CHK-FSYCL-DUMP-DEVICE-CODE-WIN
22+
23+
// CHK-FSYCL-DUMP-DEVICE-CODE: llvm-foreach{{.*}} "--out-dir=/user/input/path{{(/|\\\\)}}" "--" "{{.*}}llvm-spirv"
24+
// CHK-FSYCL-DUMP-DEVICE-CODE-WIN: llvm-foreach{{.*}} "--out-dir=/user/input/path{{(/|\\\\)}}" "--" "{{.*}}llvm-spirv"
25+
26+
// Linux
27+
// RUN: %clang -fsycl -fsycl-targets=spir64-unknown-unknown -target x86_64-unknown-linux-gnu -fsycl-dump-device-code= %s -### 2>&1 \
28+
// RUN: | FileCheck %s --check-prefixes=CHK-FSYCL-DUMP-DEVICE-CODE-CWD
29+
30+
// Windows
31+
// RUN: %clang_cl -fsycl -fsycl-dump-device-code= %s -### 2>&1 \
32+
// RUN: | FileCheck %s --check-prefixes=CHK-FSYCL-DUMP-DEVICE-CODE-WIN-CWD
33+
34+
// CHK-FSYCL-DUMP-DEVICE-CODE-CWD: llvm-foreach{{.*}} "--out-dir=.{{(/|\\\\)}}" "--" "{{.*}}llvm-spirv"
35+
// CHK-FSYCL-DUMP-DEVICE-CODE-WIN-CWD: llvm-foreach{{.*}} "--out-dir=.{{(/|\\\\)}}" "--" "{{.*}}llvm-spirv"

0 commit comments

Comments
 (0)