Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SYCL] disallow mutable lambdas #1785

Merged
merged 19 commits into from
Jul 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 3 additions & 1 deletion clang/include/clang/Basic/DiagnosticGroups.td
Original file line number Diff line number Diff line change
Expand Up @@ -1127,7 +1127,9 @@ def OpenMP : DiagGroup<"openmp", [
]>;

// SYCL warnings
def SyclStrict : DiagGroup<"sycl-strict">;
def Sycl2017Compat : DiagGroup<"sycl-2017-compat">;
def Sycl2020Compat : DiagGroup<"sycl-2020-compat">;
def SyclStrict : DiagGroup<"sycl-strict", [ Sycl2017Compat, Sycl2020Compat]>;
def SyclTarget : DiagGroup<"sycl-target">;

// Backend warnings.
Expand Down
6 changes: 6 additions & 0 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -10969,6 +10969,12 @@ def warn_boolean_attribute_argument_is_not_valid: Warning<
def err_sycl_attibute_cannot_be_applied_here
: Error<"%0 attribute cannot be applied to a "
"static function or function in an anonymous namespace">;
def warn_sycl_pass_by_value_deprecated
: Warning<"Passing kernel functions by value is deprecated in SYCL 2020">,
InGroup<Sycl2020Compat>;
def warn_sycl_pass_by_reference_future
: Warning<"Passing of kernel functions by reference is a SYCL 2020 extension">,
InGroup<Sycl2017Compat>;
def warn_sycl_attibute_function_raw_ptr
: Warning<"SYCL 1.2.1 specification does not allow %0 attribute applied "
"to a function with a raw pointer "
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2582,6 +2582,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
if (const Arg *A = Args.getLastArg(OPT_sycl_std_EQ)) {
Opts.SYCLVersion = llvm::StringSwitch<unsigned>(A->getValue())
.Cases("2017", "1.2.1", "121", "sycl-1.2.1", 2017)
.Case("2020", 2020)
.Default(0U);

if (Opts.SYCLVersion == 0U) {
Expand Down
40 changes: 34 additions & 6 deletions clang/lib/Sema/SemaSYCL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -729,7 +729,38 @@ getKernelInvocationKind(FunctionDecl *KernelCallerFunc) {
}

static const CXXRecordDecl *getKernelObjectType(FunctionDecl *Caller) {
return (*Caller->param_begin())->getType()->getAsCXXRecordDecl();
QualType KernelParamTy = (*Caller->param_begin())->getType();
erichkeane marked this conversation as resolved.
Show resolved Hide resolved
// In SYCL 2020 kernels are now passed by reference.
if (KernelParamTy->isReferenceType())
return KernelParamTy->getPointeeCXXRecordDecl();

// SYCL 1.2.1
return KernelParamTy->getAsCXXRecordDecl();
}

static void checkKernelAndCaller(Sema &SemaRef, FunctionDecl *Caller,
const CXXRecordDecl *KernelObj) {
// check captures
if (KernelObj->isLambda()) {
for (const LambdaCapture &LC : KernelObj->captures())
if (LC.capturesThis() && LC.isImplicit())
SemaRef.Diag(LC.getLocation(), diag::err_implicit_this_capture);
}

// check that calling kernel conforms to spec
assert(Caller->param_size() >= 1 && "missing kernel function argument.");
QualType KernelParamTy = (*Caller->param_begin())->getType();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably want an assert here that Caller->param_size() >=1.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

if (KernelParamTy->isReferenceType()) {
// passing by reference, so emit warning if not using SYCL 2020
if (SemaRef.LangOpts.SYCLVersion < 2020)
SemaRef.Diag(Caller->getLocation(),
diag::warn_sycl_pass_by_reference_future);
} else {
// passing by value. emit warning if using SYCL 2020 or greater
if (SemaRef.LangOpts.SYCLVersion > 2017)
SemaRef.Diag(Caller->getLocation(),
diag::warn_sycl_pass_by_value_deprecated);
}
}

/// Creates a kernel parameter descriptor
Expand Down Expand Up @@ -1943,11 +1974,8 @@ void Sema::ConstructOpenCLKernel(FunctionDecl *KernelCallerFunc,
constructKernelName(*this, KernelCallerFunc, MC);
StringRef KernelName(getLangOpts().SYCLUnnamedLambda ? StableName
: CalculatedName);
if (KernelObj->isLambda()) {
for (const LambdaCapture &LC : KernelObj->captures())
if (LC.capturesThis() && LC.isImplicit())
Diag(LC.getLocation(), diag::err_implicit_this_capture);
}

checkKernelAndCaller(*this, KernelCallerFunc, KernelObj);
SyclKernelFieldChecker checker(*this);
SyclKernelDeclCreator kernel_decl(
*this, checker, KernelName, KernelObj->getLocation(),
Expand Down
12 changes: 6 additions & 6 deletions clang/test/CodeGenSYCL/Inputs/sycl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -260,26 +260,26 @@ class spec_constant {

#define ATTR_SYCL_KERNEL __attribute__((sycl_kernel))
template <typename KernelName = auto_name, typename KernelType>
ATTR_SYCL_KERNEL void kernel_single_task(KernelType kernelFunc) {
ATTR_SYCL_KERNEL void kernel_single_task(const KernelType &kernelFunc) {
kernelFunc();
}

template <typename KernelName, typename KernelType, int Dims>
ATTR_SYCL_KERNEL void
kernel_parallel_for(KernelType KernelFunc) {
kernel_parallel_for(const KernelType &KernelFunc) {
KernelFunc(id<Dims>());
}

template <typename KernelName, typename KernelType, int Dims>
ATTR_SYCL_KERNEL void
kernel_parallel_for_work_group(KernelType KernelFunc) {
kernel_parallel_for_work_group(const KernelType &KernelFunc) {
KernelFunc(group<Dims>());
}

class handler {
public:
template <typename KernelName = auto_name, typename KernelType, int Dims>
void parallel_for(range<Dims> numWorkItems, KernelType kernelFunc) {
void parallel_for(range<Dims> numWorkItems, const KernelType &kernelFunc) {
using NameT = typename get_kernel_name_t<KernelName, KernelType>::name;
#ifdef __SYCL_DEVICE_ONLY__
kernel_parallel_for<NameT, KernelType, Dims>(kernelFunc);
Expand All @@ -289,7 +289,7 @@ class handler {
}

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

template <typename KernelName = auto_name, typename KernelType>
void single_task(KernelType kernelFunc) {
void single_task(const KernelType &kernelFunc) {
using NameT = typename get_kernel_name_t<KernelName, KernelType>::name;
#ifdef __SYCL_DEVICE_ONLY__
kernel_single_task<NameT>(kernelFunc);
Expand Down
2 changes: 1 addition & 1 deletion clang/test/CodeGenSYCL/address-space-cond-op.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ S foo(bool cond, S &lhs, S rhs) {
}

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

Expand Down
4 changes: 1 addition & 3 deletions clang/test/CodeGenSYCL/address-space-new.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,13 +110,11 @@ void test() {
// CHECK: call spir_func void @{{.*}}bar{{.*}}(%struct.{{.*}}.HasX addrspace(4)* align 4 dereferenceable(4) %[[SECOND]])
}


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


int main() {
kernel_single_task<class fake_kernel>([]() { test(); });
return 0;
Expand Down
2 changes: 1 addition & 1 deletion clang/test/CodeGenSYCL/address-space-of-returns.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ A ret_agg() {
// CHECK: define spir_func void @{{.*}}ret_agg{{.*}}(%struct.{{.*}}.A addrspace(4)* {{.*}} %agg.result)

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ void usages2() {
}

template <typename name, typename Func>
__attribute__((sycl_kernel)) void kernel_single_task(Func kernelFunc) {
__attribute__((sycl_kernel)) void kernel_single_task(const Func &kernelFunc) {
kernelFunc();
}
int main() {
Expand Down
2 changes: 1 addition & 1 deletion clang/test/CodeGenSYCL/basic-kernel-wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include "sycl.hpp"

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

Expand Down
2 changes: 1 addition & 1 deletion clang/test/CodeGenSYCL/const-wg-init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

template <typename KernelName, typename KernelType>
__attribute__((sycl_kernel)) void
kernel_parallel_for_work_group(KernelType KernelFunc) {
kernel_parallel_for_work_group(const KernelType &KernelFunc) {
cl::sycl::group<1> G;
KernelFunc(G);
}
Expand Down
2 changes: 1 addition & 1 deletion clang/test/CodeGenSYCL/debug-info-srcpos-kernel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#include <sycl.hpp>

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

Expand Down
2 changes: 1 addition & 1 deletion clang/test/CodeGenSYCL/device-functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ T bar(T arg) {
}

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

Expand Down
2 changes: 1 addition & 1 deletion clang/test/CodeGenSYCL/device-variables.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ static constexpr int my_array[1] = {42};
void foo(const test_type &) {}

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

Expand Down
2 changes: 1 addition & 1 deletion clang/test/CodeGenSYCL/emit-kernel-in-virtual-func.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// RUN: %clang_cc1 -fsycl -fsycl-is-device -triple spir64-unknown-unknown-sycldevice -emit-llvm %s -o - | FileCheck %s

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

Expand Down
4 changes: 2 additions & 2 deletions clang/test/CodeGenSYCL/emit-kernel-in-virtual-func2.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// RUN: %clang_cc1 -fsycl -fsycl-is-device -triple spir64-unknown-unknown-sycldevice -emit-llvm %s -o - | FileCheck %s

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

template <class TAR>
Expand Down
2 changes: 1 addition & 1 deletion clang/test/CodeGenSYCL/esimd_metadata1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
// 3. Proper module !spirv.Source metadata is generated

template <typename name, typename Func>
void kernel(Func f) __attribute__((sycl_kernel)) {
void kernel(const Func &f) __attribute__((sycl_kernel)) {
f();
}

Expand Down
2 changes: 1 addition & 1 deletion clang/test/CodeGenSYCL/fpga_pipes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class pipe {
};

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

Expand Down
2 changes: 1 addition & 1 deletion clang/test/CodeGenSYCL/inheritance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ struct base {
struct derived : base, second_base {
int a;

void operator()() {
void operator()() const {
}
};

Expand Down
2 changes: 1 addition & 1 deletion clang/test/CodeGenSYCL/inline_asm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
class kernel;

template <typename name, typename Func>
__attribute__((sycl_kernel)) void kernel_single_task(Func kernelFunc) {
__attribute__((sycl_kernel)) void kernel_single_task(const Func &kernelFunc) {
// CHECK: %[[ARRAY_A:[0-9a-z]+]] = alloca [100 x i32], align 4
// CHECK: %[[IDX:.*]] = getelementptr inbounds [100 x i32], [100 x i32]* %[[ARRAY_A]], i64 0, i64 0
int a[100], i = 0;
Expand Down
2 changes: 1 addition & 1 deletion clang/test/CodeGenSYCL/inlining.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// RUN: %clang_cc1 -fsycl -fsycl-is-device -triple spir64-unknown-unknown-sycldevice %s -S -emit-llvm -o - | FileCheck %s

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

Expand Down
2 changes: 1 addition & 1 deletion clang/test/CodeGenSYCL/int_header1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
#include "sycl.hpp"

template <typename KernelName, typename KernelType>
__attribute__((sycl_kernel)) void kernel_single_task(KernelType kernelFunc) {
__attribute__((sycl_kernel)) void kernel_single_task(const KernelType &kernelFunc) {
kernelFunc();
}

Expand Down
2 changes: 1 addition & 1 deletion clang/test/CodeGenSYCL/int_header_inline_ns.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#include "sycl.hpp"

template <typename KernelName, typename KernelType>
__attribute__((sycl_kernel)) void kernel_single_task(KernelType kernelFunc) {
__attribute__((sycl_kernel)) void kernel_single_task(const KernelType &kernelFunc) {
kernelFunc();
}

Expand Down
2 changes: 1 addition & 1 deletion clang/test/CodeGenSYCL/integration_header.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
#include "sycl.hpp"

template <typename KernelName, typename KernelType>
__attribute__((sycl_kernel)) void kernel_single_task(KernelType kernelFunc) {
__attribute__((sycl_kernel)) void kernel_single_task(const KernelType &kernelFunc) {
kernelFunc();
}
struct x {};
Expand Down
2 changes: 1 addition & 1 deletion clang/test/CodeGenSYCL/intel-fpga-ivdep-array.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ void ivdep_struct() {
}

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ void ivdep_embedded_multiple_dimensions() {
}

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

Expand Down
2 changes: 1 addition & 1 deletion clang/test/CodeGenSYCL/intel-fpga-ivdep-global.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ void ivdep_conflicting_safelen() {
}

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

Expand Down
2 changes: 1 addition & 1 deletion clang/test/CodeGenSYCL/intel-fpga-local.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ void field_addrspace_cast() {
}

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

Expand Down
2 changes: 1 addition & 1 deletion clang/test/CodeGenSYCL/intel-fpga-loops.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ void speculated_iterations() {
}

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

Expand Down
2 changes: 1 addition & 1 deletion clang/test/CodeGenSYCL/intel-fpga-mem-builtin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ void foo(float *A, int *B, State *C, State &D) {
// CHECK-DAG: attributes [[ATT]] = { readnone }

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

Expand Down
4 changes: 2 additions & 2 deletions clang/test/CodeGenSYCL/intel-fpga-no-global-work-offset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

class Foo {
public:
[[intelfpga::no_global_work_offset(1)]] void operator()() {}
[[intelfpga::no_global_work_offset(1)]] void operator()() const {}
};

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

Expand Down
2 changes: 1 addition & 1 deletion clang/test/CodeGenSYCL/intel-fpga-reg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ void foo() {
}

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

Expand Down
Loading