Skip to content
1 change: 1 addition & 0 deletions llvm/include/llvm/Support/PropertySetIO.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ class PropertySetRegistry {
static constexpr char SYCL_HOST_PIPES[] = "SYCL/host pipes";
static constexpr char SYCL_VIRTUAL_FUNCTIONS[] = "SYCL/virtual functions";
static constexpr char SYCL_IMPLICIT_LOCAL_ARG[] = "SYCL/implicit local arg";
static constexpr char SYCL_REGISTERED_KERNELS[] = "SYCL/registered kernels";

static constexpr char PROPERTY_REQD_WORK_GROUP_SIZE[] =
"reqd_work_group_size_uint64_t";
Expand Down
15 changes: 15 additions & 0 deletions llvm/lib/SYCLLowerIR/ComputeModuleRuntimeInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,21 @@ PropSetRegTy computeModuleProperties(const Module &M,
}
}

if (const NamedMDNode *MD = M.getNamedMetadata("sycl_registered_kernels")) {
if (MD->getNumOperands() == 1) {
const MDNode *RegisteredKernels = MD->getOperand(0);
for (const MDOperand &Op : RegisteredKernels->operands()) {
const auto *RegisteredKernel = cast<MDNode>(Op);
if (RegisteredKernel->getNumOperands() != 2)
continue;
PropSet.add(
PropSetRegTy::SYCL_REGISTERED_KERNELS,
cast<MDString>(RegisteredKernel->getOperand(0))->getString(),
cast<MDString>(RegisteredKernel->getOperand(1))->getString());
}
}
}

