Skip to content

Commit 1be5f2d

Browse files
authored
Merge branch 'sycl' into test-optimizations
2 parents d5ff978 + 414c1e5 commit 1be5f2d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+811
-192
lines changed

buildbot/dependency.conf

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@ ocl_cpu_rt_ver=2020.10.7.0.15
44
# https://github.com/intel/llvm/releases/download/2020-WW31/win-oclcpuexp-2020.10.7.0.15_rel.zip
55
ocl_cpu_rt_ver_win=2020.10.7.0.15
66
# Same GPU driver supports Level Zero and OpenCL:
7-
# https://github.com/intel/compute-runtime/releases/tag/20.25.17111
7+
# https://github.com/intel/compute-runtime/releases/tag/20.29.17408
88
ocl_gpu_rt_ver=20.29.17408
99
# Same GPU driver supports Level Zero and OpenCL:
1010
# https://downloadmirror.intel.com/29674/a08/igfx_win10_100.8336.zip
1111
ocl_gpu_rt_ver_win=27.20.100.8336
1212
intel_sycl_ver=build
13-
# https://github.com/oneapi-src/oneTBB/releases/download/v2020.2/tbb-2020.2-lin.tgz
13+
# TODO provide URL for Linux TBB driver
1414
tbb_ver=2021.1.8.515
15-
# https://github.com/oneapi-src/oneTBB/releases/download/v2020.2/tbb-2020.2-win.zip
15+
# TODO provide URL for Windows TBB driver
1616
tbb_ver_win=2021.1.8.514
1717
# https://github.com/intel/llvm/releases/download/2020-WW31/fpgaemu-2020.10.7.0.15_rel.tar.gz
1818
ocl_fpga_emu_ver=2020.10.7.0.15

clang/include/clang/Basic/Attr.td

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1131,7 +1131,7 @@ def SYCLDevice : InheritableAttr {
11311131
def SYCLKernel : InheritableAttr {
11321132
let Spellings = [Clang<"sycl_kernel">];
11331133
let Subjects = SubjectList<[FunctionTmpl]>;
1134-
let LangOpts = [SYCLIsDevice];
1134+
let LangOpts = [SYCLIsHost, SYCLIsDevice];
11351135
let Documentation = [SYCLKernelDocs];
11361136
}
11371137

@@ -1188,6 +1188,14 @@ def SYCLDeviceIndirectlyCallable : InheritableAttr {
11881188
let PragmaAttributeSupport = 0;
11891189
}
11901190

1191+
def SYCLIntelBufferLocation : InheritableAttr {
1192+
// No spelling, as this attribute can't be created in the source code.
1193+
let Spellings = [];
1194+
let Args = [UnsignedArgument<"LocationID">];
1195+
let LangOpts = [SYCLIsDevice, SYCLIsHost];
1196+
let Documentation = [SYCLIntelBufferLocationAttrDocs];
1197+
}
1198+
11911199
def SYCLIntelKernelArgsRestrict : InheritableAttr {
11921200
let Spellings = [ CXX11<"intel", "kernel_args_restrict"> ];
11931201
let Subjects = SubjectList<[Function], ErrorDiag>;

clang/include/clang/Basic/AttrDocs.td

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1994,6 +1994,25 @@ can be lowered.
19941994
}];
19951995
}
19961996

