Skip to content

Commit e4295e6

Browse files
author
iclsrc
committed
Merge from 'sycl' to 'sycl-web'
2 parents e280047 + cece649 commit e4295e6

27 files changed

+426
-125
lines changed

clang/include/clang/Basic/Attr.td

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1172,6 +1172,16 @@ def SYCLRegisterNum : InheritableAttr {
11721172
let PragmaAttributeSupport = 0;
11731173
}
11741174

1175+
// Used to mark ESIMD kernel pointer parameters originating from accessors.
1176+
def SYCLSimdAccessorPtr : InheritableAttr {
1177+
// No spelling, as this attribute can't be created in the source code.
1178+
let Spellings = [];
1179+
let Subjects = SubjectList<[ParmVar]>;
1180+
let LangOpts = [SYCLExplicitSIMD];
1181+
let Documentation = [SYCLSimdAccessorPtrDocs];
1182+
let PragmaAttributeSupport = 0;
1183+
}
1184+
11751185
def SYCLScope : Attr {
11761186
// No spelling, as this attribute can't be created in the source code.
11771187
let Spellings = [];

clang/include/clang/Basic/AttrDocs.td

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,18 @@ def SYCLRegisterNumDocs : Documentation {
380380
}];
381381
}
382382

383+
def SYCLSimdAccessorPtrDocs : Documentation {
384+
let Category = DocCatVariable;
385+
let Content = [{
386+
The ``__attribute__((esimd_acc_ptr))`` attribute is used by FE to mark ESIMD
387+
kernel pointer parameters which correspond to the original
388+
lambda's captured accessors. FE turns the attribute to some metadata
389+
required by the ESIMD Back-End.
390+
Not supposed to be used directly in the source - SYCL device compiler FE
391+
automatically adds it for ESIMD kernels.
392+
}];
393+
}
394+
383395
def C11NoReturnDocs : Documentation {
384396
let Category = DocCatFunction;
385397
let Content = [{

clang/include/clang/Sema/Sema.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,8 @@ class SYCLIntegrationHeader {
332332
/// Signals that subsequent parameter descriptor additions will go to
333333
/// the kernel with given name. Starts new kernel invocation descriptor.
334334
void startKernel(StringRef KernelName, QualType KernelNameType,
335-
StringRef KernelStableName, SourceLocation Loc);
335+
StringRef KernelStableName, SourceLocation Loc,
336+
bool IsESIMD);
336337

337338
/// Adds a kernel parameter descriptor to current kernel invocation
338339
/// descriptor.
@@ -375,6 +376,9 @@ class SYCLIntegrationHeader {
375376

376377
SourceLocation KernelLocation;
377378

379+
/// Whether this kernel is an ESIMD one.
380+
bool IsESIMDKernel;
381+
378382
/// Descriptor of kernel actual parameters.
379383
SmallVector<KernelParamDesc, 8> Params;
380384

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1487,6 +1487,10 @@ void CodeGenModule::GenOpenCLArgMetadata(llvm::Function *Fn,
14871487
// MDNode for the intel_buffer_location attribute.
14881488
SmallVector<llvm::Metadata *, 8> argSYCLBufferLocationAttr;
14891489

1490+
// MDNode for listing ESIMD kernel pointer arguments originating from
1491+
// accessors
1492+
SmallVector<llvm::Metadata *, 8> argESIMDAccPtrs;
1493+
14901494
if (FD && CGF)
14911495
for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i) {
14921496
const ParmVarDecl *parm = FD->getParamDecl(i);
@@ -1618,6 +1622,10 @@ void CodeGenModule::GenOpenCLArgMetadata(llvm::Function *Fn,
16181622
? llvm::ConstantAsMetadata::get(CGF->Builder.getInt32(
16191623
SYCLBufferLocationAttr->getLocationID()))
16201624
: llvm::ConstantAsMetadata::get(CGF->Builder.getInt32(-1)));
1625+
1626+
if (FD->hasAttr<SYCLSimdAttr>())
1627+
argESIMDAccPtrs.push_back(llvm::ConstantAsMetadata::get(
1628+
CGF->Builder.getInt1(parm->hasAttr<SYCLSimdAccessorPtrAttr>())));
16211629
}
16221630

16231631
if (LangOpts.SYCLIsDevice && !LangOpts.SYCLExplicitSIMD)
@@ -1634,6 +1642,9 @@ void CodeGenModule::GenOpenCLArgMetadata(llvm::Function *Fn,
16341642
llvm::MDNode::get(VMContext, argBaseTypeNames));
16351643
Fn->setMetadata("kernel_arg_type_qual",
16361644
llvm::MDNode::get(VMContext, argTypeQuals));
1645+
if (FD && FD->hasAttr<SYCLSimdAttr>())
1646+
Fn->setMetadata("kernel_arg_accessor_ptr",
1647+
llvm::MDNode::get(VMContext, argESIMDAccPtrs));
16371648
if (getCodeGenOpts().EmitOpenCLArgMetadata)
16381649
Fn->setMetadata("kernel_arg_name",
16391650
llvm::MDNode::get(VMContext, argNames));

clang/lib/Sema/SemaSYCL.cpp

Lines changed: 59 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ enum KernelInvocationKind {
5757
};
5858

5959
const static std::string InitMethodName = "__init";
60+
const static std::string InitESIMDMethodName = "__init_esimd";
6061
const static std::string FinalizeMethodName = "__finalize";
6162
constexpr 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 {
19511964
class 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

19701986
public:
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+
20472076
class 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) {
38393883
void 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

38503896
void SYCLIntegrationHeader::addParamDesc(kernel_param_kind_t Kind, int Info,

clang/test/CodeGenSYCL/Inputs/sycl.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ class accessor {
156156
private:
157157
void __init(__attribute__((opencl_global)) dataT *Ptr, range<dimensions> AccessRange,
158158
range<dimensions> MemRange, id<dimensions> Offset) {}
159+
void __init_esimd(__attribute__((opencl_global)) dataT *Ptr) {}
159160
};
160161

161162
template <int dimensions, access::mode accessmode, access::target accesstarget>
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// RUN: %clang_cc1 -fsycl -fsycl-explicit-simd -fsycl-is-device \
2+
// RUN: -internal-isystem %S/Inputs -triple spir64-unknown-unknown-sycldevice \
3+
// RUN: -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s
4+
5+
// This test checks
6+
// 1) proper metadata generation for accessors used in ESIMD
7+
// kernels:
8+
// - Proper 'kernel_arg_accessor_ptr' metadata is generated by the FE for
9+
// ESIMD kernels
10+
// - Pointers originating from accessors are marked with 'buffer_t' and proper
11+
// argument kind.
12+
// 2) __init_esimd function is used to initialize the accessor rather than
13+
// __init.
14+
15+
#include "sycl.hpp"
16+
17+
using namespace cl::sycl;
18+
19+
void test(int val) {
20+
queue q;
21+
q.submit([&](handler &h) {
22+
cl::sycl::accessor<int, 1, cl::sycl::access::mode::read_write> accessorA;
23+
cl::sycl::accessor<int, 1, cl::sycl::access::mode::read> accessorB;
24+
25+
h.single_task<class esimd_kernel>(
26+
[=]() __attribute__((sycl_explicit_simd)) {
27+
accessorA.use(val);
28+
accessorB.use();
29+
});
30+
});
31+
32+
// --- Name
33+
// CHECK-LABEL: define spir_kernel void @"_ZTSZZ4testiENK3$_0clERN2cl4sycl7handlerEE12esimd_kernel"(
34+
// --- Signature
35+
// CHECK: i32 addrspace(1)* "VCArgumentDesc"="buffer_t" "VCArgumentIOKind"="0" "VCArgumentKind"="2" %_arg_,
36+
// CHECK: i32 "VCArgumentDesc" "VCArgumentIOKind"="0" "VCArgumentKind"="0" %_arg_1,
37+
// CHECK: i32 addrspace(1)* "VCArgumentDesc"="buffer_t" "VCArgumentIOKind"="0" "VCArgumentKind"="2" %_arg_3)
38+
// --- Attributes
39+
// CHECK: {{.*}} !kernel_arg_accessor_ptr ![[ACC_PTR_ATTR:[0-9]+]] !sycl_explicit_simd !{{[0-9]+}} {{.*}}{
40+
// --- init_esimd call is expected instead of __init:
41+
// CHECK: call spir_func void @{{.*}}__init_esimd{{.*}}(%"{{.*}}sycl::accessor" addrspace(4)* %{{[0-9]+}}, i32 addrspace(1)* %{{[0-9]+}})
42+
// CHECK-LABEL: }
43+
// CHECK: ![[ACC_PTR_ATTR]] = !{i1 true, i1 false, i1 true}
44+
}

0 commit comments

Comments
 (0)