diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 3c2e0a863d5ad..d9ae70b86d99a 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -335,7 +335,8 @@ class SYCLIntegrationHeader { /// Signals that subsequent parameter descriptor additions will go to /// the kernel with given name. Starts new kernel invocation descriptor. void startKernel(const FunctionDecl *SyclKernel, QualType KernelNameType, - SourceLocation Loc, bool IsESIMD, bool IsUnnamedKernel); + SourceLocation Loc, bool IsESIMD, bool IsUnnamedKernel, + int64_t ObjSize); /// Adds a kernel parameter descriptor to current kernel invocation /// descriptor. @@ -402,10 +403,15 @@ class SYCLIntegrationHeader { // hasn't provided an explicit name for. bool IsUnnamedKernel; + /// Size of the kernel object. + int64_t ObjSize = 0; + KernelDesc(const FunctionDecl *SyclKernel, QualType NameType, - SourceLocation KernelLoc, bool IsESIMD, bool IsUnnamedKernel) + SourceLocation KernelLoc, bool IsESIMD, bool IsUnnamedKernel, + int64_t ObjSize) : SyclKernel(SyclKernel), NameType(NameType), KernelLocation(KernelLoc), - IsESIMDKernel(IsESIMD), IsUnnamedKernel(IsUnnamedKernel) {} + IsESIMDKernel(IsESIMD), IsUnnamedKernel(IsUnnamedKernel), + ObjSize(ObjSize) {} void updateKernelNames(StringRef Name, StringRef StableName) { this->Name = Name.str(); diff --git a/clang/lib/Sema/SemaSYCL.cpp b/clang/lib/Sema/SemaSYCL.cpp index fac53fcfbf94a..c9e23e30bb7ed 100644 --- a/clang/lib/Sema/SemaSYCL.cpp +++ b/clang/lib/Sema/SemaSYCL.cpp @@ -3124,8 +3124,13 @@ class SyclKernelIntHeaderCreator : public SyclKernelFieldHandler { FunctionDecl *KernelFunc) : SyclKernelFieldHandler(S), Header(H) { bool IsSIMDKernel = isESIMDKernelType(KernelObj); + // The header needs to access the kernel object size. + int64_t ObjSize = SemaRef.getASTContext() + .getTypeSizeInChars(KernelObj->getTypeForDecl()) + .getQuantity(); Header.startKernel(KernelFunc, NameType, KernelObj->getLocation(), - IsSIMDKernel, IsSYCLUnnamedKernel(S, KernelFunc)); + IsSIMDKernel, IsSYCLUnnamedKernel(S, KernelFunc), + ObjSize); } bool handleSyclSpecialType(const CXXRecordDecl *RD, @@ -4777,6 +4782,14 @@ void SYCLIntegrationHeader::emit(raw_ostream &O) { O << " return 0;\n"; O << "#endif\n"; O << " }\n"; + StringRef ReturnType = + (S.Context.getTargetInfo().getInt64Type() == TargetInfo::SignedLong) + ? "long" + : "long long"; + O << " // Returns the size of the kernel object in bytes.\n"; + O << " __SYCL_DLL_LOCAL\n"; + O << " static constexpr " << ReturnType << " getKernelSize() { return " + << K.ObjSize << "; }\n"; O << "};\n"; CurStart += N; } @@ -4807,9 +4820,9 @@ void SYCLIntegrationHeader::startKernel(const FunctionDecl *SyclKernel, QualType KernelNameType, SourceLocation KernelLocation, bool IsESIMDKernel, - bool IsUnnamedKernel) { + bool IsUnnamedKernel, int64_t ObjSize) { KernelDescs.emplace_back(SyclKernel, KernelNameType, KernelLocation, - IsESIMDKernel, IsUnnamedKernel); + IsESIMDKernel, IsUnnamedKernel, ObjSize); } void SYCLIntegrationHeader::addParamDesc(kernel_param_kind_t Kind, int Info, diff --git a/clang/test/CodeGenSYCL/int_header_kernelobjsize.cpp b/clang/test/CodeGenSYCL/int_header_kernelobjsize.cpp new file mode 100644 index 0000000000000..a055d26b7062e --- /dev/null +++ b/clang/test/CodeGenSYCL/int_header_kernelobjsize.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -fsycl-is-device -internal-isystem %S/Inputs -fsycl-int-header=%t.h %s +// RUN: FileCheck -input-file=%t.h %s + +// This test checks that the getKernelSize() member function is +// generated into the integration header and that it returns the +// size of the kernel object in bytes. + +#include "sycl.hpp" + +using namespace cl::sycl; + +void testA() { + queue q; + constexpr int N = 256; + int A[N] = {10}; + q.submit([&](handler &h) { + h.single_task([=]() { + for (int k = 0; k < N; ++k) { + (void)A[k]; + } + }); + }); +} +// CHECK: template <> struct KernelInfo { +// CHECK: // Returns the size of the kernel object in bytes. +// CHECK: static constexpr long{{.*}} getKernelSize() { return 1024; }