@@ -57,6 +57,7 @@ enum KernelInvocationKind {
5757};
5858
5959const static std::string InitMethodName = " __init" ;
60+ const static std::string InitESIMDMethodName = " __init_esimd" ;
6061const static std::string FinalizeMethodName = " __finalize" ;
6162constexpr unsigned MaxKernelArgsSize = 2048 ;
6263
@@ -1714,7 +1715,11 @@ class SyclKernelDeclCreator : public SyclKernelFieldHandler {
17141715 bool isAccessorType = false ) {
17151716 const auto *RecordDecl = FieldTy->getAsCXXRecordDecl ();
17161717 assert (RecordDecl && " The accessor/sampler must be a RecordDecl" );
1717- CXXMethodDecl *InitMethod = getMethodByName (RecordDecl, InitMethodName);
1718+ const std::string &MethodName =
1719+ KernelDecl->hasAttr <SYCLSimdAttr>() && isAccessorType
1720+ ? InitESIMDMethodName
1721+ : InitMethodName;
1722+ CXXMethodDecl *InitMethod = getMethodByName (RecordDecl, MethodName);
17181723 assert (InitMethod && " The accessor/sampler must have the __init method" );
17191724
17201725 // Don't do -1 here because we count on this to be the first parameter added
@@ -1723,9 +1728,14 @@ class SyclKernelDeclCreator : public SyclKernelFieldHandler {
17231728 for (const ParmVarDecl *Param : InitMethod->parameters ()) {
17241729 QualType ParamTy = Param->getType ();
17251730 addParam (FD, ParamTy.getCanonicalType ());
1726- if (ParamTy.getTypePtr ()->isPointerType () && isAccessorType)
1731+ if (ParamTy.getTypePtr ()->isPointerType () && isAccessorType) {
17271732 handleAccessorPropertyList (Params.back (), RecordDecl,
17281733 FD->getLocation ());
1734+ if (KernelDecl->hasAttr <SYCLSimdAttr>())
1735+ // In ESIMD kernels accessor's pointer argument needs to be marked
1736+ Params.back ()->addAttr (
1737+ SYCLSimdAccessorPtrAttr::CreateImplicit (SemaRef.getASTContext ()));
1738+ }
17291739 }
17301740 LastParamIndex = ParamIndex;
17311741 return true ;
@@ -1819,7 +1829,10 @@ class SyclKernelDeclCreator : public SyclKernelFieldHandler {
18191829 QualType FieldTy) final {
18201830 const auto *RecordDecl = FieldTy->getAsCXXRecordDecl ();
18211831 assert (RecordDecl && " The accessor/sampler must be a RecordDecl" );
1822- CXXMethodDecl *InitMethod = getMethodByName (RecordDecl, InitMethodName);
1832+ const std::string MethodName = KernelDecl->hasAttr <SYCLSimdAttr>()
1833+ ? InitESIMDMethodName
1834+ : InitMethodName;
1835+ CXXMethodDecl *InitMethod = getMethodByName (RecordDecl, MethodName);
18231836 assert (InitMethod && " The accessor/sampler must have the __init method" );
18241837
18251838 // Don't do -1 here because we count on this to be the first parameter added
@@ -1951,6 +1964,7 @@ class SyclKernelDeclCreator : public SyclKernelFieldHandler {
19511964class SyclKernelArgsSizeChecker : public SyclKernelFieldHandler {
19521965 SourceLocation KernelLoc;
19531966 unsigned SizeOfParams = 0 ;
1967+ bool IsSIMD = false ;
19541968
19551969 void addParam (QualType ArgTy) {
19561970 SizeOfParams +=
@@ -1960,7 +1974,9 @@ class SyclKernelArgsSizeChecker : public SyclKernelFieldHandler {
19601974 bool handleSpecialType (QualType FieldTy) {
19611975 const CXXRecordDecl *RecordDecl = FieldTy->getAsCXXRecordDecl ();
19621976 assert (RecordDecl && " The accessor/sampler must be a RecordDecl" );
1963- CXXMethodDecl *InitMethod = getMethodByName (RecordDecl, InitMethodName);
1977+ const std::string &MethodName =
1978+ IsSIMD ? InitESIMDMethodName : InitMethodName;
1979+ CXXMethodDecl *InitMethod = getMethodByName (RecordDecl, MethodName);
19641980 assert (InitMethod && " The accessor/sampler must have the __init method" );
19651981 for (const ParmVarDecl *Param : InitMethod->parameters ())
19661982 addParam (Param->getType ());
@@ -1969,8 +1985,8 @@ class SyclKernelArgsSizeChecker : public SyclKernelFieldHandler {
19691985
19701986public:
19711987 static constexpr const bool VisitInsideSimpleContainers = false ;
1972- SyclKernelArgsSizeChecker (Sema &S, SourceLocation Loc)
1973- : SyclKernelFieldHandler(S), KernelLoc(Loc) {}
1988+ SyclKernelArgsSizeChecker (Sema &S, SourceLocation Loc, bool IsSIMD )
1989+ : SyclKernelFieldHandler(S), KernelLoc(Loc), IsSIMD(IsSIMD) {}
19741990
19751991 ~SyclKernelArgsSizeChecker () {
19761992 if (SizeOfParams > MaxKernelArgsSize)
@@ -2044,6 +2060,19 @@ class SyclKernelArgsSizeChecker : public SyclKernelFieldHandler {
20442060 using SyclKernelFieldHandler::handleSyclHalfType;
20452061};
20462062
2063+ static const CXXMethodDecl *getOperatorParens (const CXXRecordDecl *Rec) {
2064+ for (const auto *MD : Rec->methods ()) {
2065+ if (MD->getOverloadedOperator () == OO_Call)
2066+ return MD;
2067+ }
2068+ return nullptr ;
2069+ }
2070+
2071+ static bool isESIMDKernelType (const CXXRecordDecl *KernelObjType) {
2072+ const CXXMethodDecl *OpParens = getOperatorParens (KernelObjType);
2073+ return (OpParens != nullptr ) && OpParens->hasAttr <SYCLSimdAttr>();
2074+ }
2075+
20472076class SyclKernelBodyCreator : public SyclKernelFieldHandler {
20482077 SyclKernelDeclCreator &DeclCreator;
20492078 llvm::SmallVector<Stmt *, 16 > BodyStmts;
@@ -2359,6 +2388,11 @@ class SyclKernelBodyCreator : public SyclKernelFieldHandler {
23592388 return VD;
23602389 }
23612390
2391+ const std::string &getInitMethodName () const {
2392+ bool IsSIMDKernel = isESIMDKernelType (KernelObj);
2393+ return IsSIMDKernel ? InitESIMDMethodName : InitMethodName;
2394+ }
2395+
23622396 // Default inits the type, then calls the init-method in the body.
23632397 bool handleSpecialType (FieldDecl *FD, QualType Ty) {
23642398 addFieldInit (FD, Ty, None,
@@ -2367,7 +2401,7 @@ class SyclKernelBodyCreator : public SyclKernelFieldHandler {
23672401 addFieldMemberExpr (FD, Ty);
23682402
23692403 const auto *RecordDecl = Ty->getAsCXXRecordDecl ();
2370- createSpecialMethodCall (RecordDecl, InitMethodName , BodyStmts);
2404+ createSpecialMethodCall (RecordDecl, getInitMethodName () , BodyStmts);
23712405
23722406 removeFieldMemberExpr (FD, Ty);
23732407
@@ -2377,7 +2411,7 @@ class SyclKernelBodyCreator : public SyclKernelFieldHandler {
23772411 bool handleSpecialType (const CXXBaseSpecifier &BS, QualType Ty) {
23782412 const auto *RecordDecl = Ty->getAsCXXRecordDecl ();
23792413 addBaseInit (BS, Ty, InitializationKind::CreateDefault (KernelCallerSrcLoc));
2380- createSpecialMethodCall (RecordDecl, InitMethodName , BodyStmts);
2414+ createSpecialMethodCall (RecordDecl, getInitMethodName () , BodyStmts);
23812415 return true ;
23822416 }
23832417
@@ -2501,7 +2535,7 @@ class SyclKernelBodyCreator : public SyclKernelFieldHandler {
25012535 // calls, so add them here instead.
25022536 const auto *StreamDecl = Ty->getAsCXXRecordDecl ();
25032537
2504- createSpecialMethodCall (StreamDecl, InitMethodName , BodyStmts);
2538+ createSpecialMethodCall (StreamDecl, getInitMethodName () , BodyStmts);
25052539 createSpecialMethodCall (StreamDecl, FinalizeMethodName, FinalizeStmts);
25062540
25072541 removeFieldMemberExpr (FD, Ty);
@@ -2659,7 +2693,9 @@ class SyclKernelIntHeaderCreator : public SyclKernelFieldHandler {
26592693 const CXXRecordDecl *KernelObj, QualType NameType,
26602694 StringRef Name, StringRef StableName)
26612695 : SyclKernelFieldHandler(S), Header(H) {
2662- Header.startKernel (Name, NameType, StableName, KernelObj->getLocation ());
2696+ bool IsSIMDKernel = isESIMDKernelType (KernelObj);
2697+ Header.startKernel (Name, NameType, StableName, KernelObj->getLocation (),
2698+ IsSIMDKernel);
26632699 }
26642700
26652701 bool handleSyclAccessorType (const CXXRecordDecl *RD,
@@ -3026,7 +3062,10 @@ void Sema::CheckSYCLKernelCall(FunctionDecl *KernelFunc, SourceRange CallLoc,
30263062 SyclKernelDecompMarker DecompMarker (*this );
30273063 SyclKernelFieldChecker FieldChecker (*this );
30283064 SyclKernelUnionChecker UnionChecker (*this );
3029- SyclKernelArgsSizeChecker ArgsSizeChecker (*this , Args[0 ]->getExprLoc ());
3065+
3066+ bool IsSIMDKernel = isESIMDKernelType (KernelObj);
3067+ SyclKernelArgsSizeChecker ArgsSizeChecker (*this , Args[0 ]->getExprLoc (),
3068+ IsSIMDKernel);
30303069
30313070 KernelObjVisitor Visitor{*this };
30323071 SYCLKernelNameTypeVisitor KernelNameTypeVisitor (*this , Args[0 ]->getExprLoc (),
@@ -3087,6 +3126,8 @@ void Sema::ConstructOpenCLKernel(FunctionDecl *KernelCallerFunc,
30873126 if (KernelObj->isInvalidDecl ())
30883127 return ;
30893128
3129+ bool IsSIMDKernel = isESIMDKernelType (KernelObj);
3130+
30903131 // Calculate both names, since Integration headers need both.
30913132 std::string CalculatedName, StableName;
30923133 std::tie (CalculatedName, StableName) =
@@ -3095,7 +3136,7 @@ void Sema::ConstructOpenCLKernel(FunctionDecl *KernelCallerFunc,
30953136 : CalculatedName);
30963137 SyclKernelDeclCreator kernel_decl (*this , KernelName, KernelObj->getLocation (),
30973138 KernelCallerFunc->isInlined (),
3098- KernelCallerFunc-> hasAttr <SYCLSimdAttr>() );
3139+ IsSIMDKernel );
30993140 SyclKernelBodyCreator kernel_body (*this , kernel_decl, KernelObj,
31003141 KernelCallerFunc);
31013142 SyclKernelIntHeaderCreator int_header (
@@ -3810,6 +3851,9 @@ void SYCLIntegrationHeader::emit(raw_ostream &O) {
38103851 O << " getParamDesc(unsigned i) {\n " ;
38113852 O << " return kernel_signatures[i+" << CurStart << " ];\n " ;
38123853 O << " }\n " ;
3854+ O << " __SYCL_DLL_LOCAL\n " ;
3855+ O << " static constexpr bool isESIMD() { return " << K.IsESIMDKernel
3856+ << " ; }\n " ;
38133857 O << " };\n " ;
38143858 CurStart += N;
38153859 }
@@ -3839,12 +3883,14 @@ bool SYCLIntegrationHeader::emit(const StringRef &IntHeaderName) {
38393883void SYCLIntegrationHeader::startKernel (StringRef KernelName,
38403884 QualType KernelNameType,
38413885 StringRef KernelStableName,
3842- SourceLocation KernelLocation) {
3886+ SourceLocation KernelLocation,
3887+ bool IsESIMDKernel) {
38433888 KernelDescs.resize (KernelDescs.size () + 1 );
38443889 KernelDescs.back ().Name = std::string (KernelName);
38453890 KernelDescs.back ().NameType = KernelNameType;
38463891 KernelDescs.back ().StableName = std::string (KernelStableName);
38473892 KernelDescs.back ().KernelLocation = KernelLocation;
3893+ KernelDescs.back ().IsESIMDKernel = IsESIMDKernel;
38483894}
38493895
38503896void SYCLIntegrationHeader::addParamDesc (kernel_param_kind_t Kind, int Info,
0 commit comments