Skip to content

Commit b986c30

Browse files
author
Erich Keane
committed
[SYCL] Start fully-qualifying our inline kernel names in forward declarations.
This has the ability to make a number easy-to-make mistakes no longer issues when using named kernels. This causes us to differentiate the inline-named kernels when they are in different namespaces, which will hopefully make running into duplicate-kernel-name issues more difficult.
1 parent d36ecab commit b986c30

10 files changed

+66
-34
lines changed

clang/lib/Sema/SemaSYCL.cpp

Lines changed: 49 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4383,17 +4383,32 @@ class SYCLFwdDeclEmitter
43834383
const DeclContext *DC = D->getDeclContext();
43844384

43854385
while (DC) {
4386-
const auto *NS = dyn_cast_or_null<NamespaceDecl>(DC);
4387-
4388-
if (!NS)
4389-
break;
4390-
4391-
++NamespaceCnt;
4392-
const StringRef NSInlinePrefix = NS->isInline() ? "inline " : "";
4393-
NSStr.insert(
4394-
0,
4395-
Twine(NSInlinePrefix + "namespace " + NS->getName() + " { ").str());
4396-
DC = NS->getDeclContext();
4386+
if (const auto *NS = dyn_cast<NamespaceDecl>(DC)) {
4387+
++NamespaceCnt;
4388+
const StringRef NSInlinePrefix = NS->isInline() ? "inline " : "";
4389+
NSStr.insert(
4390+
0,
4391+
Twine(NSInlinePrefix + "namespace " + NS->getName() + " { ").str());
4392+
DC = NS->getDeclContext();
4393+
} else {
4394+
// We should be able to handle a subset of the decl-context types to
4395+
// make our namespaces for forward declarations as specific as possible,
4396+
// so just skip them here. We can't use their names, since they would
4397+
// not be forward declarable, but we can try to make them as specific as
4398+
// possible.
4399+
// This permits things such as:
4400+
// namespace N1 { void foo() { kernel<class K>(...); }}
4401+
// and
4402+
// namespace N2 { void foo() { kernel<class K>(...); }}
4403+
// to co-exist, despite technically being against the SYCL rules.
4404+
// See SYCLKernelNameTypePrinter for the corresponding part that prints
4405+
// the kernel information for this type. These two must match.
4406+
if (isa<FunctionDecl, RecordDecl, LinkageSpecDecl>(DC)) {
4407+
DC = cast<Decl>(DC)->getDeclContext();
4408+
} else {
4409+
break;
4410+
}
4411+
}
43974412
}
43984413
OS << NSStr;
43994414
if (NamespaceCnt > 0)
@@ -4568,6 +4583,19 @@ class SYCLKernelNameTypePrinter
45684583
Quals.print(OS, Policy, /*appendSpaceIfNotEmpty*/ true);
45694584
}
45704585

4586+
// Use recursion to print the namespace-qualified name for the purposes of the
4587+
// canonical sycl example of a type being created in the kernel call.
4588+
void PrintNamespaceScopes(const DeclContext *DC) {
4589+
if (isa<NamespaceDecl, FunctionDecl, RecordDecl, LinkageSpecDecl>(DC)) {
4590+
const auto *D = cast<Decl>(DC);
4591+
PrintNamespaceScopes(D->getDeclContext());
4592+
4593+
const auto *NS = dyn_cast<NamespaceDecl>(DC);
4594+
if (NS && !NS->isAnonymousNamespace())
4595+
OS << NS->getName() << "::";
4596+
}
4597+
}
4598+
45714599
public:
45724600
SYCLKernelNameTypePrinter(raw_ostream &OS, PrintingPolicy &Policy)
45734601
: OS(OS), Policy(Policy) {}
@@ -4606,12 +4634,16 @@ class SYCLKernelNameTypePrinter
46064634