return PropSet;
}
std::string computeModuleSymbolTable(const Module &M,
Expand Down
26 changes: 26 additions & 0 deletions llvm/lib/SYCLLowerIR/ModuleSplitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -697,6 +697,31 @@ static bool mustPreserveGV(const GlobalValue &GV) {
return true;
}

void cleanupSYCLRegisteredKernels(Module *M) {
NamedMDNode *MD = M->getNamedMetadata("sycl_registered_kernels");
if (!MD)
return;

if (MD->getNumOperands() == 0)
return;

SmallVector<Metadata *, 8> OperandsToKeep;
MDNode *RegisterdKernels = MD->getOperand(0);
for (const MDOperand &Op : RegisterdKernels->operands()) {
auto RegisteredKernel = cast<MDNode>(Op);
// Ignore metadata nodes with wrong number of operands.
if (RegisteredKernel->getNumOperands() != 2)
continue;

StringRef MangledName =
cast<MDString>(RegisteredKernel->getOperand(1))->getString();
if (M->getFunction(MangledName))
OperandsToKeep.push_back(RegisteredKernel);
}
MD->clearOperands();
MD->addOperand(MDNode::get(M->getContext(), OperandsToKeep));
}

// TODO: try to move all passes (cleanup, spec consts, compile time properties)
// in one place and execute MPM.run() only once.
void ModuleDesc::cleanup() {
Expand Down Expand Up @@ -740,6 +765,7 @@ void ModuleDesc::cleanup() {
// process all nodes in the named metadata and remove nodes which are
// referencing kernels which are not included into submodule.
processSubModuleNamedMetadata(M.get());
cleanupSYCLRegisteredKernels(M.get());
}

bool ModuleDesc::isSpecConstantDefault() const {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
; RUN: sycl-post-link -properties %s -o %t.table
; RUN: FileCheck %s -input-file=%t_0.prop --implicit-check-not="[SYCL/registered kernels]"
!sycl_registered_kernels = !{}
93 changes: 93 additions & 0 deletions llvm/test/tools/sycl-post-link/sycl-registered-kernels.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
; This test checks that the sycl-post-link ouputs registered kernel data
; from !sycl_registered_kernels metadata into the SYCL/registerd_kernels section.

; RUN: sycl-post-link %s -properties -split=auto -o %t.table
; RUN: FileCheck %s -input-file=%t_0.prop --check-prefixes=CHECK-WITH-ASPECT,CHECK \
; RUN: --implicit-check-not=kernel_with_aspects
; RUN: FileCheck %s -input-file=%t_1.prop --check-prefixes=CHECK-NO-ASPECT,CHECK

!sycl_registered_kernels = !{!4}
!4 = !{!5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !16, !17, !18, !19}

; Both splits should contain the registered kernel data.
; CHECK: [SYCL/registered kernels]

; For each entry in !sycl_registered_kernels, an entry
; mapping the registered name to the mangled name is added in the
; [SYCL/registered kernels] if it references a kernel that appears
; in the split. (Although in the prop files, the
; mapped values are base64 encoded, so just using simplifed check
; with a regex.)
; CHECK-NO-ASPECT-NEXT: foo=2|{{[A-Za-z0-9+/]+}}
!5 = !{!"foo", !"_Z17__sycl_kernel_foov"}
define spir_kernel void @_Z17__sycl_kernel_foov() {
ret void
}

; CHECK-NO-ASPECT-NEXT: foo3=2|{{[A-Za-z0-9+/]+}}
!6 = !{!"foo3", !"_Z18__sycl_kernel_ff_4v"}
define spir_kernel void @_Z18__sycl_kernel_ff_4v() {
ret void
}

; CHECK-NO-ASPECT-NEXT: iota=2|{{[A-Za-z0-9+/]+}}
!7 = !{!"iota", !"_Z18__sycl_kernel_iotaiPi"}
define spir_kernel void @_Z18__sycl_kernel_iotaiPi() {
ret void
}

; CHECK-NO-ASPECT-NEXT: inst temp=2|{{[A-Za-z0-9+/]+}}
!8 = !{!"inst temp", !"_Z22__sycl_kernel_tempfoo2IiEvT_"}
define spir_kernel void @_Z22__sycl_kernel_tempfoo2IiEvT_() {
ret void
}

; CHECK-NO-ASPECT-NEXT: def spec=2|{{[A-Za-z0-9+/]+}}
!9 = !{!"def spec", !"_Z22__sycl_kernel_tempfoo2IsEvT_"}
define spir_kernel void @_Z22__sycl_kernel_tempfoo2IsEvT_() {
ret void
}

; CHECK-NO-ASPECT-NEXT: decl temp=2|{{[A-Za-z0-9+/]+}}
!10 = !{!"decl temp", !"_Z21__sycl_kernel_tempfooIiEvT_"}
define spir_kernel void @_Z21__sycl_kernel_tempfooIiEvT_() {
ret void
}

; CHECK-NO-ASPECT-NEXT: decl spec=2|{{[A-Za-z0-9+/]+}}
!11 = !{!"decl spec", !"_Z22__sycl_kernel_tempfoo2IfEvT_"}
define spir_kernel void @_Z22__sycl_kernel_tempfoo2IfEvT_() {
ret void
}

; CHECK-NO-ASPECT-NEXT: nontype=2|{{[A-Za-z0-9+/]+}}
!12 = !{!"nontype", !"_Z22__sycl_kernel_tempfoo3ILi5EEvv"}
define spir_kernel void @_Z22__sycl_kernel_tempfoo3ILi5EEvv() {
ret void
}

; CHECK-NO-ASPECT-NEXT: non-temp=2|{{[A-Za-z0-9+/]+}}
!13 = !{!"decl non-temp", !"_Z17__sycl_kernel_barv"}
define spir_kernel void @_Z17__sycl_kernel_barv() {
ret void
}

!14 = !{!"kernel_with_aspects", !"kernel_with_aspects"}
!15 = !{i32 1}
; CHECK-WITH-ASPECT-NEXT: kernel_with_aspects=2|{{[A-Za-z0-9+/]+}}
define spir_kernel void @kernel_with_aspects() !sycl_used_aspects !15 {
ret void
}

; Data with incorrect format should be ignored.
; CHECK-NOT: incorrect_data_format
!16 = !{!"incorrect_data_format"}

!17 = !{!"bar", !"_Z3barv"}
!18 = !{!"bar", !"_Z3barv"}
!19 = !{!"(void(*)())bar", !"_Z3barv"}
; CHECK-NO-ASPECT-NEXT: bar=2|[[BAR:[A-Za-z0-9+/]+]]
; CHECK-NO-ASPECT-NEXT: (void(*)())bar=2|[[BAR]]
define spir_kernel void @_Z3barv() {
ret void
}
Loading