Skip to content

Commit a43dcc2

Browse files
[SYCL] Disallow mutable lambdas (#1785)
[SYCL] Disallow mutable lambdas (#1785) With the latest changes in the SYCL spec kernel lambdas (and functors) must be const references. Have updated the SYCL headers and tests with this change. Also had to make a minor adjustment to the kernel generation code in Clang and update many of the SemaSYCL tests, because their mock kernel defs needed to be updated as well. Clang also emits a diagnostic if version flag (-std-sycl) doesn't match kernel passing (new by const reference or old by value) and enabled -std-sycl=2020 Signed-off-by: Chris Perkins [email protected]
1 parent 44136bd commit a43dcc2

File tree

134 files changed

+453
-404
lines changed

Some content is hidden

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

134 files changed

+453
-404
lines changed

clang/include/clang/Basic/DiagnosticGroups.td

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1127,7 +1127,9 @@ def OpenMP : DiagGroup<"openmp", [
11271127
]>;
11281128

11291129
// SYCL warnings
1130-
def SyclStrict : DiagGroup<"sycl-strict">;
1130+
def Sycl2017Compat : DiagGroup<"sycl-2017-compat">;
1131+
def Sycl2020Compat : DiagGroup<"sycl-2020-compat">;
1132+
def SyclStrict : DiagGroup<"sycl-strict", [ Sycl2017Compat, Sycl2020Compat]>;
11311133
def SyclTarget : DiagGroup<"sycl-target">;
11321134

11331135
// Backend warnings.

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10974,6 +10974,12 @@ def warn_boolean_attribute_argument_is_not_valid: Warning<
1097410974
def err_sycl_attibute_cannot_be_applied_here
1097510975
: Error<"%0 attribute cannot be applied to a "
1097610976
"static function or function in an anonymous namespace">;
10977+
def warn_sycl_pass_by_value_deprecated
10978+
: Warning<"Passing kernel functions by value is deprecated in SYCL 2020">,
10979+
InGroup<Sycl2020Compat>;
10980+
def warn_sycl_pass_by_reference_future
10981+
: Warning<"Passing of kernel functions by reference is a SYCL 2020 extension">,
10982+
InGroup<Sycl2017Compat>;
1097710983
def warn_sycl_attibute_function_raw_ptr
1097810984
: Warning<"SYCL 1.2.1 specification does not allow %0 attribute applied "
1097910985
"to a function with a raw pointer "

clang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2587,6 +2587,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
25872587
if (const Arg *A = Args.getLastArg(OPT_sycl_std_EQ)) {
25882588
Opts.SYCLVersion = llvm::StringSwitch<unsigned>(A->getValue())
25892589
.Cases("2017", "1.2.1", "121", "sycl-1.2.1", 2017)
2590+
.Case("2020", 2020)
25902591
.Default(0U);
25912592

25922593
if (Opts.SYCLVersion == 0U) {

clang/lib/Sema/SemaSYCL.cpp

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -698,7 +698,38 @@ getKernelInvocationKind(FunctionDecl *KernelCallerFunc) {
698698
}
699699

700700
static const CXXRecordDecl *getKernelObjectType(FunctionDecl *Caller) {
701-
return (*Caller->param_begin())->getType()->getAsCXXRecordDecl();
701+
QualType KernelParamTy = (*Caller->param_begin())->getType();
702+
// In SYCL 2020 kernels are now passed by reference.
703+
if (KernelParamTy->isReferenceType())
704+
return KernelParamTy->getPointeeCXXRecordDecl();
705+
706+
// SYCL 1.2.1
707+
return KernelParamTy->getAsCXXRecordDecl();
708+
}
709+
710+
static void checkKernelAndCaller(Sema &SemaRef, FunctionDecl *Caller,
711+
const CXXRecordDecl *KernelObj) {
712+
// check captures
713+
if (KernelObj->isLambda()) {
714+
for (const LambdaCapture &LC : KernelObj->captures())
715+
if (LC.capturesThis() && LC.isImplicit())
716+
SemaRef.Diag(LC.getLocation(), diag::err_implicit_this_capture);
717+
}
718+
719+
// check that calling kernel conforms to spec
720+
assert(Caller->param_size() >= 1 && "missing kernel function argument.");
721+
QualType KernelParamTy = (*Caller->param_begin())->getType();
722+
if (KernelParamTy->isReferenceType()) {
723+
// passing by reference, so emit warning if not using SYCL 2020
724+
if (SemaRef.LangOpts.SYCLVersion < 2020)
725+
SemaRef.Diag(Caller->getLocation(),
726+
diag::warn_sycl_pass_by_reference_future);
727+
} else {
728+
// passing by value. emit warning if using SYCL 2020 or greater
729+
if (SemaRef.LangOpts.SYCLVersion > 2017)
730+
SemaRef.Diag(Caller->getLocation(),
731+
diag::warn_sycl_pass_by_value_deprecated);
732+
}
702733
}
703734

704735
/// Creates a kernel parameter descriptor
@@ -1913,11 +1944,8 @@ void Sema::ConstructOpenCLKernel(FunctionDecl *KernelCallerFunc,
19131944
constructKernelName(*this, KernelCallerFunc, MC);
19141945
StringRef KernelName(getLangOpts().SYCLUnnamedLambda ? StableName
19151946
: CalculatedName);
1916-
if (KernelObj->isLambda()) {
1917-
for (const LambdaCapture &LC : KernelObj->captures())
1918-
if (LC.capturesThis() && LC.isImplicit())
1919-
Diag(LC.getLocation(), diag::err_implicit_this_capture);
1920-
}
1947+
1948+
checkKernelAndCaller(*this, KernelCallerFunc, KernelObj);
19211949
SyclKernelFieldChecker checker(*this);
19221950
SyclKernelDeclCreator kernel_decl(
19231951
*this, checker, KernelName, KernelObj->getLocation(),

clang/test/CodeGenSYCL/Inputs/sycl.hpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -260,26 +260,26 @@ class spec_constant {
260260

261261
#define ATTR_SYCL_KERNEL __attribute__((sycl_kernel))
262262
template <typename KernelName = auto_name, typename KernelType>
263-
ATTR_SYCL_KERNEL void kernel_single_task(KernelType kernelFunc) {
263+
ATTR_SYCL_KERNEL void kernel_single_task(const KernelType &kernelFunc) {
264264
kernelFunc();
265265
}
266266

267267
template <typename KernelName, typename KernelType, int Dims>
268268
ATTR_SYCL_KERNEL void
269-
kernel_parallel_for(KernelType KernelFunc) {
269+
kernel_parallel_for(const KernelType &KernelFunc) {
270270
KernelFunc(id<Dims>());
271271
}
272272

273273
template <typename KernelName, typename KernelType, int Dims>
274274
ATTR_SYCL_KERNEL void
275-
kernel_parallel_for_work_group(KernelType KernelFunc) {
275+
kernel_parallel_for_work_group(const KernelType &KernelFunc) {
276276
KernelFunc(group<Dims>());
277277
}
278278

279279
class handler {
280280
public:
281281
template <typename KernelName = auto_name, typename KernelType, int Dims>
282-
void parallel_for(range<Dims> numWorkItems, KernelType kernelFunc) {
282+
void parallel_for(range<Dims> numWorkItems, const KernelType &kernelFunc) {
283283
using NameT = typename get_kernel_name_t<KernelName, KernelType>::name;
284284
#ifdef __SYCL_DEVICE_ONLY__
285285
kernel_parallel_for<NameT, KernelType, Dims>(kernelFunc);
@@ -289,7 +289,7 @@ class handler {
289289
}
290290

291291
template <typename KernelName = auto_name, typename KernelType, int Dims>
292-
void parallel_for_work_group(range<Dims> numWorkGroups, range<Dims> WorkGroupSize, KernelType kernelFunc) {
292+
void parallel_for_work_group(range<Dims> numWorkGroups, range<Dims> WorkGroupSize, const KernelType &kernelFunc) {
293293
using NameT = typename get_kernel_name_t<KernelName, KernelType>::name;
294294
#ifdef __SYCL_DEVICE_ONLY__
295295
kernel_parallel_for_work_group<NameT, KernelType, Dims>(kernelFunc);
@@ -300,7 +300,7 @@ class handler {
300300
}
301301

302302
template <typename KernelName = auto_name, typename KernelType>
303-
void single_task(KernelType kernelFunc) {
303+
void single_task(const KernelType &kernelFunc) {
304304
using NameT = typename get_kernel_name_t<KernelName, KernelType>::name;
305305
#ifdef __SYCL_DEVICE_ONLY__
306306
kernel_single_task<NameT>(kernelFunc);

clang/test/CodeGenSYCL/address-space-cond-op.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ S foo(bool cond, S &lhs, S rhs) {
2424
}
2525

2626
template <typename name, typename Func>
27-
__attribute__((sycl_kernel)) void kernel(Func kernelFunc) {
27+
__attribute__((sycl_kernel)) void kernel(const Func &kernelFunc) {
2828
kernelFunc();
2929
}
3030

clang/test/CodeGenSYCL/address-space-new.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,13 +110,11 @@ void test() {
110110
// CHECK: call spir_func void @{{.*}}bar{{.*}}(%struct.{{.*}}.HasX addrspace(4)* align 4 dereferenceable(4) %[[SECOND]])
111111
}
112112

113-
114113
template <typename name, typename Func>
115-
__attribute__((sycl_kernel)) void kernel_single_task(Func kernelFunc) {
114+
__attribute__((sycl_kernel)) void kernel_single_task(const Func &kernelFunc) {
116115
kernelFunc();
117116
}
118117

119-
120118
int main() {
121119
kernel_single_task<class fake_kernel>([]() { test(); });
122120
return 0;

clang/test/CodeGenSYCL/address-space-of-returns.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ A ret_agg() {
2929
// CHECK: define spir_func void @{{.*}}ret_agg{{.*}}(%struct.{{.*}}.A addrspace(4)* {{.*}} %agg.result)
3030

3131
template <typename name, typename Func>
32-
__attribute__((sycl_kernel)) void kernel_single_task(Func kernelFunc) {
32+
__attribute__((sycl_kernel)) void kernel_single_task(const Func &kernelFunc) {
3333
kernelFunc();
3434
}
3535

clang/test/CodeGenSYCL/address-space-parameter-conversions.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ void usages2() {
195195
}
196196

197197
template <typename name, typename Func>
198-
__attribute__((sycl_kernel)) void kernel_single_task(Func kernelFunc) {
198+
__attribute__((sycl_kernel)) void kernel_single_task(const Func &kernelFunc) {
199199
kernelFunc();
200200
}
201201
int main() {

clang/test/CodeGenSYCL/basic-kernel-wrapper.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#include "sycl.hpp"
77

88
template <typename name, typename Func>
9-
__attribute__((sycl_kernel)) void kernel(Func kernelFunc) {
9+
__attribute__((sycl_kernel)) void kernel(const Func &kernelFunc) {
1010
kernelFunc();
1111
}
1212

0 commit comments

Comments
 (0)