Skip to content

Commit 46285e4

Browse files
authored
Don't wrap kernels that are not being called in the module (#2119)
* Don't wrap kernels that are not being called in the module This patch is a result of a reflection about previously merged PR #1149 "add an entry point wrapper around functions (llvm pass)" and is enspired by various reported translator, clang (OpenCL) and Intel GPU drivers issues (see #2029 for reference). While SPIR-V spec states: === *OpName* --//--. This has nosemantic impact and can safely be removed from a module. === yet having EntryPoint function and a function that shares the name via OpName might be confusing by both (old) drivers and programmers, who read the SPIR-V file. This patch prevents generation of the wrapper function when it's not necessary to generate it aka if a kernel function is not called by other kernel. We can do better in other cases as well, for example I have experiments of renaming a wrapped function adding a previx, so it could be distinguished from the actual kernel/entry point, but for now it doesn't pass validation for E2E OpenCL tests. Signed-off-by: Sidorov, Dmitry <[email protected]> * prevent a copy Signed-off-by: Sidorov, Dmitry <[email protected]> This patch is a result of a reflection about previously merged PR #1149 "add an entry point wrapper around functions (llvm pass)" and is enspired by various reported translator, clang (OpenCL) and Intel GPU drivers issues (see #2029 for reference). While SPIR-V spec states: OpName --//--. This has nosemantic impact and can safely be removed from a module. yet having EntryPoint function and a function that shares the name via OpName might be confusing by both not-up-to-date drivers and programmers, who read the SPIR-V file. This patch prevents generation of the wrapper function when it's not necessary to generate it aka if a kernel function is not called by other kernel. Signed-off-by: Sidorov, Dmitry <[email protected]>
1 parent 4f7efd3 commit 46285e4

26 files changed

+126
-94
lines changed

