Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
7974c35
Support for arrays as kernel parameters.
rdeodhar Jun 9, 2020
4907194
Reusing some memberexpr building code.
rdeodhar Jun 9, 2020
d54c0ca
Merge branch 'sycl' of https://github.com/otcshare/llvm into akp2
rdeodhar Jun 9, 2020
546c58d
Merge branch 'sycl' of https://github.com/otcshare/llvm into akp2
rdeodhar Jun 10, 2020
52ce3f2
Updated support for arrays.
rdeodhar Jun 12, 2020
983b3d5
Merge branch 'sycl' of https://github.com/otcshare/llvm into akp2
rdeodhar Jun 12, 2020
1bf0903
Formatting changes.
rdeodhar Jun 12, 2020
5d5121b
Formatting changes.
rdeodhar Jun 12, 2020
f03edd9
Correction to a test.
rdeodhar Jun 15, 2020
d87b2cc
Merge branch 'sycl' of https://github.com/otcshare/llvm into akp2
rdeodhar Jun 22, 2020
0412db3
Array elements are now passed as individual parameters.
rdeodhar Jun 25, 2020
810af7b
Merge branch 'sycl' of https://github.com/otcshare/llvm into akp2
rdeodhar Jun 25, 2020
00c082f
Merge branch 'sycl' of https://github.com/otcshare/llvm into akp2
rdeodhar Jun 25, 2020
af0b0c9
Corrections to temporarily disable tests expected to fail.
rdeodhar Jun 25, 2020
d5fb2d9
Changed tests to work with current array support.
rdeodhar Jun 26, 2020
db492bd
Decomposed array elements, and changed manner of array element initia…
rdeodhar Jun 27, 2020
59cabac
Merge branch 'sycl' of https://github.com/otcshare/llvm into akp2
rdeodhar Jun 27, 2020
4afc3a3
Removed one redundant check.
rdeodhar Jun 29, 2020
9196a30
Changed how some lit tests are run.
rdeodhar Jun 30, 2020
5660269
Update clang/test/CodeGenSYCL/kernel-param-member-acc-array-ih.cpp
rdeodhar Jun 30, 2020
81ace26
Fixed formatting.
rdeodhar Jun 30, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
201 changes: 155 additions & 46 deletions clang/lib/Sema/SemaSYCL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -878,7 +878,6 @@ template <typename Derived> class SyclKernelFieldHandler {
virtual void leaveField(const CXXRecordDecl *, const CXXBaseSpecifier &) {}
virtual void enterField(const CXXRecordDecl *, FieldDecl *) {}
virtual void leaveField(const CXXRecordDecl *, FieldDecl *) {}
virtual void enterArray(const CXXBaseSpecifier &) {}
virtual void enterArray() {}
virtual void nextElement(QualType) {}
virtual void leaveArray(QualType, int64_t) {}
Expand All @@ -897,10 +896,10 @@ class SyclKernelFieldChecker
if (const auto *CAT = dyn_cast<ConstantArrayType>(FieldTy)) {
QualType ET = CAT->getElementType();
return checkNotCopyableToKernel(FD, ET);
} else
return Diag.Report(FD->getLocation(),
diag::err_sycl_non_constant_array_type)
<< FieldTy;
}
return Diag.Report(FD->getLocation(),
diag::err_sycl_non_constant_array_type)
<< FieldTy;
}

if (SemaRef.getASTContext().getLangOpts().SYCLStdLayoutKernelParams)
Expand Down Expand Up @@ -1125,6 +1124,30 @@ class SyclKernelDeclCreator
return true;
}

