From 8a2a3cf8082b74cf9c9bf5d5cc72aa38fa304606 Mon Sep 17 00:00:00 2001 From: Alexey Bader Date: Wed, 19 Mar 2025 18:35:28 -0700 Subject: [PATCH 1/5] [clang-linker-wrapper] Dump any device code format Dispate of the option name sycl-dump-device-code it enables dumping of SPIR-V files emitted by the translator tool. This change dumps device code right before embedding it into the fat object. The tool dumps offloading image of any format. --- .../ClangLinkerWrapper.cpp | 48 +++++++++---------- .../clang-linker-wrapper/LinkerWrapperOpts.td | 2 +- 2 files changed, 24 insertions(+), 26 deletions(-) diff --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp index fadc7863968ca..2a85532b83d64 100644 --- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp +++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp @@ -151,7 +151,7 @@ static std::optional SYCLModuleSplitMode; static bool UseSYCLPostLinkTool; -static SmallString<128> SPIRVDumpDir; +static SmallString<128> OffloadImageDumpDir; using OffloadingImage = OffloadBinary::OffloadingImage; @@ -923,29 +923,6 @@ static Expected runLLVMToSPIRVTranslation(StringRef File, if (Error Err = executeCommands(*LLVMToSPIRVPath, CmdArgs)) return std::move(Err); - if (!SPIRVDumpDir.empty()) { - std::error_code EC = - llvm::sys::fs::create_directory(SPIRVDumpDir, /*IgnoreExisting*/ true); - if (EC) - return createStringError( - EC, - formatv("failed to create dump directory. path: {0}, error_code: {1}", - SPIRVDumpDir, EC.value())); - - StringRef Sep = llvm::sys::path::get_separator(); - StringRef Path = *TempFileOrErr; - StringRef Filename = Path.rsplit(Sep).second; - SmallString<128> CopyPath = SPIRVDumpDir; - CopyPath.append(Filename); - EC = llvm::sys::fs::copy_file(Path, CopyPath); - if (EC) - return createStringError( - EC, - formatv( - "failed to copy file. original: {0}, copy: {1}, error_code: {2}", - Path, CopyPath, EC.value())); - } - return *TempFileOrErr; } @@ -1103,6 +1080,27 @@ wrapSYCLBinariesFromFile(std::vector &SplitModules, RegularTarget = "spir64"; for (auto &SI : SplitModules) { + if (!OffloadImageDumpDir.empty()) { + std::error_code EC = llvm::sys::fs::create_directory( + OffloadImageDumpDir, /*IgnoreExisting*/ true); + if (EC) + return createStringError( + EC, + formatv( + "failed to create dump directory. path: {0}, error_code: {1}", + OffloadImageDumpDir, EC.value())); + + StringRef CopyFrom = SI.ModuleFilePath; + SmallString<128> CopyTo = OffloadImageDumpDir; + StringRef Filename = llvm::sys::path::filename(CopyFrom); + CopyTo.append(Filename); + EC = llvm::sys::fs::copy_file(CopyFrom, CopyTo); + if (EC) + return createStringError(EC, formatv("failed to copy file. From: " + "{0} to: {1}, error_code: {2}", + CopyFrom, CopyTo, EC.value())); + } + auto MBOrDesc = MemoryBuffer::getFile(SI.ModuleFilePath); if (!MBOrDesc) return createFileError(SI.ModuleFilePath, MBOrDesc.getError()); @@ -2624,7 +2622,7 @@ int main(int Argc, char **Argv) { else Dir.append(llvm::sys::path::get_separator()); - SPIRVDumpDir = Dir; + OffloadImageDumpDir = Dir; } { diff --git a/clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td b/clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td index 1885fb430b2bd..d7a1aa02e8978 100644 --- a/clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td +++ b/clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td @@ -242,7 +242,7 @@ Flags<[WrapperOnlyOption]>, HelpText<"Embed LLVM IR for runtime kernel fusion"> def sycl_dump_device_code_EQ : Joined<["--", "-"], "sycl-dump-device-code=">, Flags<[WrapperOnlyOption]>, - HelpText<"Path to the folder where the tool dumps SPIR-V device code. Other formats aren't dumped.">; + HelpText<"Directory to dump offloading images to.">; // Options to enable/disable device dynamic linking. def sycl_allow_device_image_dependencies : Flag<["--", "-"], "sycl-allow-device-image-dependencies">, From 88a20ef4f423bdc6b865faa905ac5fb17eb7d1ef Mon Sep 17 00:00:00 2001 From: Alexey Bader Date: Wed, 19 Mar 2025 19:04:07 -0700 Subject: [PATCH 2/5] Create directory once. --- .../ClangLinkerWrapper.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp index 2a85532b83d64..3541eeb96af28 100644 --- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp +++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp @@ -1081,20 +1081,11 @@ wrapSYCLBinariesFromFile(std::vector &SplitModules, for (auto &SI : SplitModules) { if (!OffloadImageDumpDir.empty()) { - std::error_code EC = llvm::sys::fs::create_directory( - OffloadImageDumpDir, /*IgnoreExisting*/ true); - if (EC) - return createStringError( - EC, - formatv( - "failed to create dump directory. path: {0}, error_code: {1}", - OffloadImageDumpDir, EC.value())); - StringRef CopyFrom = SI.ModuleFilePath; SmallString<128> CopyTo = OffloadImageDumpDir; StringRef Filename = llvm::sys::path::filename(CopyFrom); CopyTo.append(Filename); - EC = llvm::sys::fs::copy_file(CopyFrom, CopyTo); + std::error_code EC = llvm::sys::fs::copy_file(CopyFrom, CopyTo); if (EC) return createStringError(EC, formatv("failed to copy file. From: " "{0} to: {1}, error_code: {2}", @@ -2623,6 +2614,14 @@ int main(int Argc, char **Argv) { Dir.append(llvm::sys::path::get_separator()); OffloadImageDumpDir = Dir; + + std::error_code EC = llvm::sys::fs::create_directory( + OffloadImageDumpDir, /*IgnoreExisting*/ true); + if (EC) + reportError(createStringError( + EC, + formatv("failed to create dump directory. path: {0}, error_code: {1}", + OffloadImageDumpDir, EC.value()))); } { From 7806eef0a6c6e24f7de9b9438552a04fe79aa324 Mon Sep 17 00:00:00 2001 From: Alexey Bader Date: Wed, 19 Mar 2025 21:13:04 -0700 Subject: [PATCH 3/5] Remove test. --- clang/test/Driver/linker-wrapper-sycl.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/clang/test/Driver/linker-wrapper-sycl.cpp b/clang/test/Driver/linker-wrapper-sycl.cpp index d32f33149c3b3..6ca069d82d5f5 100644 --- a/clang/test/Driver/linker-wrapper-sycl.cpp +++ b/clang/test/Driver/linker-wrapper-sycl.cpp @@ -47,11 +47,6 @@ // RUN: clang-linker-wrapper -sycl-device-libraries=%t.devicelib.o -sycl-post-link-options="SYCL_POST_LINK_OPTIONS" -llvm-spirv-options="LLVM_SPIRV_OPTIONS" "--host-triple=x86_64-unknown-linux-gnu" "--triple=spir64" "--linker-path=/usr/bin/ld" -shared "--" HOST_LINKER_FLAGS "-dynamic-linker" HOST_DYN_LIB "-o" "a.out" HOST_LIB_PATH HOST_STAT_LIB %t.o --dry-run 2>&1 | FileCheck -check-prefix=CHK-SHARED %s // CHK-SHARED: "{{.*}}clang"{{.*}} -fPIC -// RUN: rm %T/linker_wrapper_dump || true -// RUN: clang-linker-wrapper -sycl-dump-device-code=%T/linker_wrapper_dump -sycl-device-libraries=%t.devicelib.o "--host-triple=x86_64-unknown-linux-gnu" "--triple=spir64" "--linker-path=/usr/bin/ld" -shared "--" HOST_LINKER_FLAGS "-dynamic-linker" HOST_DYN_LIB "-o" "a.out" HOST_LIB_PATH HOST_STAT_LIB %t.o --dry-run -// RUN: ls %T/linker_wrapper_dump | FileCheck -check-prefix=CHK-SYCL-DUMP-DEVICE %s -// CHK-SYCL-DUMP-DEVICE: {{.*}}.spv - /// Check for list of commands for standalone clang-linker-wrapper run for sycl (AOT for Intel GPU) // ------- // Generate .o file as linker wrapper input. From c01853c350a0a2711f9f92539f8436b1a349816a Mon Sep 17 00:00:00 2001 From: Alexey Bader Date: Thu, 20 Mar 2025 07:58:46 -0700 Subject: [PATCH 4/5] Don't create directory for dumping device code in "dry run" mode. --- .../ClangLinkerWrapper.cpp | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp index 3541eeb96af28..2639a76a08da2 100644 --- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp +++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp @@ -1083,9 +1083,9 @@ wrapSYCLBinariesFromFile(std::vector &SplitModules, if (!OffloadImageDumpDir.empty()) { StringRef CopyFrom = SI.ModuleFilePath; SmallString<128> CopyTo = OffloadImageDumpDir; - StringRef Filename = llvm::sys::path::filename(CopyFrom); + StringRef Filename = sys::path::filename(CopyFrom); CopyTo.append(Filename); - std::error_code EC = llvm::sys::fs::copy_file(CopyFrom, CopyTo); + std::error_code EC = sys::fs::copy_file(CopyFrom, CopyTo); if (EC) return createStringError(EC, formatv("failed to copy file. From: " "{0} to: {1}, error_code: {2}", @@ -2609,19 +2609,22 @@ int main(int Argc, char **Argv) { Arg *A = Args.getLastArg(OPT_sycl_dump_device_code_EQ); SmallString<128> Dir(A->getValue()); if (Dir.empty()) - llvm::sys::path::native(Dir = "./"); + sys::path::native(Dir = "./"); else - Dir.append(llvm::sys::path::get_separator()); + Dir.append(sys::path::get_separator()); OffloadImageDumpDir = Dir; - std::error_code EC = llvm::sys::fs::create_directory( - OffloadImageDumpDir, /*IgnoreExisting*/ true); - if (EC) - reportError(createStringError( - EC, - formatv("failed to create dump directory. path: {0}, error_code: {1}", - OffloadImageDumpDir, EC.value()))); + if (!DryRun) { + std::error_code EC = sys::fs::create_directory(OffloadImageDumpDir, + /*IgnoreExisting*/ true); + if (EC) + reportError(createStringError( + EC, + formatv( + "failed to create dump directory. path: {0}, error_code: {1}", + OffloadImageDumpDir, EC.value()))); + } } { From 0753bb88163f3142daf7b6ba4ac833c8d448d1ab Mon Sep 17 00:00:00 2001 From: Alexey Bader Date: Tue, 25 Mar 2025 09:16:57 -0700 Subject: [PATCH 5/5] apply code review feedback. --- .../ClangLinkerWrapper.cpp | 21 ++++--------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp index 2639a76a08da2..adb942a6e6a31 100644 --- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp +++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp @@ -2607,24 +2607,11 @@ int main(int Argc, char **Argv) { if (Args.hasArg(OPT_sycl_dump_device_code_EQ)) { Arg *A = Args.getLastArg(OPT_sycl_dump_device_code_EQ); - SmallString<128> Dir(A->getValue()); - if (Dir.empty()) - sys::path::native(Dir = "./"); + OffloadImageDumpDir = A->getValue(); + if (OffloadImageDumpDir.empty()) + sys::path::native(OffloadImageDumpDir = "./"); else - Dir.append(sys::path::get_separator()); - - OffloadImageDumpDir = Dir; - - if (!DryRun) { - std::error_code EC = sys::fs::create_directory(OffloadImageDumpDir, - /*IgnoreExisting*/ true); - if (EC) - reportError(createStringError( - EC, - formatv( - "failed to create dump directory. path: {0}, error_code: {1}", - OffloadImageDumpDir, EC.value()))); - } + OffloadImageDumpDir.append(sys::path::get_separator()); } {