From 6a13fa903f380e17378286a7cd43995b0ae162ad Mon Sep 17 00:00:00 2001 From: Artem Gindinson Date: Thu, 7 Jul 2022 08:49:48 +0000 Subject: [PATCH] Rework kernel metadata handling in SPIR-V Reader After the introduction of kernel entry point wrappers within KhronosGroup/SPIRV-LLVM-Translator@85815e7, initial approach to avoiding kernel metadata duplication within our internal SPIR-V consumer has been to skip metadata generation whenever we encounter the entry point kernel (we would assume that all necessary metadata had already been assigned to the LLVM function upon encountering the "actual" SPIR-V kernel). For more details on the initial approach, see intel/intel-graphics-compiler@12332c1. The change, however, did not take into account that all SPIR-V information regarding the kernel execution mode was being stored exclusively for the entry point wrapper kernel. Therefore, by skipping the SPIR-V entry point wrappers we end up losing certain metadata entries, e.g. "required WG size". Assume that the entry point wrappers contain fuller information and generate LLVM metadata based on these SPIR-V functions instead. This fixes kernel attributes' lowering with LLVM 14. An alternative SPIR-V Reader solution would imply copying over all SPIR-V information from entry point wrappers to the actual kernel body, and then dropping entry point wrappers from the `SPIRVModule`'s/`SPIRVToLLVM`'s function collections. --- IGC/AdaptorOCL/SPIRV/SPIRVReader.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/IGC/AdaptorOCL/SPIRV/SPIRVReader.cpp b/IGC/AdaptorOCL/SPIRV/SPIRVReader.cpp index 33441cf620cf..29d098d7337d 100644 --- a/IGC/AdaptorOCL/SPIRV/SPIRVReader.cpp +++ b/IGC/AdaptorOCL/SPIRV/SPIRVReader.cpp @@ -58,7 +58,6 @@ THE SOFTWARE. #include #include #include -#include #include "libSPIRV/SPIRVDebugInfoExt.h" #include "llvmWrapper/Transforms/Utils/Cloning.h" #include "common/LLVMWarningsPop.hpp" @@ -4707,15 +4706,11 @@ SPIRVToLLVM::transKernelMetadata() transCapsIntoMetadata(MD); NamedMDNode *KernelMDs = M->getOrInsertNamedMetadata(SPIR_MD_KERNELS); - SmallSet HandledLLVMKernels; for (unsigned I = 0, E = BM->getNumFunctions(); I != E; ++I) { SPIRVFunction *BF = BM->getFunction(I); Function *F = static_cast(getTranslatedValue(BF)); IGC_ASSERT_MESSAGE(F, "Invalid translated function"); - if (HandledLLVMKernels.count(F)) - continue; - HandledLLVMKernels.insert(F); // __attribute__((annotate("some_user_annotation"))) are passed via // UserSemantic decoration on functions. @@ -4727,6 +4722,17 @@ SPIRVToLLVM::transKernelMetadata() if (F->getCallingConv() != CallingConv::SPIR_KERNEL || F->isDeclaration()) continue; + // Kernel entry point wrappers and SPIR-V functions with actual kernel + // body resolve to the same LLVM functions. Only generate metadata upon + // encountering entry point wrappers, as SPIR-V stores all execution + // mode information at the entry point wrapper site. + // TODO: Instead, consider copying all SPIR-V function information from + // entry point wrappers to the actual SPIR-V funtions, and then + // erasing entry point wrappers as such from the SPIRVModule/ + // SPIRVToLLVM classes. Preferably, such a rework should be done in the + // Khronos SPIR-V Translator and then downstreamed. + if (!isOpenCLKernel(BF)) + continue; std::vector KernelMD; KernelMD.push_back(ValueAsMetadata::get(F));