Skip to content

Commit 32bc92d

Browse files
jzcsteffenlarsen
andauthored
[SYCL] Add SYCL registered kernel metadata into property sets (#16821)
For the sycl kernel compiler extension, see #11985, #16485 --------- Co-authored-by: Steffen Larsen <[email protected]>
1 parent 59a1bab commit 32bc92d

File tree

5 files changed

+138
-0
lines changed

5 files changed

+138
-0
lines changed

llvm/include/llvm/Support/PropertySetIO.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ class PropertySetRegistry {
211211
static constexpr char SYCL_HOST_PIPES[] = "SYCL/host pipes";
212212
static constexpr char SYCL_VIRTUAL_FUNCTIONS[] = "SYCL/virtual functions";
213213
static constexpr char SYCL_IMPLICIT_LOCAL_ARG[] = "SYCL/implicit local arg";
214+
static constexpr char SYCL_REGISTERED_KERNELS[] = "SYCL/registered kernels";
214215

215216
static constexpr char PROPERTY_REQD_WORK_GROUP_SIZE[] =
216217
"reqd_work_group_size_uint64_t";

llvm/lib/SYCLLowerIR/ComputeModuleRuntimeInfo.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,21 @@ PropSetRegTy computeModuleProperties(const Module &M,
471471
}
472472
}
473473

474+
if (const NamedMDNode *MD = M.getNamedMetadata("sycl_registered_kernels")) {
475+
if (MD->getNumOperands() == 1) {
476+
const MDNode *RegisteredKernels = MD->getOperand(0);
477+
for (const MDOperand &Op : RegisteredKernels->operands()) {
478+
const auto *RegisteredKernel = cast<MDNode>(Op);
479+
if (RegisteredKernel->getNumOperands() != 2)
480+
continue;
481+
PropSet.add(
482+
PropSetRegTy::SYCL_REGISTERED_KERNELS,
483+
cast<MDString>(RegisteredKernel->getOperand(0))->getString(),
484+
cast<MDString>(RegisteredKernel->getOperand(1))->getString());
485+
}
486+
}
487+
}
488+
474489
return PropSet;
475490
}
476491
std::string computeModuleSymbolTable(const Module &M,

llvm/lib/SYCLLowerIR/ModuleSplitter.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -697,6 +697,31 @@ static bool mustPreserveGV(const GlobalValue &GV) {
697697
return true;
698698
}
699699

700+
void cleanupSYCLRegisteredKernels(Module *M) {
701+
NamedMDNode *MD = M->getNamedMetadata("sycl_registered_kernels");
702+
if (!MD)
703+
return;
704+
705+
if (MD->getNumOperands() == 0)
706+
return;
707+
708+
SmallVector<Metadata *, 8> OperandsToKeep;
709+
MDNode *RegisterdKernels = MD->getOperand(0);
710+
for (const MDOperand &Op : RegisterdKernels->operands()) {
711+
auto RegisteredKernel = cast<MDNode>(Op);
712+
// Ignore metadata nodes with wrong number of operands.
713+
if (RegisteredKernel->getNumOperands() != 2)
714+
continue;
715+
716+
StringRef MangledName =
717+
cast<MDString>(RegisteredKernel->getOperand(1))->getString();
718+
if (M->getFunction(MangledName))
719+
OperandsToKeep.push_back(RegisteredKernel);
720+
}
721+
MD->clearOperands();
722+
MD->addOperand(MDNode::get(M->getContext(), OperandsToKeep));
723+
}
724+
700725
// TODO: try to move all passes (cleanup, spec consts, compile time properties)
701726
// in one place and execute MPM.run() only once.
702727
void ModuleDesc::cleanup() {
@@ -740,6 +765,7 @@ void ModuleDesc::cleanup() {
740765
// process all nodes in the named metadata and remove nodes which are
741766
// referencing kernels which are not included into submodule.
742767
processSubModuleNamedMetadata(M.get());
768+
cleanupSYCLRegisteredKernels(M.get());
743769
}
744770

745771
bool ModuleDesc::isSpecConstantDefault() const {
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
; RUN: sycl-post-link -properties %s -o %t.table
2+
; RUN: FileCheck %s -input-file=%t_0.prop --implicit-check-not="[SYCL/registered kernels]"
3+
!sycl_registered_kernels = !{}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
; This test checks that the sycl-post-link ouputs registered kernel data
2+
; from !sycl_registered_kernels metadata into the SYCL/registerd_kernels section.
3+
4+
; RUN: sycl-post-link %s -properties -split=auto -o %t.table
5+
; RUN: FileCheck %s -input-file=%t_0.prop --check-prefixes=CHECK-WITH-ASPECT,CHECK \
6+
; RUN: --implicit-check-not=kernel_with_aspects
7+
; RUN: FileCheck %s -input-file=%t_1.prop --check-prefixes=CHECK-NO-ASPECT,CHECK
8+
9+
!sycl_registered_kernels = !{!4}
10+
!4 = !{!5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !16, !17, !18, !19}
11+
12+
; Both splits should contain the registered kernel data.
13+
; CHECK: [SYCL/registered kernels]
14+
15+
; For each entry in !sycl_registered_kernels, an entry
16+
; mapping the registered name to the mangled name is added in the
17+
; [SYCL/registered kernels] if it references a kernel that appears
18+
; in the split. (Although in the prop files, the
19+
; mapped values are base64 encoded, so just using simplifed check
20+
; with a regex.)
21+
; CHECK-NO-ASPECT-NEXT: foo=2|{{[A-Za-z0-9+/]+}}
22+
!5 = !{!"foo", !"_Z17__sycl_kernel_foov"}
23+
define spir_kernel void @_Z17__sycl_kernel_foov() {
24+
ret void
25+
}
26+
27+
; CHECK-NO-ASPECT-NEXT: foo3=2|{{[A-Za-z0-9+/]+}}
28+
!6 = !{!"foo3", !"_Z18__sycl_kernel_ff_4v"}
29+
define spir_kernel void @_Z18__sycl_kernel_ff_4v() {
30+
ret void
31+
}
32+
33+
; CHECK-NO-ASPECT-NEXT: iota=2|{{[A-Za-z0-9+/]+}}
34+
!7 = !{!"iota", !"_Z18__sycl_kernel_iotaiPi"}
35+
define spir_kernel void @_Z18__sycl_kernel_iotaiPi() {
36+
ret void
37+
}
38+
39+
; CHECK-NO-ASPECT-NEXT: inst temp=2|{{[A-Za-z0-9+/]+}}
40+
!8 = !{!"inst temp", !"_Z22__sycl_kernel_tempfoo2IiEvT_"}
41+
define spir_kernel void @_Z22__sycl_kernel_tempfoo2IiEvT_() {
42+
ret void
43+
}
44+
45+
; CHECK-NO-ASPECT-NEXT: def spec=2|{{[A-Za-z0-9+/]+}}
46+
!9 = !{!"def spec", !"_Z22__sycl_kernel_tempfoo2IsEvT_"}
47+
define spir_kernel void @_Z22__sycl_kernel_tempfoo2IsEvT_() {
48+
ret void
49+
}
50+
51+
; CHECK-NO-ASPECT-NEXT: decl temp=2|{{[A-Za-z0-9+/]+}}
52+
!10 = !{!"decl temp", !"_Z21__sycl_kernel_tempfooIiEvT_"}
53+
define spir_kernel void @_Z21__sycl_kernel_tempfooIiEvT_() {
54+
ret void
55+
}
56+
57+
; CHECK-NO-ASPECT-NEXT: decl spec=2|{{[A-Za-z0-9+/]+}}
58+
!11 = !{!"decl spec", !"_Z22__sycl_kernel_tempfoo2IfEvT_"}
59+
define spir_kernel void @_Z22__sycl_kernel_tempfoo2IfEvT_() {
60+
ret void
61+
}
62+
63+
; CHECK-NO-ASPECT-NEXT: nontype=2|{{[A-Za-z0-9+/]+}}
64+
!12 = !{!"nontype", !"_Z22__sycl_kernel_tempfoo3ILi5EEvv"}
65+
define spir_kernel void @_Z22__sycl_kernel_tempfoo3ILi5EEvv() {
66+
ret void
67+
}
68+
69+
; CHECK-NO-ASPECT-NEXT: non-temp=2|{{[A-Za-z0-9+/]+}}
70+
!13 = !{!"decl non-temp", !"_Z17__sycl_kernel_barv"}
71+
define spir_kernel void @_Z17__sycl_kernel_barv() {
72+
ret void
73+
}
74+
75+
!14 = !{!"kernel_with_aspects", !"kernel_with_aspects"}
76+
!15 = !{i32 1}
77+
; CHECK-WITH-ASPECT-NEXT: kernel_with_aspects=2|{{[A-Za-z0-9+/]+}}
78+
define spir_kernel void @kernel_with_aspects() !sycl_used_aspects !15 {
79+
ret void
80+
}
81+
82+
; Data with incorrect format should be ignored.
83+
; CHECK-NOT: incorrect_data_format
84+
!16 = !{!"incorrect_data_format"}
85+
86+
!17 = !{!"bar", !"_Z3barv"}
87+
!18 = !{!"bar", !"_Z3barv"}
88+
!19 = !{!"(void(*)())bar", !"_Z3barv"}
89+
; CHECK-NO-ASPECT-NEXT: bar=2|[[BAR:[A-Za-z0-9+/]+]]
90+
; CHECK-NO-ASPECT-NEXT: (void(*)())bar=2|[[BAR]]
91+
define spir_kernel void @_Z3barv() {
92+
ret void
93+
}

0 commit comments

Comments
 (0)