bool handleArrayType(FieldDecl *FD, QualType FieldTy) final {
// if (!Util::isArrayOfSpecialSyclType(FieldTy)) {
if (!cast<ConstantArrayType>(FieldTy)
->getElementType()
->isStructureOrClassType()) {
// Wrap the array in a struct.
RecordDecl *NewClass =
SemaRef.getASTContext().buildImplicitRecord("wrapped_array");
NewClass->startDefinition();
FieldDecl *Field = FieldDecl::Create(
SemaRef.getASTContext(), NewClass, SourceLocation(), SourceLocation(),
/*Id=*/nullptr, FieldTy,
SemaRef.getASTContext().getTrivialTypeSourceInfo(FieldTy,
SourceLocation()),
/*BW=*/nullptr, /*Mutable=*/false, /*InitStyle=*/ICIS_NoInit);
Field->setAccess(AS_public);
NewClass->addDecl(Field);
NewClass->completeDefinition();
QualType ST = SemaRef.getASTContext().getRecordType(NewClass);
addParam(FD, ST);
}
return true;
}

bool handleScalarType(FieldDecl *FD, QualType FieldTy) final {
addParam(FD, FieldTy);
return true;
Expand Down Expand Up @@ -1260,6 +1283,41 @@ class SyclKernelBodyCreator
InitExprs.push_back(MemberInit.get());
}

void createExprForArray(FieldDecl *FD) {
ParmVarDecl *KernelParameter =
DeclCreator.getParamVarDeclsForCurrentField()[0];
QualType ParamType = KernelParameter->getOriginalType();
CXXRecordDecl *WrapperStruct = ParamType->getAsCXXRecordDecl();
// The first and only field of the wrapper struct is the array
FieldDecl *Array = *(WrapperStruct->field_begin());
auto DRE = DeclRefExpr::Create(SemaRef.Context, NestedNameSpecifierLoc(),
SourceLocation(), KernelParameter, false,
DeclarationNameInfo(), ParamType, VK_LValue);
DeclAccessPair ArrayDAP = DeclAccessPair::make(Array, AS_none);
Expr *InitExpr = MemberExpr::Create(
SemaRef.Context, DRE, false, SourceLocation(), NestedNameSpecifierLoc(),
SourceLocation(), Array, ArrayDAP,
DeclarationNameInfo(Array->getDeclName(), SourceLocation()), nullptr,
Array->getType(), VK_LValue, OK_Ordinary, NOUR_None);
InitializationKind InitKind = InitializationKind::CreateDirect(
SourceLocation(), SourceLocation(), SourceLocation());
InitializedEntity Entity = InitializedEntity::InitializeLambdaCapture(
nullptr, Array->getType(), SourceLocation());
InitializationSequence InitSeq(SemaRef, Entity, InitKind, InitExpr);
ExprResult MemberInit =
InitSeq.Perform(SemaRef, Entity, InitKind, InitExpr);
InitExprs.push_back(MemberInit.get());
}

void createExprForArrayElement(size_t ArrayIndex) {
Expr *ArrayBase = MemberExprBases.back();
ExprResult IndexExpr =
SemaRef.ActOnIntegerConstant(SourceLocation(), ArrayIndex);
ExprResult ElementBase = SemaRef.CreateBuiltinArraySubscriptExpr(
ArrayBase, SourceLocation(), IndexExpr.get(), SourceLocation());
MemberExprBases.push_back(ElementBase.get());
}

void createSpecialMethodCall(const CXXRecordDecl *SpecialClass, Expr *Base,
const std::string &MethodName,
FieldDecl *Field) {
Expand All @@ -1276,9 +1334,7 @@ class SyclKernelBodyCreator
ParamDREs[I] = SemaRef.BuildDeclRefExpr(KernelParameters[I], ParamType,
VK_LValue, SourceLocation());
}

MemberExpr *SpecialObjME = BuildMemberExpr(Base, Field);
MemberExpr *MethodME = BuildMemberExpr(SpecialObjME, Method);
MemberExpr *MethodME = BuildMemberExpr(Base, Method);