46074635
return;
46084636
}
4609-
// TODO: Next part of code results in printing of "class" keyword before
4610-
// class name in case if kernel name doesn't belong to some namespace. It
4611-
// seems if we don't print it, the integration header still represents valid
4612-
// c++ code. Probably we don't need to print it at all.
4613-
if (RD->getDeclContext()->isFunctionOrMethod()) {
4614-
OS << QualType::getAsString(T, Qualifiers(), Policy);
4637+
4638+
// Handle the canonical sycl example where the type is created for the first
4639+
// time in the kernel naming. We want to qualify this as fully as we can,
4640+
// but not in a way that won't be forward declarable. See
4641+
// SYCLFwdDeclEmitter::printForwardDecl for the corresponding list for
4642+
// printing the forward declaration, these two must match.
4643+
DeclContext *DC = RD->getDeclContext();
4644+
if (isa<FunctionDecl, RecordDecl, LinkageSpecDecl>(DC)) {
4645+
PrintNamespaceScopes(DC);
4646+
RD->printName(OS);
46154647
return;
46164648
}
46174649

clang/test/CodeGenSYCL/int_header1.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
// CHECK-NEXT:struct IsThisValid;
1616
// CHECK-NEXT:}}
1717

18-
// CHECK:template <> struct KernelInfo<class KernelName> {
18+
// CHECK:template <> struct KernelInfo<KernelName> {
1919
// CHECK:template <> struct KernelInfo<::nm1::nm2::KernelName0> {
2020
// CHECK:template <> struct KernelInfo<::nm1::KernelName1> {
2121
// CHECK:template <> struct KernelInfo<::nm1::KernelName3<::nm1::nm2::KernelName0>> {

clang/test/CodeGenSYCL/int_header_esimd.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ void testA() {
1919
h.single_task<class KernelA>([=]() __attribute__((sycl_explicit_simd)){});
2020
});
2121
}
22-
// CHECK-LABEL: template <> struct KernelInfo<class KernelA> {
22+
// CHECK-LABEL: template <> struct KernelInfo<KernelA> {
2323
// CHECK: static constexpr bool isESIMD() { return 1; }
2424

2525
// -- ESIMD Functor object kernel.
@@ -46,7 +46,7 @@ void testNA() {
4646
h.single_task<class KernelNA>([=]() {});
4747
});
4848
}
49-
// CHECK-LABEL: template <> struct KernelInfo<class KernelNA> {
49+
// CHECK-LABEL: template <> struct KernelInfo<KernelNA> {
5050
// CHECK: static constexpr bool isESIMD() { return 0; }
5151

5252
// -- Non-ESIMD Functor object kernel.

clang/test/CodeGenSYCL/integration_header.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
// CHECK-EMPTY:
5151
// CHECK-NEXT: };
5252
//
53-
// CHECK: template <> struct KernelInfo<class first_kernel> {
53+
// CHECK: template <> struct KernelInfo<first_kernel> {
5454
// CHECK: template <> struct KernelInfo<::second_namespace::second_kernel<char>> {
5555
// CHECK: template <> struct KernelInfo<::fourth_kernel<::template_arg_ns::namespaced_arg<1>>> {
5656

clang/test/CodeGenSYCL/kernel-param-acc-array-ih.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
// CHECK-EMPTY:
2626
// CHECK-NEXT: };
2727

28-
// CHECK: template <> struct KernelInfo<class kernel_A> {
28+
// CHECK: template <> struct KernelInfo<kernel_A> {
2929

3030
#include "Inputs/sycl.hpp"
3131

clang/test/CodeGenSYCL/kernel-param-member-acc-array-ih.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
// CHECK-EMPTY:
2626
// CHECK-NEXT: };
2727

28-
// CHECK: template <> struct KernelInfo<class kernel_C> {
28+
// CHECK: template <> struct KernelInfo<kernel_C> {
2929

3030
#include "Inputs/sycl.hpp"
3131

clang/test/CodeGenSYCL/kernel-param-pod-array-ih.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@
3131
// CHECK-EMPTY:
3232
// CHECK-NEXT: };
3333

34-
// CHECK: template <> struct KernelInfo<class kernel_B> {
35-
// CHECK: template <> struct KernelInfo<class kernel_C> {
36-
// CHECK: template <> struct KernelInfo<class kernel_D> {
34+
// CHECK: template <> struct KernelInfo<kernel_B> {
35+
// CHECK: template <> struct KernelInfo<kernel_C> {
36+
// CHECK: template <> struct KernelInfo<kernel_D> {
3737

3838
#include "Inputs/sycl.hpp"
3939

clang/test/CodeGenSYCL/parallel_for_this_item.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
// CHECK-NEXT: "_ZTSZZ4mainENKUlRN2cl4sycl7handlerEE_clES2_E3BEE"
1919
// CHECK-NEXT: };
2020