1997+
def SYCLIntelBufferLocationAttrDocs : Documentation {
1998+
let Category = DocCatFunction;
1999+
let Heading = "kernel_args_buffer_location";
2000+
let Content = [{
2001+
This attribute is implicitly added to OpenCL pointer kernel parameters generated
2002+
from a SYCL kernel object. It lacks a spelling, as it is not intended to be used
2003+
by the programmer.
2004+
2005+
This attribute causes clang to generate metadata on the OpenCL kernel containing
2006+
the number of kernel parameters. The metadata contains an integer that is set
2007+
according to the values passed through the ``accessor`` property
2008+
``buffer_location``. These values are mapped to the actual locations of the
2009+
global buffers (such as DDR, QDR, etc) and applied to pointer kernel parameters.
2010+
Number of metadata arguments is the same as a number of kernel parameters, so
2011+
any parameter that isn't an ``accessor`` with ``buffer_location`` property is
2012+
annotated by '-1' in the metadata node.
2013+
}];
2014+
}
2015+
19972016
def SYCLIntelKernelArgsRestrictDocs : Documentation {
19982017
let Category = DocCatVariable;
19992018
let Heading = "kernel_args_restrict";

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10919,8 +10919,8 @@ def warn_sycl_kernel_invalid_template_param_type : Warning<
1091910919
"template parameter of a function template with the 'sycl_kernel' attribute"
1092010920
" cannot be a non-type template parameter">, InGroup<IgnoredAttributes>;
1092110921
def warn_sycl_kernel_num_of_function_params : Warning<
10922-
"function template with 'sycl_kernel' attribute must have a single parameter">,
10923-
InGroup<IgnoredAttributes>;
10922+
"function template with 'sycl_kernel' attribute must have at least one"
10923+
" parameter">, InGroup<IgnoredAttributes>;
1092410924
def warn_sycl_kernel_return_type : Warning<
1092510925
"function template with 'sycl_kernel' attribute must have a 'void' return type">,
1092610926
InGroup<IgnoredAttributes>;
@@ -10980,6 +10980,16 @@ def warn_boolean_attribute_argument_is_not_valid: Warning<
1098010980
def err_sycl_attibute_cannot_be_applied_here
1098110981
: Error<"%0 attribute cannot be applied to a "
1098210982
"static function or function in an anonymous namespace">;
10983+
def err_sycl_compiletime_property_duplication : Error<
10984+
"Can't apply %0 property twice to the same accessor">;
10985+
def err_sycl_invalid_property_list_param_number : Error<
10986+
"%0 must have exactly one template parameter">;
10987+
def err_sycl_invalid_accessor_property_template_param : Error<
10988+
"Fifth template parameter of the accessor must be of a property_list type">;
10989+
def err_sycl_invalid_property_list_template_param : Error<
10990+
"%select{property_list|property_list pack argument|buffer_location}0 "
10991+
"template parameter must be a "
10992+
"%select{parameter pack|type|non-negative integer}1">;
1098310993
def warn_sycl_attibute_function_raw_ptr
1098410994
: Warning<"SYCL 1.2.1 specification does not allow %0 attribute applied "
1098510995
"to a function with a raw pointer "

clang/lib/CodeGen/CodeGenFunction.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -889,6 +889,9 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
889889
if (D && D->hasAttr<CFICanonicalJumpTableAttr>())
890890
Fn->addFnAttr("cfi-canonical-jump-table");
891891

892+
if (getLangOpts().SYCLIsHost && D && D->hasAttr<SYCLKernelAttr>())
893+
Fn->addFnAttr("sycl_kernel");
894+
892895
if (getLangOpts().OpenCL || getLangOpts().SYCLIsDevice) {
893896
// Add metadata for a kernel function.
894897
if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) {

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1413,6 +1413,9 @@ void CodeGenModule::GenOpenCLArgMetadata(llvm::Function *Fn,
14131413
// MDNode for the kernel argument names.
14141414
SmallVector<llvm::Metadata *, 8> argNames;
14151415

1416+
// MDNode for the intel_buffer_location attribute.
1417+
SmallVector<llvm::Metadata *, 8> argSYCLBufferLocationAttr;
1418+
14161419
if (FD && CGF)
14171420
for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i) {
14181421
const ParmVarDecl *parm = FD->getParamDecl(i);
@@ -1536,6 +1539,14 @@ void CodeGenModule::GenOpenCLArgMetadata(llvm::Function *Fn,
15361539

15371540
// Get argument name.
15381541
argNames.push_back(llvm::MDString::get(VMContext, parm->getName()));
1542+
1543+
auto *SYCLBufferLocationAttr =
1544+
parm->getAttr<SYCLIntelBufferLocationAttr>();
1545+
argSYCLBufferLocationAttr.push_back(
1546+
(SYCLBufferLocationAttr)
1547+
? llvm::ConstantAsMetadata::get(CGF->Builder.getInt32(
1548+
SYCLBufferLocationAttr->getLocationID()))
1549+
: llvm::ConstantAsMetadata::get(CGF->Builder.getInt32(-1)));
15391550
}
15401551

15411552
Fn->setMetadata("kernel_arg_addr_space",
@@ -1551,6 +1562,9 @@ void CodeGenModule::GenOpenCLArgMetadata(llvm::Function *Fn,
15511562
if (getCodeGenOpts().EmitOpenCLArgMetadata)
15521563
Fn->setMetadata("kernel_arg_name",
15531564
llvm::MDNode::get(VMContext, argNames));
1565+
if (LangOpts.SYCLIsDevice)
1566+
Fn->setMetadata("kernel_arg_buffer_location",
1567+
llvm::MDNode::get(VMContext, argSYCLBufferLocationAttr));
15541568
}
15551569

15561570
/// Determines whether the language options require us to model

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7188,15 +7188,16 @@ static void handleSYCLKernelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
71887188
const FunctionTemplateDecl *FT = FD->getDescribedFunctionTemplate();
71897189
assert(FT && "Function template is expected");
71907190

7191-
// Function template must have at least two template parameters.
7191+
// Function template must have at least two template parameters so it
7192+
// can be used in OpenCL kernel generation.
71927193
const TemplateParameterList *TL = FT->getTemplateParameters();
7193-
if (TL->size() < 2) {
7194+
if (S.LangOpts.SYCLIsDevice && TL->size() < 2) {
71947195
S.Diag(FT->getLocation(), diag::warn_sycl_kernel_num_of_template_params);
71957196
return;
71967197
}
71977198

7198-
// Template parameters must be typenames.
7199-
for (unsigned I = 0; I < 2; ++I) {
7199+
// The first two template parameters must be typenames.
7200+
for (unsigned I = 0; I < 2 && I < TL->size(); ++I) {
72007201
const NamedDecl *TParam = TL->getParam(I);
72017202
if (isa<NonTypeTemplateParmDecl>(TParam)) {
72027203
S.Diag(FT->getLocation(),
@@ -7205,8 +7206,8 @@ static void handleSYCLKernelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
72057206
}
72067207
}
72077208

7208-
// Function must have at least one argument.
7209-
if (getFunctionOrMethodNumParams(D) != 1) {
7209+
// Function must have at least one parameter.
7210+
if (getFunctionOrMethodNumParams(D) < 1) {
72107211
S.Diag(FT->getLocation(), diag::warn_sycl_kernel_num_of_function_params);
72117212
return;
72127213
}

clang/lib/Sema/SemaSYCL.cpp

Lines changed: 149 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,14 @@ class Util {
8080
/// half class.
8181
static bool isSyclHalfType(const QualType &Ty);
8282

83+
/// Checks whether given clang type is a full specialization of the SYCL
84+
/// property_list class.
85+
static bool isPropertyListType(const QualType &Ty);
86+
87+
/// Checks whether given clang type is a full specialization of the SYCL
88+
/// buffer_location class.
89+
static bool isSyclBufferLocationType(const QualType &Ty);
90+
8391
/// Checks whether given clang type is a standard SYCL API class with given
8492
/// name.
8593
/// \param Ty the clang type being checked
@@ -1076,6 +1084,66 @@ class SyclKernelFieldChecker : public SyclKernelFieldHandler {
10761084
return false;
10771085
}
10781086

1087+
void checkPropertyListType(TemplateArgument PropList, SourceLocation Loc) {
1088+
if (PropList.getKind() != TemplateArgument::ArgKind::Type) {
1089+
SemaRef.Diag(Loc,
1090+
diag::err_sycl_invalid_accessor_property_template_param);
1091+
return;
1092+
}
1093+
QualType PropListTy = PropList.getAsType();
1094+
if (!Util::isPropertyListType(PropListTy)) {
1095+
SemaRef.Diag(Loc,
1096+
diag::err_sycl_invalid_accessor_property_template_param);
1097+
return;
1098+
}
1099+
const auto *PropListDecl =
1100+
cast<ClassTemplateSpecializationDecl>(PropListTy->getAsRecordDecl());
1101+
if (PropListDecl->getTemplateArgs().size() != 1) {
1102+
SemaRef.Diag(Loc, diag::err_sycl_invalid_property_list_param_number)
1103+
<< "property_list";
1104+
return;
1105+
}
1106+
const auto TemplArg = PropListDecl->getTemplateArgs()[0];
1107+
if (TemplArg.getKind() != TemplateArgument::ArgKind::Pack) {
1108+
SemaRef.Diag(Loc, diag::err_sycl_invalid_property_list_template_param)
1109+
<< /*property_list*/ 0 << /*parameter pack*/ 0;
1110+
return;
1111+
}
1112+
for (TemplateArgument::pack_iterator Prop = TemplArg.pack_begin();
1113+
Prop != TemplArg.pack_end(); ++Prop) {
1114+
if (Prop->getKind() != TemplateArgument::ArgKind::Type) {
1115+
SemaRef.Diag(Loc, diag::err_sycl_invalid_property_list_template_param)
1116+
<< /*property_list pack argument*/ 1 << /*type*/ 1;
1117+
return;
1118+
}
1119+
QualType PropTy = Prop->getAsType();
1120+
if (Util::isSyclBufferLocationType(PropTy))
1121+
checkBufferLocationType(PropTy, Loc);
1122+
}
1123+
}
1124+
1125+
void checkBufferLocationType(QualType PropTy, SourceLocation Loc) {
1126+
const auto *PropDecl =
1127+
dyn_cast<ClassTemplateSpecializationDecl>(PropTy->getAsRecordDecl());
1128+
if (PropDecl->getTemplateArgs().size() != 1) {
1129+
SemaRef.Diag(Loc, diag::err_sycl_invalid_property_list_param_number)
1130+
<< "buffer_location";
1131+
return;
1132+
}
1133+
const auto BufferLoc = PropDecl->getTemplateArgs()[0];
1134+
if (BufferLoc.getKind() != TemplateArgument::ArgKind::Integral) {
1135+
SemaRef.Diag(Loc, diag::err_sycl_invalid_property_list_template_param)
1136+
<< /*buffer_location*/ 2 << /*non-negative integer*/ 2;
1137+
return;
1138+
}
1139+
int LocationID = static_cast<int>(BufferLoc.getAsIntegral().getExtValue());
1140+
if (LocationID < 0) {
1141+
SemaRef.Diag(Loc, diag::err_sycl_invalid_property_list_template_param)
1142+
<< /*buffer_location*/ 2 << /*non-negative integer*/ 2;
1143+
return;
1144+
}
1145+
}
1146+
10791147
void checkAccessorType(QualType Ty, SourceRange Loc) {
10801148
assert(Util::isSyclAccessorType(Ty) &&
10811149
"Should only be called on SYCL accessor types.");
@@ -1087,6 +1155,8 @@ class SyclKernelFieldChecker : public SyclKernelFieldHandler {
10871155
TemplateArgument TA = TAL.get(0);
10881156
const QualType TemplateArgTy = TA.getAsType();
10891157

1158+
if (TAL.size() > 5)
1159+
checkPropertyListType(TAL.get(5), Loc.getBegin());
10901160
llvm::DenseSet<QualType> Visited;
10911161
checkSYCLType(SemaRef, TemplateArgTy, Loc, Visited);
10921162
}
@@ -1158,8 +1228,9 @@ class SyclKernelDeclCreator : public SyclKernelFieldHandler {
11581228

11591229
void addParam(ParamDesc newParamDesc, QualType FieldTy) {
11601230
// Create a new ParmVarDecl based on the new info.
1231+
ASTContext &Ctx = SemaRef.getASTContext();
11611232
auto *NewParam = ParmVarDecl::Create(
1162-
SemaRef.getASTContext(), KernelDecl, SourceLocation(), SourceLocation(),
1233+
Ctx, KernelDecl, SourceLocation(), SourceLocation(),
11631234
std::get<1>(newParamDesc), std::get<0>(newParamDesc),
11641235
std::get<2>(newParamDesc), SC_None, /*DefArg*/ nullptr);
11651236
NewParam->setScopeInfo(0, Params.size());
@@ -1169,11 +1240,56 @@ class SyclKernelDeclCreator : public SyclKernelFieldHandler {
11691240
Params.push_back(NewParam);
11701241
}
11711242

1243+
// Handle accessor properties. If any properties were found in
1244+
// the property_list - add the appropriate attributes to ParmVarDecl.
1245+
void handleAccessorPropertyList(ParmVarDecl *Param,
1246+
const CXXRecordDecl *RecordDecl,
1247+
SourceLocation Loc) {
1248+
const auto *AccTy = cast<ClassTemplateSpecializationDecl>(RecordDecl);
1249+
// TODO: when SYCL headers' part is ready - replace this 'if' with an error
1250+
if (AccTy->getTemplateArgs().size() < 6)
1251+
return;
1252+
const auto PropList = cast<TemplateArgument>(AccTy->getTemplateArgs()[5]);
1253+
QualType PropListTy = PropList.getAsType();
1254+
const auto *PropListDecl =
1255+
cast<ClassTemplateSpecializationDecl>(PropListTy->getAsRecordDecl());
1256+
const auto TemplArg = PropListDecl->getTemplateArgs()[0];
1257+
// Move through TemplateArgs list of a property list and search for
1258+
// properties. If found - apply the appropriate attribute to ParmVarDecl.
1259+
for (TemplateArgument::pack_iterator Prop = TemplArg.pack_begin();
1260+
Prop != TemplArg.pack_end(); ++Prop) {
1261+
QualType PropTy = Prop->getAsType();
1262+
if (Util::isSyclBufferLocationType(PropTy))
1263+
handleBufferLocationProperty(Param, PropTy, Loc);
1264+
}
1265+
}
1266+
1267+
// Obtain an integer value stored in a template parameter of buffer_location
1268+
// property to pass it to buffer_location kernel attribute
1269+
void handleBufferLocationProperty(ParmVarDecl *Param, QualType PropTy,
1270+
SourceLocation Loc) {
1271+
// If we have more than 1 buffer_location properties on a single
1272+
// accessor - emit an error
1273+
if (Param->hasAttr<SYCLIntelBufferLocationAttr>()) {
1274+
SemaRef.Diag(Loc, diag::err_sycl_compiletime_property_duplication)
1275+
<< "buffer_location";
1276+
return;
1277+
}
1278+
ASTContext &Ctx = SemaRef.getASTContext();
1279+
const auto *PropDecl =
1280+
cast<ClassTemplateSpecializationDecl>(PropTy->getAsRecordDecl());
1281+
const auto BufferLoc = PropDecl->getTemplateArgs()[0];
1282+
int LocationID = static_cast<int>(BufferLoc.getAsIntegral().getExtValue());
1283+
Param->addAttr(
1284+
SYCLIntelBufferLocationAttr::CreateImplicit(Ctx, LocationID));
1285+
}
1286+
11721287
// All special SYCL objects must have __init method. We extract types for
11731288
// kernel parameters from __init method parameters. We will use __init method
11741289
// and kernel parameters which we build here to initialize special objects in
11751290
// the kernel body.
1176-
bool handleSpecialType(FieldDecl *FD, QualType FieldTy) {
1291+
bool handleSpecialType(FieldDecl *FD, QualType FieldTy,
1292+
bool isAccessorType = false) {
11771293
const auto *RecordDecl = FieldTy->getAsCXXRecordDecl();
11781294
assert(RecordDecl && "The accessor/sampler must be a RecordDecl");
11791295
CXXMethodDecl *InitMethod = getMethodByName(RecordDecl, InitMethodName);
@@ -1182,8 +1298,13 @@ class SyclKernelDeclCreator : public SyclKernelFieldHandler {
11821298
// Don't do -1 here because we count on this to be the first parameter added
11831299
// (if any).
11841300
size_t ParamIndex = Params.size();
1185-
for (const ParmVarDecl *Param : InitMethod->parameters())
1186-
addParam(FD, Param->getType().getCanonicalType());
1301+
for (const ParmVarDecl *Param : InitMethod->parameters()) {
1302+
QualType ParamTy = Param->getType();
1303+
addParam(FD, ParamTy.getCanonicalType());
1304+
if (ParamTy.getTypePtr()->isPointerType() && isAccessorType)
1305+
handleAccessorPropertyList(Params.back(), RecordDecl,
1306+
FD->getLocation());
1307+
}
11871308
LastParamIndex = ParamIndex;
11881309
return true;
11891310
}
@@ -1253,14 +1374,18 @@ class SyclKernelDeclCreator : public SyclKernelFieldHandler {
12531374
// Don't do -1 here because we count on this to be the first parameter added
12541375
// (if any).
12551376
size_t ParamIndex = Params.size();
1256-
for (const ParmVarDecl *Param : InitMethod->parameters())
1257-
addParam(BS, Param->getType().getCanonicalType());
1377+
for (const ParmVarDecl *Param : InitMethod->parameters()) {
1378+
QualType ParamTy = Param->getType();
1379+
addParam(BS, ParamTy.getCanonicalType());
1380+
if (ParamTy.getTypePtr()->isPointerType())
1381+
handleAccessorPropertyList(Params.back(), RecordDecl, BS.getBeginLoc());
1382+
}
12581383
LastParamIndex = ParamIndex;
12591384
return true;
12601385
}
12611386

12621387
bool handleSyclAccessorType(FieldDecl *FD, QualType FieldTy) final {
1263-
return handleSpecialType(FD, FieldTy);
1388+
return handleSpecialType(FD, FieldTy, /*isAccessorType*/ true);
12641389
}
12651390

12661391
bool handleSyclSamplerType(FieldDecl *FD, QualType FieldTy) final {
@@ -2834,6 +2959,23 @@ bool Util::isSyclSpecConstantType(const QualType &Ty) {
28342959
return matchQualifiedTypeName(Ty, Scopes);
28352960
}
28362961

2962+
bool Util::isPropertyListType(const QualType &Ty) {
2963+
return isSyclType(Ty, "property_list", true /*Tmpl*/);
2964+
}
2965+
2966+
bool Util::isSyclBufferLocationType(const QualType &Ty) {
2967+
const StringRef &Name = "buffer_location";
2968+
std::array<DeclContextDesc, 4> Scopes = {
2969+
Util::DeclContextDesc{clang::Decl::Kind::Namespace, "cl"},
2970+
Util::DeclContextDesc{clang::Decl::Kind::Namespace, "sycl"},
2971+
// TODO: this doesn't belong to property namespace, instead it shall be
2972+
// in its own namespace. Change it, when the actual implementation in SYCL
2973+
// headers is ready
2974+
Util::DeclContextDesc{clang::Decl::Kind::Namespace, "property"},
2975+
Util::DeclContextDesc{Decl::Kind::ClassTemplateSpecialization, Name}};
2976+
return matchQualifiedTypeName(Ty, Scopes);
2977+
}
2978+
28372979
bool Util::isSyclType(const QualType &Ty, StringRef Name, bool Tmpl) {
28382980
Decl::Kind ClassDeclKind =
28392981
Tmpl ? Decl::Kind::ClassTemplateSpecialization : Decl::Kind::CXXRecord;

0 commit comments

Comments
 (0)