QualType ResultTy = Method->getReturnType();
ExprValueKind VK = Expr::getValueKindForType(ResultTy);
Expand Down Expand Up @@ -1313,7 +1369,7 @@ class SyclKernelBodyCreator
bool handleSpecialType(FieldDecl *FD, QualType Ty) {
const auto *RecordDecl = Ty->getAsCXXRecordDecl();
// Perform initialization only if it is field of kernel object
if (MemberExprBases.size() == 1) {
if (MemberExprBases.size() == 2) {
InitializedEntity Entity =
InitializedEntity::InitializeMember(FD, &VarEntity);
// Initialize with the default constructor.
Expand Down Expand Up @@ -1371,9 +1427,10 @@ class SyclKernelBodyCreator
bool handleSyclStreamType(FieldDecl *FD, QualType Ty) final {
const auto *StreamDecl = Ty->getAsCXXRecordDecl();
createExprForStructOrScalar(FD);
createSpecialMethodCall(StreamDecl, MemberExprBases.back(), InitMethodName,
FD);
createSpecialMethodCall(StreamDecl, MemberExprBases.back(),
size_t NumBases = MemberExprBases.size();
createSpecialMethodCall(StreamDecl, MemberExprBases[NumBases - 2],
InitMethodName, FD);
createSpecialMethodCall(StreamDecl, MemberExprBases[NumBases - 2],
FinalizeMethodName, FD);
return true;
}
Expand All @@ -1399,16 +1456,53 @@ class SyclKernelBodyCreator
return true;
}

void enterStruct(const CXXRecordDecl *, FieldDecl *FD) final {
MemberExprBases.push_back(BuildMemberExpr(MemberExprBases.back(), FD));
bool handleArrayType(FieldDecl *FD, QualType FieldTy) final {
if (!cast<ConstantArrayType>(FieldTy)
->getElementType()
->isStructureOrClassType()) {
createExprForArray(FD);
}
return true;
}

void leaveStruct(const CXXRecordDecl *, FieldDecl *FD) final {
MemberExprBases.pop_back();
void enterField(const CXXRecordDecl *RD, FieldDecl *FD) final {
if (!FD->getType()->isReferenceType())
MemberExprBases.push_back(BuildMemberExpr(MemberExprBases.back(), FD));
}

using SyclKernelFieldHandler::enterStruct;
using SyclKernelFieldHandler::leaveStruct;
void leaveField(const CXXRecordDecl *, FieldDecl *FD) final {
if (!FD->getType()->isReferenceType())
MemberExprBases.pop_back();
}

void enterArray() final {
Expr *ArrayBase = MemberExprBases.back();
ExprResult IndexExpr = SemaRef.ActOnIntegerConstant(SourceLocation(), 0);
ExprResult ElementBase = SemaRef.CreateBuiltinArraySubscriptExpr(
ArrayBase, SourceLocation(), IndexExpr.get(), SourceLocation());
MemberExprBases.push_back(ElementBase.get());
}

void nextElement(QualType) final {
ArraySubscriptExpr *LastArrayRef =
dyn_cast<ArraySubscriptExpr>(MemberExprBases.back());
MemberExprBases.pop_back();
Expr *LastIdx = LastArrayRef->getIdx();
llvm::APSInt Result;
SemaRef.VerifyIntegerConstantExpression(LastIdx, &Result);
Expr *ArrayBase = MemberExprBases.back();
ExprResult IndexExpr = SemaRef.ActOnIntegerConstant(
SourceLocation(), Result.getExtValue() + 1);
ExprResult ElementBase = SemaRef.CreateBuiltinArraySubscriptExpr(
ArrayBase, SourceLocation(), IndexExpr.get(), SourceLocation());
MemberExprBases.push_back(ElementBase.get());
}

void leaveArray(QualType, int64_t) final { MemberExprBases.pop_back(); }

using SyclKernelFieldHandler::enterArray;
using SyclKernelFieldHandler::enterField;
using SyclKernelFieldHandler::leaveField;
};

class SyclKernelIntHeaderCreator
Expand All @@ -1419,23 +1513,20 @@ class SyclKernelIntHeaderCreator
const CXXRecordDecl *CurStruct = nullptr;
int64_t CurOffset = 0;

uint64_t getOffset(const CXXRecordDecl *RD) const {
assert(CurOffset &&
"Cannot have a base class without setting the active struct");
const ASTRecordLayout &Layout =
SemaRef.getASTContext().getASTRecordLayout(CurStruct);
return CurOffset + Layout.getBaseClassOffset(RD).getQuantity();
}
uint64_t getOffset(const FieldDecl *FD) const {
return CurOffset + SemaRef.getASTContext().getFieldOffset(FD) / 8;
}

void addParam(const FieldDecl *FD, QualType FieldTy,
void addParam(const FieldDecl *FD, QualType ArgTy,
SYCLIntegrationHeader::kernel_param_kind_t Kind) {
uint64_t Size =
SemaRef.getASTContext().getTypeSizeInChars(FieldTy).getQuantity();
uint64_t Size;
const ConstantArrayType *CAT =
SemaRef.getASTContext().getAsConstantArrayType(ArgTy);
if (CAT) {
QualType ET = CAT->getElementType();
Size = static_cast<size_t>(CAT->getSize().getZExtValue()) *
SemaRef.getASTContext().getTypeSizeInChars(ET).getQuantity();
} else {
Size = SemaRef.getASTContext().getTypeSizeInChars(ArgTy).getQuantity();
}
Header.addParamDesc(Kind, static_cast<unsigned>(Size),
static_cast<unsigned>(getOffset(FD)));
static_cast<unsigned>(CurOffset));
}

public:
Expand All @@ -1456,8 +1547,7 @@ class SyclKernelIntHeaderCreator
int Dims = static_cast<int>(
AccTy->getTemplateArgs()[1].getAsIntegral().getExtValue());
int Info = getAccessTarget(AccTy) | (Dims << 11);
Header.addParamDesc(SYCLIntegrationHeader::kind_accessor, Info,
getOffset(BC.getType()->getAsCXXRecordDecl()));
Header.addParamDesc(SYCLIntegrationHeader::kind_accessor, Info, CurOffset);
return true;
}

Expand All @@ -1469,8 +1559,7 @@ class SyclKernelIntHeaderCreator
int Dims = static_cast<int>(
AccTy->getTemplateArgs()[1].getAsIntegral().getExtValue());
int Info = getAccessTarget(AccTy) | (Dims << 11);
Header.addParamDesc(SYCLIntegrationHeader::kind_accessor, Info,
getOffset(FD));
Header.addParamDesc(SYCLIntegrationHeader::kind_accessor, Info, CurOffset);
return true;
}

Expand Down Expand Up @@ -1511,10 +1600,21 @@ class SyclKernelIntHeaderCreator
addParam(FD, FieldTy, SYCLIntegrationHeader::kind_pointer);
return true;
}

bool handleArrayType(FieldDecl *FD, QualType FieldTy) final {
// if (!Util::isArrayOfSpecialSyclType(FieldTy))
if (!cast<ConstantArrayType>(FieldTy)
->getElementType()
->isStructureOrClassType())
addParam(FD, FieldTy, SYCLIntegrationHeader::kind_std_layout);
return true;
}

bool handleStructType(FieldDecl *FD, QualType FieldTy) final {
addParam(FD, FieldTy, SYCLIntegrationHeader::kind_std_layout);
return true;
}

bool handleScalarType(FieldDecl *FD, QualType FieldTy) final {
addParam(FD, FieldTy, SYCLIntegrationHeader::kind_std_layout);
return true;
Expand All @@ -1524,39 +1624,48 @@ class SyclKernelIntHeaderCreator
addParam(FD, FieldTy, SYCLIntegrationHeader::kind_std_layout);
return true;
}

bool handleSyclStreamType(const CXXBaseSpecifier &BC,
QualType FieldTy) final {
// FIXME SYCL stream should be usable as a base type
// See https://github.com/intel/llvm/issues/1552
return true;
}

// Keep track of the current struct offset.
void enterStruct(const CXXRecordDecl *RD, FieldDecl *FD) final {
CurStruct = FD->getType()->getAsCXXRecordDecl();
void enterField(const CXXRecordDecl *RD, FieldDecl *FD) final {
CurOffset += SemaRef.getASTContext().getFieldOffset(FD) / 8;
}

void leaveStruct(const CXXRecordDecl *RD, FieldDecl *FD) final {
CurStruct = RD;
void leaveField(const CXXRecordDecl *, FieldDecl *FD) final {
CurOffset -= SemaRef.getASTContext().getFieldOffset(FD) / 8;
}

void enterStruct(const CXXRecordDecl *RD, const CXXBaseSpecifier &BS) final {
CurStruct = BS.getType()->getAsCXXRecordDecl();
void enterField(const CXXRecordDecl *RD, const CXXBaseSpecifier &BS) final {
const ASTRecordLayout &Layout =
SemaRef.getASTContext().getASTRecordLayout(RD);
CurOffset += Layout.getBaseClassOffset(BS.getType()->getAsCXXRecordDecl())
.getQuantity();
}

void leaveStruct(const CXXRecordDecl *RD, const CXXBaseSpecifier &BS) final {
CurStruct = RD;
void leaveField(const CXXRecordDecl *RD, const CXXBaseSpecifier &BS) final {
const ASTRecordLayout &Layout =
SemaRef.getASTContext().getASTRecordLayout(RD);
CurOffset -= Layout.getBaseClassOffset(BS.getType()->getAsCXXRecordDecl())
.getQuantity();
}

void nextElement(QualType ET) final {
CurOffset += SemaRef.getASTContext().getTypeSizeInChars(ET).getQuantity();
}

void leaveArray(QualType ET, int64_t Count) final {
int64_t ArraySize =
SemaRef.getASTContext().getTypeSizeInChars(ET).getQuantity();
if (!ET->isArrayType()) {
ArraySize *= Count;
}
CurOffset -= ArraySize;
}
};
} // namespace

Expand Down
55 changes: 55 additions & 0 deletions clang/test/CodeGenSYCL/kernel-param-acc-array-ih.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// RUN: %clang -I %S/Inputs -fsycl-device-only -Xclang -fsycl-int-header=%t.h %s -c -o %T/kernel.spv
// RUN: FileCheck -input-file=%t.h %s

// This test checks the integration header generated when
// the kernel argument is an Accessor array.

// CHECK: #include <CL/sycl/detail/kernel_desc.hpp>

// CHECK: class kernel_A;

// CHECK: __SYCL_INLINE_NAMESPACE(cl) {
// CHECK-NEXT: namespace sycl {
// CHECK-NEXT: namespace detail {

// CHECK: static constexpr
// CHECK-NEXT: const char* const kernel_names[] = {
// CHECK-NEXT: "_ZTSZ4mainE8kernel_A"
// CHECK-NEXT: };

// CHECK: static constexpr
// CHECK-NEXT: const kernel_param_desc_t kernel_signatures[] = {
// CHECK-NEXT: //--- _ZTSZ4mainE8kernel_A
// CHECK-NEXT: { kernel_param_kind_t::kind_accessor, 4062, 0 },
// CHECK-NEXT: { kernel_param_kind_t::kind_accessor, 4062, 12 },
// CHECK-EMPTY:
// CHECK-NEXT: };

// CHECK: static constexpr
// CHECK-NEXT: const unsigned kernel_signature_start[] = {
// CHECK-NEXT: 0 // _ZTSZ4mainE8kernel_A
// CHECK-NEXT: };

// CHECK: template <> struct KernelInfo<class kernel_A> {

#include <sycl.hpp>

using namespace cl::sycl;

template <typename name, typename Func>
__attribute__((sycl_kernel)) void a_kernel(Func kernelFunc) {
kernelFunc();
}

int main() {

using Accessor =
accessor<int, 1, access::mode::read_write, access::target::global_buffer>;

Accessor acc[2];

a_kernel<class kernel_A>(
[=]() {
acc[1].use();
});
}
Loading