21-
// CHECK:template <> struct KernelInfo<class GNU> {
21+
// CHECK:template <> struct KernelInfo<GNU> {
2222
// CHECK-NEXT: __SYCL_DLL_LOCAL
2323
// CHECK-NEXT: static constexpr const char* getName() { return "_ZTSZZ4mainENKUlRN2cl4sycl7handlerEE_clES2_E3GNU"; }
2424
// CHECK-NEXT: __SYCL_DLL_LOCAL
@@ -34,7 +34,7 @@
3434
// CHECK-NEXT: __SYCL_DLL_LOCAL
3535
// CHECK-NEXT: static constexpr bool callsAnyThisFreeFunction() { return 0; }
3636
// CHECK-NEXT:};
37-
// CHECK-NEXT:template <> struct KernelInfo<class EMU> {
37+
// CHECK-NEXT:template <> struct KernelInfo<EMU> {
3838
// CHECK-NEXT: __SYCL_DLL_LOCAL
3939
// CHECK-NEXT: static constexpr const char* getName() { return "_ZTSZZ4mainENKUlRN2cl4sycl7handlerEE_clES2_E3EMU"; }
4040
// CHECK-NEXT: __SYCL_DLL_LOCAL
@@ -50,7 +50,7 @@
5050
// CHECK-NEXT: __SYCL_DLL_LOCAL
5151
// CHECK-NEXT: static constexpr bool callsAnyThisFreeFunction() { return 1; }
5252
// CHECK-NEXT:};
53-
// CHECK-NEXT:template <> struct KernelInfo<class OWL> {
53+
// CHECK-NEXT:template <> struct KernelInfo<OWL> {
5454
// CHECK-NEXT: __SYCL_DLL_LOCAL
5555
// CHECK-NEXT: static constexpr const char* getName() { return "_ZTSZZ4mainENKUlRN2cl4sycl7handlerEE_clES2_E3OWL"; }
5656
// CHECK-NEXT: __SYCL_DLL_LOCAL
@@ -66,7 +66,7 @@
6666
// CHECK-NEXT: __SYCL_DLL_LOCAL
6767
// CHECK-NEXT: static constexpr bool callsAnyThisFreeFunction() { return 0; }
6868
// CHECK-NEXT:};
69-
// CHECK-NEXT:template <> struct KernelInfo<class RAT> {
69+
// CHECK-NEXT:template <> struct KernelInfo<RAT> {
7070
// CHECK-NEXT: __SYCL_DLL_LOCAL
7171
// CHECK-NEXT: static constexpr const char* getName() { return "_ZTSZZ4mainENKUlRN2cl4sycl7handlerEE_clES2_E3RAT"; }
7272
// CHECK-NEXT: __SYCL_DLL_LOCAL
@@ -82,7 +82,7 @@
8282
// CHECK-NEXT: __SYCL_DLL_LOCAL
8383
// CHECK-NEXT: static constexpr bool callsAnyThisFreeFunction() { return 1; }
8484
// CHECK-NEXT:};
85-
// CHECK-NEXT:template <> struct KernelInfo<class FOX> {
85+
// CHECK-NEXT:template <> struct KernelInfo<FOX> {
8686
// CHECK-NEXT: __SYCL_DLL_LOCAL
8787
// CHECK-NEXT: static constexpr const char* getName() { return "_ZTSZZ4mainENKUlRN2cl4sycl7handlerEE_clES2_E3FOX"; }
8888
// CHECK-NEXT: __SYCL_DLL_LOCAL
@@ -98,7 +98,7 @@
9898
// CHECK-NEXT: __SYCL_DLL_LOCAL
9999
// CHECK-NEXT: static constexpr bool callsAnyThisFreeFunction() { return 1; }
100100
// CHECK-NEXT:};
101-
// CHECK-NEXT:template <> struct KernelInfo<class BEE> {
101+
// CHECK-NEXT:template <> struct KernelInfo<BEE> {
102102
// CHECK-NEXT: __SYCL_DLL_LOCAL
103103
// CHECK-NEXT: static constexpr const char* getName() { return "_ZTSZZ4mainENKUlRN2cl4sycl7handlerEE_clES2_E3BEE"; }
104104
// CHECK-NEXT: __SYCL_DLL_LOCAL

clang/test/CodeGenSYCL/union-kernel-param-ih.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
// CHECK-EMPTY:
2525
// CHECK-NEXT:};
2626

27-
// CHECK: template <> struct KernelInfo<class kernel_A> {
27+
// CHECK: template <> struct KernelInfo<kernel_A> {
2828

2929
union MyUnion {
3030
int FldInt;

clang/test/CodeGenSYCL/wrapped-accessor.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
// CHECK-EMPTY:
2222
// CHECK-NEXT: };
2323

24-
// CHECK: template <> struct KernelInfo<class wrapped_access> {
24+
// CHECK: template <> struct KernelInfo<wrapped_access> {
2525

2626
#include "Inputs/sycl.hpp"
2727

0 commit comments

Comments
 (0)