lib/SPIRV/SPIRVRegularizeLLVM.cpp

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -363,9 +363,10 @@ bool SPIRVRegularizeLLVMBase::runRegularizeLLVM(Module &Module) {
363363
/// Remove entities not representable by SPIR-V
364364
bool SPIRVRegularizeLLVMBase::regularize() {
365365
eraseUselessFunctions(M);
366-
addKernelEntryPoint(M);
367366
expandSYCLTypeUsing(M);
368367

368+
// Kernels called by other kernels
369+
std::vector<Function *> CalledKernels;
369370
for (auto I = M->begin(), E = M->end(); I != E;) {
370371
Function *F = &(*I++);
371372
if (F->isDeclaration() && F->use_empty()) {
@@ -379,7 +380,9 @@ bool SPIRVRegularizeLLVMBase::regularize() {
379380
if (auto *Call = dyn_cast<CallInst>(&II)) {
380381
Call->setTailCall(false);
381382
Function *CF = Call->getCalledFunction();
382-
if (CF && CF->isIntrinsic()) {
383+
if (CF && CF->getCallingConv() == CallingConv::SPIR_KERNEL) {
384+
CalledKernels.push_back(CF);
385+
} else if (CF && CF->isIntrinsic()) {
383386
removeFnAttr(Call, Attribute::NoUnwind);
384387
auto *II = cast<IntrinsicInst>(Call);
385388
if (II->getIntrinsicID() == Intrinsic::memset ||
@@ -497,19 +500,14 @@ bool SPIRVRegularizeLLVMBase::regularize() {
497500
}
498501
}
499502

503+
addKernelEntryPoint(CalledKernels);
500504
if (SPIRVDbgSaveRegularizedModule)
501505
saveLLVMModule(M, RegularizedModuleTmpFile);
502506
return true;
503507
}
504508

505-
void SPIRVRegularizeLLVMBase::addKernelEntryPoint(Module *M) {
506-
std::vector<Function *> Work;
507-
508-
// Get a list of all functions that have SPIR kernel calling conv
509-
for (auto &F : *M) {
510-
if (F.getCallingConv() == CallingConv::SPIR_KERNEL)
511-
Work.push_back(&F);
512-
}
509+
void SPIRVRegularizeLLVMBase::addKernelEntryPoint(
510+
const std::vector<Function *> &Work) {
513511
for (auto &F : Work) {
514512
// for declarations just make them into SPIR functions.
515513
F->setCallingConv(CallingConv::SPIR_FUNC);

lib/SPIRV/SPIRVRegularizeLLVM.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,11 @@ class SPIRVRegularizeLLVMBase {
5151
// Lower functions
5252
bool regularize();
5353

54-
// SPIR-V disallows functions being entrypoints and called
55-
// LLVM doesn't. This adds a wrapper around the entry point
56-
// that later SPIR-V writer renames.
57-
void addKernelEntryPoint(llvm::Module *M);
54+
// SPIR-V disallows functions being entrypoints/kernels and called
55+
// OpenCL doesn't. This adds a wrapper around the entry points that are called
56+
// by other entry point that later SPIR-V writer renames. Caller of the
57+
// function is responsible to fill 'CalledKernels' with such entry points.
58+
void addKernelEntryPoint(const std::vector<Function *> &CalledKernels);
5859

5960
/// Some LLVM intrinsics that have no SPIR-V counterpart may be wrapped in
6061
/// @spirv.llvm_intrinsic_* function. During reverse translation from SPIR-V

lib/SPIRV/SPIRVWriter.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -788,10 +788,11 @@ SPIRVFunction *LLVMToSPIRVBase::transFunctionDecl(Function *F) {
788788
BF->setFunctionControlMask(transFunctionControlMask(F));
789789
if (F->hasName()) {
790790
if (isKernel(F)) {
791-
/* strip the prefix as the runtime will be looking for this name */
792-
std::string Prefix = kSPIRVName::EntrypointPrefix;
793-
std::string Name = F->getName().str();
794-
BM->setName(BF, Name.substr(Prefix.size()));
791+
// If found, strip the entry point wrapper prefix as the runtime will
792+
// be looking for this name
793+
StringRef Name = F->getName();
794+
(void) Name.consume_front(kSPIRVName::EntrypointPrefix);
795+
BM->setName(BF, Name.str());
795796
} else {
796797
if (isUniformGroupOperation(F))
797798
BM->getErrorLog().checkError(
@@ -5329,8 +5330,9 @@ bool LLVMToSPIRVBase::transMetadata() {
53295330
// Work around to translate kernel_arg_type and kernel_arg_type_qual metadata
53305331
static void transKernelArgTypeMD(SPIRVModule *BM, Function *F, MDNode *MD,
53315332
std::string MDName) {
5332-
std::string Prefix = kSPIRVName::EntrypointPrefix;
5333-
std::string Name = F->getName().str().substr(Prefix.size());
5333+
StringRef FunName = F->getName();
5334+
(void) FunName.consume_front(kSPIRVName::EntrypointPrefix);
5335+
std::string Name = FunName.str();
53345336
std::string KernelArgTypesMDStr = std::string(MDName) + "." + Name + ".";
53355337
for (const auto &TyOp : MD->operands())
53365338
KernelArgTypesMDStr += cast<MDString>(TyOp)->getString().str() + ",";

test/entry_point_func.ll

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,47 @@ define spir_kernel void @testfunction() {
1212
ret void
1313
}
1414

15+
define spir_kernel void @callerfunction() {
16+
call spir_kernel void @testfunction()
17+
call spir_kernel void @testdeclaration()
18+
ret void
19+
}
20+
21+
declare spir_kernel void @testdeclaration()
22+
1523
; Check there is an entrypoint and a function produced.
16-
; CHECK-SPIRV: EntryPoint 6 [[EP:[0-9]+]] "testfunction"
17-
; CHECK-SPIRV: Name [[FUNC:[0-9]+]] "testfunction"
18-
; CHECK-SPIRV: Decorate [[FUNC]] LinkageAttributes "testfunction" Export
19-
; CHECK-SPIRV: Function 2 [[FUNC]] 0 3
20-
; CHECK-SPIRV: Function 2 [[EP]] 0 3
21-
; CHECK-SPIRV: FunctionCall 2 8 [[FUNC]]
24+
; CHECK-SPIRV: EntryPoint 6 [[#CallerEn:]] "callerfunction"
25+
; CHECK-SPIRV: EntryPoint 6 [[#TestEn:]] "testfunction"
26+
; CHECK-SPIRV: Name [[#TestDecl:]] "testdeclaration"
27+
; CHECK-SPIRV: Name [[#TestFn:]] "testfunction"
28+
; CHECK-SPIRV: Decorate [[#TestDecl]] LinkageAttributes "testdeclaration" Import
29+
; CHECK-SPIRV: Decorate [[#TestFn]] LinkageAttributes "testfunction" Export
30+
31+
; CHECK-SPIRV: Function [[#]] [[#TestDecl]] [[#]] [[#]]
32+
; CHECK-SPIRV-EMPTY:
33+
; CHECK-SPIRV-NEXT: FunctionEnd
34+
35+
; CHECK-SPIRV: Function [[#]] [[#TestFn]] [[#]] [[#]]
36+
; CHECK-SPIRV-EMPTY:
37+
; CHECK-SPIRV-NEXT: Label
38+
; CHECK-SPIRV-NEXT: Return
39+
; CHECK-SPIRV-EMPTY:
40+
; CHECK-SPIRV-NEXT: FunctionEnd
41+
42+
; CHECK-SPIRV: Function [[#]] [[#CallerEn]] [[#]] [[#]]
43+
; CHECK-SPIRV-EMPTY:
44+
; CHECK-SPIRV-NEXT: Label
45+
; CHECK-SPIRV-NEXT: FunctionCall [[#]] [[#]] [[#TestFn]]
46+
; CHECK-SPIRV-NEXT: FunctionCall [[#]] [[#]] [[#TestDecl]]
47+
; CHECK-SPIRV-NEXT: Return
48+
; CHECK-SPIRV-EMPTY:
49+
; CHECK-SPIRV-NEXT: FunctionEnd
50+
51+
52+
; CHECK-SPIRV: Function [[#]] [[#TestEn]] [[#]] [[#]]
53+
; CHECK-SPIRV-EMPTY:
54+
; CHECK-SPIRV-NEXT: Label
55+
; CHECK-SPIRV-NEXT: FunctionCall [[#]] [[#]] [[#TestFn]]
56+
; CHECK-SPIRV-NEXT: Return
57+
; CHECK-SPIRV-EMPTY:
58+
; CHECK-SPIRV-NEXT: FunctionEnd

test/extensions/INTEL/SPV_INTEL_fpga_argument_interfaces/sycl-kernel-arg-annotation.ll

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ entry:
5353
; CHECK-SPIRV: Capability FPGAArgumentInterfacesINTEL
5454
; CHECK-SPIRV: Extension "SPV_INTEL_fpga_argument_interfaces"
5555
; CHECK-SPIRV: Extension "SPV_INTEL_fpga_buffer_location"
56-
; CHECK-SPIRV-DAG: Name [[IDS:[0-9]+]] "_arg_p"
5756
; CHECK-SPIRV-DAG: Name [[ID:[0-9]+]] "_arg_p"
5857
; CHECK-SPIRV: Decorate [[ID]] Alignment 4
5958
; CHECK-SPIRV: Decorate [[ID]] MMHostInterfaceAddressWidthINTEL 32

test/extensions/INTEL/SPV_INTEL_function_pointers/alias.ll

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,10 @@ target triple = "spir64-unknown-unknown"
1010
; when used since they can't be translated directly.
1111

1212
; CHECK-SPIRV-DAG: Name [[#FOO:]] "foo"
13-
; CHECK-SPIRV-DAG: Name [[#BAR:]] "bar"
13+
; CHECK-SPIRV-DAG: EntryPoint [[#]] [[#BAR:]] "bar"
1414
; CHECK-SPIRV-DAG: Name [[#Y:]] "y"
1515
; CHECK-SPIRV-DAG: Name [[#FOOPTR:]] "foo.alias"
1616
; CHECK-SPIRV-DAG: Decorate [[#FOO]] LinkageAttributes "foo" Export
17-
; CHECK-SPIRV-DAG: Decorate [[#BAR]] LinkageAttributes "bar" Export
1817
; CHECK-SPIRV-DAG: TypeInt [[#I32:]] 32 0
1918
; CHECK-SPIRV-DAG: TypeInt [[#I64:]] 64 0
2019
; CHECK-SPIRV-DAG: TypeFunction [[#FOO_TYPE:]] [[#I32]] [[#I32]]

test/extensions/INTEL/SPV_INTEL_function_pointers/fp-from-host.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
; CHECK-SPIRV: Capability FunctionPointersINTEL
1818
; CHECK-SPIRV: Extension "SPV_INTEL_function_pointers"
1919
;
20-
; CHECK-SPIRV: Name [[KERNEL_ID:[0-9]+]] "test"
20+
; CHECK-SPIRV: EntryPoint [[#]] [[KERNEL_ID:[0-9]+]] "test"
2121
; CHECK-SPIRV: TypeInt [[INT32_TYPE_ID:[0-9]+]] 32
2222
; CHECK-SPIRV: TypePointer [[INT_PTR:[0-9]+]] 5 [[INT32_TYPE_ID]]
2323
; CHECK-SPIRV: TypeFunction [[FOO_TYPE_ID:[0-9]+]] [[INT32_TYPE_ID]] [[INT32_TYPE_ID]]

test/extensions/INTEL/SPV_INTEL_function_pointers/function-pointer-as-function-arg.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
; CHECK-SPIRV: Capability FunctionPointersINTEL
3434
; CHECK-SPIRV: Extension "SPV_INTEL_function_pointers"
3535
;
36-
; CHECK-SPIRV: Name [[KERNEL_ID:[0-9]+]] "test"
36+
; CHECK-SPIRV: EntryPoint [[#]] [[KERNEL_ID:[0-9]+]] "test"
3737
; CHECK-SPIRV: TypeInt [[TYPE_INT32_ID:[0-9]+]] 32
3838
; CHECK-SPIRV: TypeFunction [[FOO_TYPE_ID:[0-9]+]] [[TYPE_INT32_ID]] [[TYPE_INT32_ID]]
3939
; CHECK-SPIRV: TypePointer [[FOO_PTR_TYPE_ID:[0-9]+]] {{[0-9]+}} [[FOO_TYPE_ID]]

test/extensions/INTEL/SPV_INTEL_function_pointers/function-pointer.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
;
2020
; CHECK-SPIRV: Capability FunctionPointersINTEL
2121
; CHECK-SPIRV: Extension "SPV_INTEL_function_pointers"
22-
; CHECK-SPIRV: Name [[KERNEL_ID:[0-9]+]] "test"
22+
; CHECK-SPIRV: EntryPoint [[#]] [[KERNEL_ID:[0-9]+]] "test"
2323
; CHECK-SPIRV: TypeInt [[TYPE_INT_ID:[0-9]+]]
2424
; CHECK-SPIRV: TypeFunction [[FOO_TYPE_ID:[0-9]+]] [[TYPE_INT_ID]] [[TYPE_INT_ID]]
2525
; CHECK-SPIRV: TypePointer [[FOO_PTR_ID:[0-9]+]] {{[0-9]+}} [[FOO_TYPE_ID]]

test/extensions/INTEL/SPV_INTEL_function_pointers/non-uniform-function-pointer.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
; CHECK-SPIRV: Capability FunctionPointersINTEL
3030
; CHECK-SPIRV: Extension "SPV_INTEL_function_pointers"
3131
;
32-
; CHECK-SPIRV: Name [[KERNEL_ID:[0-9]+]] "test"
32+
; CHECK-SPIRV: EntryPoint [[#]] [[KERNEL_ID:[0-9]+]] "test"
3333
; CHECK-SPIRV: TypeInt [[TYPE_INT32_ID:[0-9+]]] 32
3434
; CHECK-SPIRV: TypeFunction [[FOO_TYPE_ID:[0-9]+]] [[TYPE_INT32_ID]] [[TYPE_INT32_ID]]
3535
; CHECK-SPIRV: TypePointer [[FOO_PTR_TYPE_ID:[0-9]+]] {{[0-9]+}} [[FOO_TYPE_ID]]

0 commit comments

Comments
 (0)