@@ -1148,10 +1148,10 @@ static target getAccessTarget(QualType FieldTy,
11481148
11491149// FIXME: Free functions must have void return type and be declared at file
11501150// scope, outside any namespaces.
1151- static bool isFreeFunction (SemaSYCL &SemaSYCLRef, const FunctionDecl *FD) {
1151+ bool SemaSYCL:: isFreeFunction (const FunctionDecl *FD) {
11521152 for (auto *IRAttr : FD->specific_attrs <SYCLAddIRAttributesFunctionAttr>()) {
11531153 SmallVector<std::pair<std::string, std::string>, 4 > NameValuePairs =
1154- IRAttr->getAttributeNameValuePairs (SemaSYCLRef. getASTContext ());
1154+ IRAttr->getAttributeNameValuePairs (getASTContext ());
11551155 for (const auto &NameValuePair : NameValuePairs) {
11561156 if (NameValuePair.first == " sycl-nd-range-kernel" ||
11571157 NameValuePair.first == " sycl-single-task-kernel" ) {
@@ -5291,7 +5291,7 @@ void SemaSYCL::SetSYCLKernelNames() {
52915291 SyclKernelsToOpenCLKernels) {
52925292 std::string CalculatedName, StableName;
52935293 StringRef KernelName;
5294- if (isFreeFunction (* this , Pair.first )) {
5294+ if (isFreeFunction (Pair.first )) {
52955295 std::tie (CalculatedName, StableName) =
52965296 constructFreeFunctionKernelName (*this , Pair.first , *MangleCtx);
52975297 KernelName = CalculatedName;
@@ -5414,24 +5414,66 @@ void SemaSYCL::ConstructOpenCLKernel(FunctionDecl *KernelCallerFunc,
54145414 }
54155415}
54165416
5417- void ConstructFreeFunctionKernel (SemaSYCL &SemaSYCLRef, FunctionDecl *FD) {
5418- SyclKernelArgsSizeChecker argsSizeChecker (SemaSYCLRef, FD->getLocation (),
5417+ static void addRegisteredKernelName (SemaSYCL &S, StringRef Str,
5418+ FunctionDecl *FD, SourceLocation Loc) {
5419+ if (!Str.empty ())
5420+ FD->addAttr (SYCLRegisteredKernelNameAttr::CreateImplicit (S.getASTContext (),
5421+ Str, Loc));
5422+ }
5423+
5424+ static bool checkAndAddRegisteredKernelName (SemaSYCL &S, FunctionDecl *FD,
5425+ StringRef Str) {
5426+ using KernelPair = std::pair<const FunctionDecl *, FunctionDecl *>;
5427+ for (const KernelPair &Pair : S.getKernelFDPairs ()) {
5428+ if (Pair.first == FD) {
5429+ // If the current list of free function entries already contains this
5430+ // free function, apply the name Str as an attribute. But if it already
5431+ // has an attribute name, issue a diagnostic instead.
5432+ if (!Str.empty ()) {
5433+ if (!Pair.second ->hasAttr <SYCLRegisteredKernelNameAttr>())
5434+ addRegisteredKernelName (S, Str, Pair.second , FD->getLocation ());
5435+ else
5436+ S.Diag (FD->getLocation (),
5437+ diag::err_registered_kernels_name_already_registered)
5438+ << Pair.second ->getAttr <SYCLRegisteredKernelNameAttr>()
5439+ ->getRegName ()
5440+ << Str;
5441+ }
5442+ // An empty name string implies a regular free kernel construction
5443+ // call, so simply return.
5444+ return false ;
5445+ }
5446+ }
5447+ return true ;
5448+ }
5449+
5450+ void SemaSYCL::constructFreeFunctionKernel (FunctionDecl *FD,
5451+ StringRef NameStr) {
5452+ if (!checkAndAddRegisteredKernelName (*this , FD, NameStr))
5453+ return ;
5454+
5455+ SyclKernelArgsSizeChecker argsSizeChecker (*this , FD->getLocation (),
54195456 false /* IsSIMDKernel*/ );
5420- SyclKernelDeclCreator kernel_decl (SemaSYCLRef, FD->getLocation (),
5421- FD->isInlined (), false /* IsSIMDKernel */ ,
5422- FD);
5457+ SyclKernelDeclCreator kernel_decl (*this , FD->getLocation (), FD->isInlined (),
5458+ false /* IsSIMDKernel */ , FD);
54235459
5424- FreeFunctionKernelBodyCreator kernel_body (SemaSYCLRef , kernel_decl, FD);
5460+ FreeFunctionKernelBodyCreator kernel_body (* this , kernel_decl, FD);
54255461
5426- SyclKernelIntHeaderCreator int_header (
5427- SemaSYCLRef, SemaSYCLRef. getSyclIntegrationHeader (), FD->getType (), FD);
5462+ SyclKernelIntHeaderCreator int_header (* this , getSyclIntegrationHeader (),
5463+ FD->getType (), FD);
54285464
5429- SyclKernelIntFooterCreator int_footer (SemaSYCLRef,
5430- SemaSYCLRef.getSyclIntegrationFooter ());
5431- KernelObjVisitor Visitor{SemaSYCLRef};
5465+ SyclKernelIntFooterCreator int_footer (*this , getSyclIntegrationFooter ());
5466+ KernelObjVisitor Visitor{*this };
54325467
54335468 Visitor.VisitFunctionParameters (FD, argsSizeChecker, kernel_decl, kernel_body,
54345469 int_header, int_footer);
5470+
5471+ assert (getKernelFDPairs ().back ().first == FD &&
5472+ " OpenCL Kernel not found for free function entry" );
5473+ // Register the kernel name with the OpenCL kernel generated for the
5474+ // free function.
5475+ addRegisteredKernelName (*this , NameStr, getKernelFDPairs ().back ().second ,
5476+ FD->getLocation ());
54355477}
54365478
54375479// Figure out the sub-group for the this function. First we check the
@@ -5717,7 +5759,7 @@ void SemaSYCL::MarkDevices() {
57175759}
57185760
57195761void SemaSYCL::ProcessFreeFunction (FunctionDecl *FD) {
5720- if (isFreeFunction (* this , FD)) {
5762+ if (isFreeFunction (FD)) {
57215763 SyclKernelDecompMarker DecompMarker (*this );
57225764 SyclKernelFieldChecker FieldChecker (*this );
57235765 SyclKernelUnionChecker UnionChecker (*this );
@@ -5736,7 +5778,7 @@ void SemaSYCL::ProcessFreeFunction(FunctionDecl *FD) {
57365778 if (!FieldChecker.isValid () || !UnionChecker.isValid ())
57375779 return ;
57385780
5739- ConstructFreeFunctionKernel (* this , FD);
5781+ constructFreeFunctionKernel ( FD);
57405782 }
57415783}
57425784
@@ -6621,7 +6663,7 @@ void SYCLIntegrationHeader::emit(raw_ostream &O) {
66216663 unsigned ShimCounter = 1 ;
66226664 int FreeFunctionCount = 0 ;
66236665 for (const KernelDesc &K : KernelDescs) {
6624- if (!isFreeFunction (S, K.SyclKernel ))
6666+ if (!S. isFreeFunction (K.SyclKernel ))
66256667 continue ;
66266668 ++FreeFunctionCount;
66276669 // Generate forward declaration for free function.
@@ -6739,7 +6781,7 @@ void SYCLIntegrationHeader::emit(raw_ostream &O) {
67396781 }
67406782 ShimCounter = 1 ;
67416783 for (const KernelDesc &K : KernelDescs) {
6742- if (!isFreeFunction (S, K.SyclKernel ))
6784+ if (!S. isFreeFunction (K.SyclKernel ))
67436785 continue ;
67446786
67456787 O << " \n // Definition of kernel_id of " << K.Name << " \n " ;
0 commit comments