From 226f35e2373b1db8ed07ba939a9c9bcb844288e6 Mon Sep 17 00:00:00 2001 From: "Larsen, Steffen" Date: Thu, 12 Jun 2025 09:56:28 -0700 Subject: [PATCH 1/3] [SYCL] Emit kernel names for SYCLBIN This commit adds a new property to the property set when producing SYCLBIN files. This new property lists all kernels inside the corresponding binaries. Signed-off-by: Larsen, Steffen --- clang/test/Driver/sycl-post-link-options.cpp | 6 ++ .../ClangLinkerWrapper.cpp | 3 + .../SYCLPostLink/ComputeModuleRuntimeInfo.h | 1 + llvm/include/llvm/Support/PropertySetIO.h | 1 + .../SYCLPostLink/ComputeModuleRuntimeInfo.cpp | 8 ++ llvm/lib/Support/PropertySetIO.cpp | 1 + .../tools/sycl-post-link/emit_kernel_names.ll | 100 ++++++++++++++++++ llvm/tools/sycl-post-link/sycl-post-link.cpp | 17 ++- .../lib/rtc/DeviceCompilation.cpp | 10 +- sycl/doc/design/PropertySets.md | 10 ++ 10 files changed, 149 insertions(+), 8 deletions(-) create mode 100644 llvm/test/tools/sycl-post-link/emit_kernel_names.ll diff --git a/clang/test/Driver/sycl-post-link-options.cpp b/clang/test/Driver/sycl-post-link-options.cpp index 8dfa2c888270d..b0966c7fd636c 100644 --- a/clang/test/Driver/sycl-post-link-options.cpp +++ b/clang/test/Driver/sycl-post-link-options.cpp @@ -21,3 +21,9 @@ // RUN: --sycl-post-link-options="-O2 -device-globals -O0" \ // RUN: --linker-path=/usr/bin/ld %t.o -o a.out 2>&1 | FileCheck --check-prefix OPTIONS_POSTLINK_JIT_NEW %s // OPTIONS_POSTLINK_JIT_NEW: sycl-post-link{{.*}} -spec-const=native -properties -split=auto -emit-only-kernels-as-entry-points -emit-param-info -symbols -emit-exported-symbols -emit-imported-symbols -split-esimd -lower-esimd -O2 -device-globals -O0 +// +// RUN: clang-linker-wrapper --dry-run --host-triple=x86_64-unknown-linux-gnu \ +// RUN: -syclbin=executable -sycl-device-libraries=%t.devicelib.o \ +// RUN: --sycl-post-link-options="-O2 -device-globals -O0" \ +// RUN: --linker-path=/usr/bin/ld %t.o -o a.out 2>&1 | FileCheck --check-prefix OPTIONS_POSTLINK_JIT_NEW_SYCLBIN %s +// OPTIONS_POSTLINK_JIT_NEW_SYCLBIN: sycl-post-link{{.*}} -spec-const=native -properties -split=auto -emit-only-kernels-as-entry-points -emit-param-info -symbols -emit-kernel-names -emit-exported-symbols -emit-imported-symbols -split-esimd -lower-esimd -O2 -device-globals -O0 diff --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp index dcb06a3c674bb..7ff3343b64a0e 100644 --- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp +++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp @@ -694,6 +694,9 @@ getTripleBasedSYCLPostLinkOpts(const ArgList &Args, OPT_no_sycl_device_code_split_esimd, SplitEsimdByDefault); if (!Args.hasArg(OPT_sycl_thin_lto)) PostLinkArgs.push_back("-symbols"); + // Emit kernel names if we are producing SYCLBIN. + if (Args.hasArg(OPT_syclbin_EQ)) + PostLinkArgs.push_back("-emit-kernel-names"); // Specialization constant info generation is mandatory - // add options unconditionally PostLinkArgs.push_back("-emit-exported-symbols"); diff --git a/llvm/include/llvm/SYCLPostLink/ComputeModuleRuntimeInfo.h b/llvm/include/llvm/SYCLPostLink/ComputeModuleRuntimeInfo.h index 8c6b1a130b92f..43070dab50fbe 100644 --- a/llvm/include/llvm/SYCLPostLink/ComputeModuleRuntimeInfo.h +++ b/llvm/include/llvm/SYCLPostLink/ComputeModuleRuntimeInfo.h @@ -24,6 +24,7 @@ namespace sycl { struct GlobalBinImageProps { bool EmitKernelParamInfo; bool EmitProgramMetadata; + bool EmitKernelNames; bool EmitExportedSymbols; bool EmitImportedSymbols; bool EmitDeviceGlobalPropSet; diff --git a/llvm/include/llvm/Support/PropertySetIO.h b/llvm/include/llvm/Support/PropertySetIO.h index 7153a099bc18a..c0b3f7779c159 100644 --- a/llvm/include/llvm/Support/PropertySetIO.h +++ b/llvm/include/llvm/Support/PropertySetIO.h @@ -217,6 +217,7 @@ class PropertySetRegistry { static constexpr char SYCL_PROGRAM_METADATA[] = "SYCL/program metadata"; static constexpr char SYCL_MISC_PROP[] = "SYCL/misc properties"; static constexpr char SYCL_ASSERT_USED[] = "SYCL/assert used"; + static constexpr char SYCL_KERNEL_NAMES[] = "SYCL/kernel names"; static constexpr char SYCL_EXPORTED_SYMBOLS[] = "SYCL/exported symbols"; static constexpr char SYCL_IMPORTED_SYMBOLS[] = "SYCL/imported symbols"; static constexpr char SYCL_DEVICE_GLOBALS[] = "SYCL/device globals"; diff --git a/llvm/lib/SYCLPostLink/ComputeModuleRuntimeInfo.cpp b/llvm/lib/SYCLPostLink/ComputeModuleRuntimeInfo.cpp index 4722330c2ae2e..d19d089550d46 100644 --- a/llvm/lib/SYCLPostLink/ComputeModuleRuntimeInfo.cpp +++ b/llvm/lib/SYCLPostLink/ComputeModuleRuntimeInfo.cpp @@ -271,6 +271,14 @@ PropSetRegTy computeModuleProperties(const Module &M, } } } + if (GlobProps.EmitKernelNames) { + for (const auto *F : EntryPoints) { + if (F->getCallingConv() == CallingConv::SPIR_KERNEL) { + PropSet.add(PropSetRegTy::SYCL_KERNEL_NAMES, F->getName(), + /*PropVal=*/true); + } + } + } if (GlobProps.EmitImportedSymbols) { // record imported functions in the property set diff --git a/llvm/lib/Support/PropertySetIO.cpp b/llvm/lib/Support/PropertySetIO.cpp index 25f6b92de0380..d2030a8825fde 100644 --- a/llvm/lib/Support/PropertySetIO.cpp +++ b/llvm/lib/Support/PropertySetIO.cpp @@ -201,6 +201,7 @@ constexpr char PropertySetRegistry::SYCL_KERNEL_PARAM_OPT_INFO[]; constexpr char PropertySetRegistry::SYCL_PROGRAM_METADATA[]; constexpr char PropertySetRegistry::SYCL_MISC_PROP[]; constexpr char PropertySetRegistry::SYCL_ASSERT_USED[]; +constexpr char PropertySetRegistry::SYCL_KERNEL_NAMES[]; constexpr char PropertySetRegistry::SYCL_EXPORTED_SYMBOLS[]; constexpr char PropertySetRegistry::SYCL_IMPORTED_SYMBOLS[]; constexpr char PropertySetRegistry::SYCL_DEVICE_GLOBALS[]; diff --git a/llvm/test/tools/sycl-post-link/emit_kernel_names.ll b/llvm/test/tools/sycl-post-link/emit_kernel_names.ll new file mode 100644 index 0000000000000..bcf1a289babeb --- /dev/null +++ b/llvm/test/tools/sycl-post-link/emit_kernel_names.ll @@ -0,0 +1,100 @@ +; This test checks that the post-link tool generates list of kernel names. +; +; Global scope +; RUN: sycl-post-link -properties -symbols -emit-kernel-names -S < %s -o %t.global.files.table +; RUN: FileCheck %s -input-file=%t.global.files_0.prop --implicit-check-not="SpirFunc" --check-prefix=CHECK-GLOBAL-PROP +; +; Per-module split +; RUN: sycl-post-link -properties -symbols -split=source -emit-kernel-names -S < %s -o %t.per_module.files.table +; RUN: FileCheck %s -input-file=%t.per_module.files_0.prop -implicit-check-not="SpirFunc" --check-prefix=CHECK-PERMODULE-0-PROP +; RUN: FileCheck %s -input-file=%t.per_module.files_1.prop -implicit-check-not="SpirFunc" --check-prefix=CHECK-PERMODULE-1-PROP +; RUN: FileCheck %s -input-file=%t.per_module.files_2.prop -implicit-check-not="SpirFunc" --check-prefix=CHECK-KERNELLESS-PROP +; +; Per-kernel split +; RUN: sycl-post-link -properties -symbols -split=kernel -emit-kernel-names -S < %s -o %t.per_kernel.files.table +; RUN: FileCheck %s -input-file=%t.per_kernel.files_0.prop --implicit-check-not="SpirFunc" --check-prefix=CHECK-PERKERNEL-0-PROP +; RUN: FileCheck %s -input-file=%t.per_kernel.files_1.prop --implicit-check-not="SpirFunc" --check-prefix=CHECK-PERKERNEL-1-PROP +; RUN: FileCheck %s -input-file=%t.per_kernel.files_2.prop --implicit-check-not="SpirFunc" --check-prefix=CHECK-PERKERNEL-2-PROP +; RUN: FileCheck %s -input-file=%t.per_kernel.files_3.prop --implicit-check-not="SpirFunc" --check-prefix=CHECK-KERNELLESS-PROP +; RUN: FileCheck %s -input-file=%t.per_kernel.files_4.prop --implicit-check-not="SpirFunc" --check-prefix=CHECK-KERNELLESS-PROP +; RUN: FileCheck %s -input-file=%t.per_kernel.files_5.prop --implicit-check-not="SpirFunc" --check-prefix=CHECK-KERNELLESS-PROP + +target triple = "spir64-unknown-unknown" + +define dso_local spir_kernel void @SpirKernel1(float %arg1) #2 { +entry: + ret void +} + +define dso_local spir_kernel void @SpirKernel2(float %arg1) #1 { +entry: + ret void +} + +define dso_local spir_kernel void @SpirKernel3(float %arg1) #2 { +entry: + ret void +} + +define dso_local spir_func void @SpirFunc1(float %arg1) #0 { +entry: + ret void +} + +define dso_local spir_func void @SpirFunc2(i32 %arg1, i32 %arg2) #1 { +entry: + ret void +} + +define dso_local spir_func void @SpirFunc3(float %arg1) #0 { +entry: + ret void +} + +define dso_local spir_func void @SpirFunc4(float %arg1) { +entry: + ret void +} + +attributes #0 = { "sycl-module-id"="a.cpp" } +attributes #1 = { "sycl-module-id"="b.cpp" } +attributes #2 = { "sycl-module-id"="c.cpp" } + +; Global scope +; CHECK-GLOBAL-PROP: [SYCL/kernel names] +; CHECK-GLOBAL-PROP-NEXT: SpirKernel1 +; CHECK-GLOBAL-PROP-NEXT: SpirKernel2 +; CHECK-GLOBAL-PROP-NEXT: SpirKernel3 + +; Per-module split +; CHECK-PERMODULE-0-PROP: [SYCL/kernel names] +; CHECK-PERMODULE-0-PROP-NEXT: SpirKernel1 +; CHECK-PERMODULE-0-PROP-NEXT: SpirKernel3 +; CHECK-PERMODULE-0-PROP-NOT: SpirKernel2 + +; CHECK-PERMODULE-1-PROP: [SYCL/kernel names] +; CHECK-PERMODULE-1-PROP-NEXT: SpirKernel2 +; CHECK-PERMODULE-1-PROP-NOT: SpirKernel1 +; CHECK-PERMODULE-1-PROP-NOT: SpirKernel3 + +; Per-kernel split +; CHECK-PERKERNEL-0-PROP: [SYCL/kernel names] +; CHECK-PERKERNEL-0-PROP-NEXT: SpirKernel3 +; CHECK-PERKERNEL-0-PROP-NOT: SpirKernel1 +; CHECK-PERKERNEL-0-PROP-NOT: SpirKernel2 + +; CHECK-PERKERNEL-1-PROP: [SYCL/kernel names] +; CHECK-PERKERNEL-1-PROP-NEXT: SpirKernel2 +; CHECK-PERKERNEL-1-PROP-NOT: SpirKernel1 +; CHECK-PERKERNEL-1-PROP-NOT: SpirKernel3 + +; CHECK-PERKERNEL-2-PROP: [SYCL/kernel names] +; CHECK-PERKERNEL-2-PROP-NEXT: SpirKernel1 +; CHECK-PERKERNEL-2-PROP-NOT: SpirKernel2 +; CHECK-PERKERNEL-2-PROP-NOT: SpirKernel3 + +; Kernel-less generated modules should have no kernel names +; CHECK-KERNELLESS-PROP-NOT: [SYCL/kernel names] +; CHECK-KERNELLESS-PROP-NOT: SpirKernel1 +; CHECK-KERNELLESS-PROP-NOT: SpirKernel2 +; CHECK-KERNELLESS-PROP-NOT: SpirKernel3 diff --git a/llvm/tools/sycl-post-link/sycl-post-link.cpp b/llvm/tools/sycl-post-link/sycl-post-link.cpp index 5342cd7d51757..b9aa5453284a5 100644 --- a/llvm/tools/sycl-post-link/sycl-post-link.cpp +++ b/llvm/tools/sycl-post-link/sycl-post-link.cpp @@ -219,6 +219,9 @@ cl::opt EmitProgramMetadata{"emit-program-metadata", cl::desc("emit SYCL program metadata"), cl::cat(PostLinkCat)}; +cl::opt EmitKernelNames{ + "emit-kernel-names", cl::desc("emit kernel names"), cl::cat(PostLinkCat)}; + cl::opt EmitExportedSymbols{"emit-exported-symbols", cl::desc("emit exported symbols"), cl::cat(PostLinkCat)}; @@ -402,8 +405,8 @@ void saveModule(std::vector> &OutTables, auto CopyTriple = BaseTriple; if (DoPropGen) { GlobalBinImageProps Props = {EmitKernelParamInfo, EmitProgramMetadata, - EmitExportedSymbols, EmitImportedSymbols, - DeviceGlobals}; + EmitKernelNames, EmitExportedSymbols, + EmitImportedSymbols, DeviceGlobals}; CopyTriple.Prop = saveModuleProperties(MD, Props, I, Suffix, OutputFile.Target); } @@ -811,6 +814,7 @@ int main(int argc, char **argv) { bool DoSpecConst = SpecConstLower.getNumOccurrences() > 0; bool DoParamInfo = EmitKernelParamInfo.getNumOccurrences() > 0; bool DoProgMetadata = EmitProgramMetadata.getNumOccurrences() > 0; + bool DoKernelNames = EmitKernelNames.getNumOccurrences() > 0; bool DoExportedSyms = EmitExportedSymbols.getNumOccurrences() > 0; bool DoImportedSyms = EmitImportedSymbols.getNumOccurrences() > 0; bool DoDeviceGlobals = DeviceGlobals.getNumOccurrences() > 0; @@ -818,8 +822,8 @@ int main(int argc, char **argv) { GenerateDeviceImageWithDefaultSpecConsts.getNumOccurrences() > 0; if (!DoSplit && !DoSpecConst && !DoSymGen && !DoPropGen && !DoParamInfo && - !DoProgMetadata && !DoSplitEsimd && !DoExportedSyms && !DoImportedSyms && - !DoDeviceGlobals && !DoLowerEsimd) { + !DoProgMetadata && !DoSplitEsimd && !DoKernelNames && !DoExportedSyms && + !DoImportedSyms && !DoDeviceGlobals && !DoLowerEsimd) { errs() << "no actions specified; try --help for usage info\n"; return 1; } @@ -853,6 +857,11 @@ int main(int argc, char **argv) { << " -" << IROutputOnly.ArgStr << "\n"; return 1; } + if (IROutputOnly && DoKernelNames) { + errs() << "error: -" << EmitKernelNames.ArgStr << " can't be used with" + << " -" << IROutputOnly.ArgStr << "\n"; + return 1; + } if (IROutputOnly && DoExportedSyms) { errs() << "error: -" << EmitExportedSymbols.ArgStr << " can't be used with" << " -" << IROutputOnly.ArgStr << "\n"; diff --git a/sycl-jit/jit-compiler/lib/rtc/DeviceCompilation.cpp b/sycl-jit/jit-compiler/lib/rtc/DeviceCompilation.cpp index 6a39b79034e7b..4977bb944c397 100644 --- a/sycl-jit/jit-compiler/lib/rtc/DeviceCompilation.cpp +++ b/sycl-jit/jit-compiler/lib/rtc/DeviceCompilation.cpp @@ -734,10 +734,12 @@ jit_compiler::performPostLink(ModuleUPtr Module, [](Function *F) { return F->getName(); }); // TODO: Determine what is requested. - GlobalBinImageProps PropReq{ - /*EmitKernelParamInfo=*/true, /*EmitProgramMetadata=*/true, - /*EmitExportedSymbols=*/true, /*EmitImportedSymbols=*/true, - /*DeviceGlobals=*/true}; + GlobalBinImageProps PropReq{/*EmitKernelParamInfo=*/true, + /*EmitProgramMetadata=*/true, + /*EmitKernelNames=*/true, + /*EmitExportedSymbols=*/true, + /*EmitImportedSymbols=*/true, + /*DeviceGlobals=*/true}; PropertySetRegistry Properties = computeModuleProperties(MDesc.getModule(), MDesc.entries(), PropReq, AllowDeviceImageDependencies); diff --git a/sycl/doc/design/PropertySets.md b/sycl/doc/design/PropertySets.md index 25b95d6c91337..512bca64f9eff 100644 --- a/sycl/doc/design/PropertySets.md +++ b/sycl/doc/design/PropertySets.md @@ -139,6 +139,16 @@ __Value type:__ 32 bit integer. ("1") __Value:__ 1 if the kernel uses assertions and 0 or missing otherwise. +### [SYCL/kernel names] + +__Key:__ Kernel name. + +__Value type:__ 32 bit integer. ("1") + +__Value:__ 1 if the name is identifies a kernel inside the binary and 0 or +missing otherwise. + + ### [SYCL/exported symbols] __Key:__ Symbol name. From 495071aa8ac5011b15af9aabec233c4c6d4afdb0 Mon Sep 17 00:00:00 2001 From: Steffen Larsen Date: Fri, 13 Jun 2025 12:27:04 +0200 Subject: [PATCH 2/3] Update sycl/doc/design/PropertySets.md Co-authored-by: Marcos Maronas --- sycl/doc/design/PropertySets.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sycl/doc/design/PropertySets.md b/sycl/doc/design/PropertySets.md index 512bca64f9eff..6e1cc6f629163 100644 --- a/sycl/doc/design/PropertySets.md +++ b/sycl/doc/design/PropertySets.md @@ -145,7 +145,7 @@ __Key:__ Kernel name. __Value type:__ 32 bit integer. ("1") -__Value:__ 1 if the name is identifies a kernel inside the binary and 0 or +__Value:__ 1 if the name identifies a kernel inside the binary and 0 or missing otherwise. From ffae4dcafcc6a22e9e41181f4e8b0a5135e41d66 Mon Sep 17 00:00:00 2001 From: "Larsen, Steffen" Date: Sun, 15 Jun 2025 21:54:49 -0700 Subject: [PATCH 3/3] Add comment to new clang-linker-wrapper test Signed-off-by: Larsen, Steffen --- clang/test/Driver/sycl-post-link-options.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/clang/test/Driver/sycl-post-link-options.cpp b/clang/test/Driver/sycl-post-link-options.cpp index b0966c7fd636c..52cf4827c3b34 100644 --- a/clang/test/Driver/sycl-post-link-options.cpp +++ b/clang/test/Driver/sycl-post-link-options.cpp @@ -22,6 +22,8 @@ // RUN: --linker-path=/usr/bin/ld %t.o -o a.out 2>&1 | FileCheck --check-prefix OPTIONS_POSTLINK_JIT_NEW %s // OPTIONS_POSTLINK_JIT_NEW: sycl-post-link{{.*}} -spec-const=native -properties -split=auto -emit-only-kernels-as-entry-points -emit-param-info -symbols -emit-exported-symbols -emit-imported-symbols -split-esimd -lower-esimd -O2 -device-globals -O0 // +// Run clang-linker-wrapper test for generating SYCLBIN files. +// // RUN: clang-linker-wrapper --dry-run --host-triple=x86_64-unknown-linux-gnu \ // RUN: -syclbin=executable -sycl-device-libraries=%t.devicelib.o \ // RUN: --sycl-post-link-options="-O2 -device-globals -O0" \