Skip to content

Commit 8a4fc3f

Browse files
committed
Added support for passing arguments to sycl_kernel_launch as xvalues.
1 parent 5b18f99 commit 8a4fc3f

File tree

3 files changed

+69
-31
lines changed

3 files changed

+69
-31
lines changed

clang/lib/Sema/SemaSYCL.cpp

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -456,8 +456,9 @@ namespace {
456456

457457
// Constructs the arguments to be passed for the SYCL kernel launch call.
458458
// The first argument is a string literal that contains the SYCL kernel
459-
// name. The remaining arguments are the parameters of 'FD'.
460-
void BuildSYCLKernelLaunchCallArgs(Sema &SemaRef, FunctionDecl *FD,
459+
// name. The remaining arguments are the parameters of 'FD' passed as
460+
// move-elligible xvalues. Returns true on error and false otherwise.
461+
bool BuildSYCLKernelLaunchCallArgs(Sema &SemaRef, FunctionDecl *FD,
461462
const SYCLKernelInfo *SKI,
462463
SmallVectorImpl<Expr *> &Args,
463464
SourceLocation Loc) {
@@ -478,11 +479,23 @@ void BuildSYCLKernelLaunchCallArgs(Sema &SemaRef, FunctionDecl *FD,
478479
/*Pascal*/ false, KernelNameArrayTy, Loc);
479480
Args.push_back(KernelNameExpr);
480481

482+
// Forward all parameters of 'FD' to the SYCL kernel launch function as if
483+
// by std::move().
481484
for (ParmVarDecl *PVD : FD->parameters()) {
482485
QualType ParamType = PVD->getOriginalType().getNonReferenceType();
483-
Expr *DRE = SemaRef.BuildDeclRefExpr(PVD, ParamType, VK_LValue, Loc);
484-
Args.push_back(DRE);
486+
ExprResult E = SemaRef.BuildDeclRefExpr(PVD, ParamType, VK_LValue, Loc);
487+
if (E.isInvalid())
488+
return true;
489+
if (!PVD->getType()->isLValueReferenceType())
490+
E = ImplicitCastExpr::Create(SemaRef.Context, E.get()->getType(), CK_NoOp,
491+
E.get(), nullptr, VK_XValue,
492+
FPOptionsOverride());
493+
if (E.isInvalid())
494+
return true;
495+
Args.push_back(E.get());
485496
}
497+
498+
return false;
486499
}
487500

488501
// Constructs the SYCL kernel launch call.
@@ -494,7 +507,8 @@ StmtResult BuildSYCLKernelLaunchCallStmt(Sema &SemaRef, FunctionDecl *FD,
494507
// IdExpr may be null if name lookup failed.
495508
if (IdExpr) {
496509
llvm::SmallVector<Expr *, 12> Args;
497-
BuildSYCLKernelLaunchCallArgs(SemaRef, FD, SKI, Args, Loc);
510+
if (BuildSYCLKernelLaunchCallArgs(SemaRef, FD, SKI, Args, Loc))
511+
return StmtError();
498512
ExprResult LaunchResult =
499513
SemaRef.BuildCallExpr(SemaRef.getCurScope(), IdExpr, Loc, Args, Loc);
500514
if (LaunchResult.isInvalid())

clang/test/ASTSYCL/ast-dump-sycl-kernel-call-stmt.cpp

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,8 @@ void skep2<KN<2>>(K<2>);
9292
// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} 'void (const char *, K<2>)' lvalue Function {{.*}} 'sycl_kernel_launch' {{.*}}
9393
// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} 'const char *' <ArrayToPointerDecay>
9494
// CHECK-NEXT: | | | | `-StringLiteral {{.*}} 'const char[14]' lvalue "_ZTS2KNILi2EE"
95-
// CHECK-NEXT: | | | `-CXXConstructExpr {{.*}} 'K<2>' 'void (const K<2> &) noexcept'
96-
// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <NoOp>
95+
// CHECK-NEXT: | | | `-CXXConstructExpr {{.*}} 'K<2>' 'void (K<2> &&) noexcept'
96+
// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} 'K<2>' xvalue <NoOp>
9797
// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} 'K<2>' lvalue ParmVar {{.*}} 'k' 'K<2>'
9898
// CHECK-NEXT: | | `-OutlinedFunctionDecl {{.*}}
9999
// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} implicit used k 'K<2>'
@@ -148,8 +148,8 @@ void skep3<KN<3>>(K<3> k) {
148148
// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} 'void (const char *, K<3>)' lvalue Function {{.*}} 'sycl_kernel_launch' 'void (const char *, K<3>)' {{.*}}
149149
// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} 'const char *' <ArrayToPointerDecay>
150150
// CHECK-NEXT: | | | | `-StringLiteral {{.*}} 'const char[14]' lvalue "_ZTS2KNILi3EE"
151-
// CHECK-NEXT: | | | `-CXXConstructExpr {{.*}} 'K<3>' 'void (const K<3> &) noexcept'
152-
// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} 'const K<3>' lvalue <NoOp>
151+
// CHECK-NEXT: | | | `-CXXConstructExpr {{.*}} 'K<3>' 'void (K<3> &&) noexcept'
152+
// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} 'K<3>' xvalue <NoOp>
153153
// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} 'K<3>' lvalue ParmVar {{.*}} 'k' 'K<3>'
154154
// CHECK-NEXT: | | `-OutlinedFunctionDecl {{.*}}
155155
// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} implicit used k 'K<3>'
@@ -186,13 +186,15 @@ void skep4(K<4> k, int p1, int p2) {
186186
// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} 'void (const char *, K<4>, int, int)' lvalue Function {{.*}} 'sycl_kernel_launch' 'void (const char *, K<4>, int, int)' {{.*}}
187187
// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} 'const char *' <ArrayToPointerDecay>
188188
// CHECK-NEXT: | | | | `-StringLiteral {{.*}} 'const char[14]' lvalue "_ZTS2KNILi4EE"
189-
// CHECK-NEXT: | | | |-CXXConstructExpr {{.*}} 'K<4>' 'void (const K<4> &) noexcept'
190-
// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} 'const K<4>' lvalue <NoOp>
189+
// CHECK-NEXT: | | | |-CXXConstructExpr {{.*}} 'K<4>' 'void (K<4> &&) noexcept'
190+
// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} 'K<4>' xvalue <NoOp>
191191
// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} 'K<4>' lvalue ParmVar {{.*}} 'k' 'K<4>'
192192
// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} 'int' <LValueToRValue>
193-
// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'p1' 'int'
193+
// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} 'int' xvalue <NoOp>
194+
// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'p1' 'int'
194195
// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} 'int' <LValueToRValue>
195-
// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'p2' 'int'
196+
// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} 'int' xvalue <NoOp>
197+
// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'p2' 'int'
196198
// CHECK-NEXT: | | `-OutlinedFunctionDecl {{.*}}
197199
// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} implicit used k 'K<4>'
198200
// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} implicit used p1 'int'
@@ -230,16 +232,20 @@ void skep5(int unused1, K<5> k, int unused2, int p, int unused3) {
230232
// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} 'const char *' <ArrayToPointerDecay>
231233
// CHECK-NEXT: | | | | `-StringLiteral {{.*}} 'const char[14]' lvalue "_ZTS2KNILi5EE"
232234
// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} 'int' <LValueToRValue>
233-
// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'unused1' 'int'
234-
// CHECK-NEXT: | | | |-CXXConstructExpr {{.*}} 'K<5>' 'void (const K<5> &) noexcept'
235-
// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} 'const K<5>' lvalue <NoOp>
235+
// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} 'int' xvalue <NoOp>
236+
// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'unused1' 'int'
237+
// CHECK-NEXT: | | | |-CXXConstructExpr {{.*}} 'K<5>' 'void (K<5> &&) noexcept'
238+
// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} 'K<5>' xvalue <NoOp>
236239
// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} 'K<5>' lvalue ParmVar {{.*}} 'k' 'K<5>'
237240
// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} 'int' <LValueToRValue>
238-
// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'unused2' 'int'
241+
// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} 'int' xvalue <NoOp>
242+
// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'unused2' 'int'
239243
// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} 'int' <LValueToRValue>
240-
// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'p' 'int'
244+
// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} 'int' xvalue <NoOp>
245+
// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'p' 'int'
241246
// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} 'int' <LValueToRValue>
242-
// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'unused3' 'int'
247+
// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} 'int' xvalue <NoOp>
248+
// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'unused3' 'int'
243249
// CHECK-NEXT: | | `-OutlinedFunctionDecl {{.*}}
244250
// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} implicit unused1 'int'
245251
// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} implicit used k 'K<5>'
@@ -332,8 +338,8 @@ void skep7(S7 k) {
332338
// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} 'void (const char *, S7)' lvalue Function {{.*}} 'sycl_kernel_launch' 'void (const char *, S7)' {{.*}}
333339
// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} 'const char *' <ArrayToPointerDecay>
334340
// CHECK-NEXT: | | | | `-StringLiteral {{.*}} 'const char[14]' lvalue "_ZTS2KNILi7EE"
335-
// CHECK-NEXT: | | | `-CXXConstructExpr {{.*}} 'S7' 'void (const S7 &) noexcept'
336-
// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} 'const S7' lvalue <NoOp>
341+
// CHECK-NEXT: | | | `-CXXConstructExpr {{.*}} 'S7' 'void (S7 &&) noexcept'
342+
// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} 'S7' xvalue <NoOp>
337343
// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} 'S7' lvalue ParmVar {{.*}} 'k' 'S7'
338344
// CHECK-NEXT: | | `-OutlinedFunctionDecl {{.*}}
339345
// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} implicit used k 'S7'
@@ -366,8 +372,8 @@ void skep8(S8 k) {
366372
// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} 'void (const char *, S8)' lvalue Function {{.*}} 'sycl_kernel_launch' 'void (const char *, S8)' {{.*}}
367373
// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} 'const char *' <ArrayToPointerDecay>
368374
// CHECK-NEXT: | | | | `-StringLiteral {{.*}} 'const char[12]' lvalue "_ZTS6\316\264\317\204\317\207"
369-
// CHECK-NEXT: | | | `-CXXConstructExpr {{.*}} 'S8' 'void (const S8 &) noexcept'
370-
// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} 'const S8' lvalue <NoOp>
375+
// CHECK-NEXT: | | | `-CXXConstructExpr {{.*}} 'S8' 'void (S8 &&) noexcept'
376+
// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} 'S8' xvalue <NoOp>
371377
// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} 'S8' lvalue ParmVar {{.*}} 'k' 'S8'
372378
// CHECK: | | `-OutlinedFunctionDecl {{.*}}
373379
// CHECK: | `-SYCLKernelEntryPointAttr {{.*}}
@@ -429,12 +435,14 @@ void foo() {
429435
// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} 'const char *' <ArrayToPointerDecay>
430436
// CHECK-NEXT: | | | | | `-StringLiteral {{.*}} 'const char[14]' lvalue "_ZTS2KNILi9EE"
431437
// CHECK-NEXT: | | | | |-CXXConstructExpr {{.*}}
432-
// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} lvalue <NoOp>
438+
// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} xvalue <NoOp>
433439
// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} lvalue ParmVar {{.*}} 'k' {{.*}}
434440
// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} 'int' <LValueToRValue>
435-
// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'a' 'int'
441+
// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} 'int' xvalue <NoOp>
442+
// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'a' 'int'
436443
// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} 'int' <LValueToRValue>
437-
// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'b' 'int'
444+
// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} 'int' xvalue <NoOp>
445+
// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'b' 'int'
438446
// CHECK-NEXT: | | | `-OutlinedFunctionDecl {{.*}}
439447
// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} implicit used k {{.*}}
440448
// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} implicit used a 'int'

clang/test/SemaSYCL/sycl-kernel-launch.cpp

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,21 @@ namespace ok10 {
172172
};
173173
}
174174

175-
// sycl_kernel_launch with forward reference parameters.
175+
// sycl_kernel_launch with non-reference parameters.
176176
namespace ok11 {
177+
template<typename KN, typename... Ts>
178+
void sycl_kernel_launch(const char *, Ts...);
179+
struct move_only {
180+
move_only(move_only&&) = default;
181+
};
182+
[[clang::sycl_kernel_entry_point(KN<11>)]]
183+
void skep(KT<11> k, move_only) {
184+
k();
185+
}
186+
}
187+
188+
// sycl_kernel_launch with forward reference parameters.
189+
namespace ok12 {
177190
template<typename KN, typename... Ts>
178191
void sycl_kernel_launch(const char *, Ts &&...);
179192
struct non_copyable {
@@ -182,8 +195,11 @@ namespace ok11 {
182195
struct non_moveable {
183196
non_moveable(non_moveable&&) = delete;
184197
};
185-
[[clang::sycl_kernel_entry_point(KN<11>)]]
186-
void skep(KT<11> k, non_copyable, non_moveable) {
198+
struct move_only {
199+
move_only(move_only&&) = default;
200+
};
201+
[[clang::sycl_kernel_entry_point(KN<12>)]]
202+
void skep(KT<12> k, non_copyable, non_moveable, move_only) {
187203
k();
188204
}
189205
}
@@ -437,10 +453,10 @@ namespace bad14 {
437453
k();
438454
}
439455
struct non_moveable {
440-
// expected-note@+1 {{copy constructor is implicitly deleted because 'non_moveable' has a user-declared move constructor}}
456+
// expected-note@+1 {{'non_moveable' has been explicitly marked deleted here}}
441457
non_moveable(non_moveable&&) = delete;
442458
};
443-
// expected-error@+2 {{call to implicitly-deleted copy constructor of 'bad14::non_moveable'}}
459+
// expected-error@+2 {{call to deleted constructor of 'bad14::non_moveable'}}
444460
[[clang::sycl_kernel_entry_point(BADKN<14,1>)]]
445461
void skep(BADKT<14,1> k, non_moveable) {
446462
k();

0 commit comments

Comments
 (0)