Skip to content

Commit e8b0872

Browse files
committed
Test changes and improved this_item call detection.
1 parent e8e7f74 commit e8b0872

File tree

5 files changed

+185
-67
lines changed

5 files changed

+185
-67
lines changed

clang/lib/Sema/SemaSYCL.cpp

Lines changed: 44 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,6 @@ class Util {
8080
/// stream class.
8181
static bool isSyclStreamType(const QualType &Ty);
8282

83-
/// Checks whether given clang type is a full specialization of the SYCL
84-
/// item class.
85-
static bool isSyclItemType(const QualType &Ty);
86-
8783
/// Checks whether given clang type is a full specialization of the SYCL
8884
/// half class.
8985
static bool isSyclHalfType(const QualType &Ty);
@@ -103,10 +99,23 @@ class Util {
10399
/// \param Tmpl whether the class is template instantiation or simple record
104100
static bool isSyclType(const QualType &Ty, StringRef Name, bool Tmpl = false);
105101

102+
/// Checks whether given function is a standard SYCL API function with given
103+
/// name.
104+
/// \param FD the function being checked.
105+
/// \param Name the function name to be checked against.
106+
static bool isSyclFunction(const FunctionDecl *FD, StringRef Name);
107+
106108
/// Checks whether given clang type is a full specialization of the SYCL
107109
/// specialization constant class.
108110
static bool isSyclSpecConstantType(const QualType &Ty);
109111

112+
// Checks declaration context hierarchy.
113+
/// \param DC the context of the item to be checked.
114+
/// \param Scopes the declaration scopes leading from the item context to the
115+
/// translation unit (excluding the latter)
116+
static bool matchContext(const DeclContext *DC,
117+
ArrayRef<Util::DeclContextDesc> Scopes);
118+
110119
/// Checks whether given clang type is declared in the given hierarchy of
111120
/// declaration contexts.
112121
/// \param Ty the clang type being checked
@@ -2736,9 +2745,8 @@ class SyclKernelIntHeaderCreator : public SyclKernelFieldHandler {
27362745
if (!Visited.insert(FD).second)
27372746
continue; // We've already seen this Decl
27382747

2739-
if (FD->isFunctionOrMethod() && FD->getIdentifier() &&
2740-
!FD->getName().empty() && "this_item" == FD->getName() &&
2741-
Util::isSyclItemType(FD->getReturnType())) {
2748+
// Check whether this call is to sycl::this_item().
2749+
if (Util::isSyclFunction(FD, "this_item")) {
27422750
Header.setCallsThisItem(true);
27432751
return;
27442752
}
@@ -4014,10 +4022,6 @@ bool Util::isSyclStreamType(const QualType &Ty) {
40144022
return isSyclType(Ty, "stream");
40154023
}
40164024

4017-
bool Util::isSyclItemType(const QualType &Ty) {
4018-
return isSyclType(Ty, "item", true /*Tmpl*/);
4019-
}
4020-
40214025
bool Util::isSyclHalfType(const QualType &Ty) {
40224026
const StringRef &Name = "half";
40234027
std::array<DeclContextDesc, 5> Scopes = {
@@ -4064,6 +4068,21 @@ bool Util::isSyclType(const QualType &Ty, StringRef Name, bool Tmpl) {
40644068
return matchQualifiedTypeName(Ty, Scopes);
40654069
}
40664070

4071+
bool Util::isSyclFunction(const FunctionDecl *FD, StringRef Name) {
4072+
if (!FD->isFunctionOrMethod() || !FD->getIdentifier() ||
4073+
FD->getName().empty() || Name != FD->getName())
4074+
return false;
4075+
4076+
const DeclContext *DC = FD->getDeclContext();
4077+
if (DC->isTranslationUnit())
4078+
return false;
4079+
4080+
std::array<DeclContextDesc, 2> Scopes = {
4081+
Util::DeclContextDesc{clang::Decl::Kind::Namespace, "cl"},
4082+
Util::DeclContextDesc{clang::Decl::Kind::Namespace, "sycl"}};
4083+
return matchContext(DC, Scopes);
4084+
}
4085+
40674086
bool Util::isAccessorPropertyListType(const QualType &Ty) {
40684087
const StringRef &Name = "accessor_property_list";
40694088
std::array<DeclContextDesc, 4> Scopes = {
@@ -4074,21 +4093,15 @@ bool Util::isAccessorPropertyListType(const QualType &Ty) {
40744093
return matchQualifiedTypeName(Ty, Scopes);
40754094
}
40764095

4077-
bool Util::matchQualifiedTypeName(const QualType &Ty,
4078-
ArrayRef<Util::DeclContextDesc> Scopes) {
4079-
// The idea: check the declaration context chain starting from the type
4096+
bool Util::matchContext(const DeclContext *Ctx,
4097+
ArrayRef<Util::DeclContextDesc> Scopes) {
4098+
// The idea: check the declaration context chain starting from the item
40804099
// itself. At each step check the context is of expected kind
40814100
// (namespace) and name.
4082-
const CXXRecordDecl *RecTy = Ty->getAsCXXRecordDecl();
4083-
4084-
if (!RecTy)
4085-
return false; // only classes/structs supported
4086-
const auto *Ctx = cast<DeclContext>(RecTy);
40874101
StringRef Name = "";
40884102

40894103
for (const auto &Scope : llvm::reverse(Scopes)) {
40904104
clang::Decl::Kind DK = Ctx->getDeclKind();
4091-
40924105
if (DK != Scope.first)
40934106
return false;
40944107

@@ -4102,11 +4115,21 @@ bool Util::matchQualifiedTypeName(const QualType &Ty,
41024115
Name = cast<NamespaceDecl>(Ctx)->getName();
41034116
break;
41044117
default:
4105-
llvm_unreachable("matchQualifiedTypeName: decl kind not supported");
4118+
llvm_unreachable("matchContext: decl kind not supported");
41064119
}
41074120
if (Name != Scope.second)
41084121
return false;
41094122
Ctx = Ctx->getParent();
41104123
}
41114124
return Ctx->isTranslationUnit();
41124125
}
4126+
4127+
bool Util::matchQualifiedTypeName(const QualType &Ty,
4128+
ArrayRef<Util::DeclContextDesc> Scopes) {
4129+
const CXXRecordDecl *RecTy = Ty->getAsCXXRecordDecl();
4130+
4131+
if (!RecTy)
4132+
return false; // only classes/structs supported
4133+
const auto *Ctx = cast<DeclContext>(RecTy);
4134+
return Util::matchContext(Ctx, Scopes);
4135+
}

clang/test/CodeGenSYCL/parallel_for_this_item.cpp

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,13 +80,33 @@ using namespace cl::sycl;
8080
SYCL_EXTERNAL item<1> g() { return this_item<1>(); }
8181
SYCL_EXTERNAL item<1> f() { return g(); }
8282

83+
// This is a similar-looking this_item function but not the real one.
84+
template <int Dims> item<Dims> this_item(int i) { return item<1>{i}; }
85+
86+
// This is a method named this_item but not the real one.
87+
class C {
88+
public:
89+
template <int Dims> item<Dims> this_item() { return item<1>{66}; };
90+
};
91+
8392
int main() {
8493
queue myQueue;
8594
myQueue.submit([&](::handler &cgh) {
86-
cgh.parallel_for<class GNU>(range<1>(1), [=](item<1> I) {});
95+
// This kernel does not call sycl::this_item
96+
cgh.parallel_for<class GNU>(range<1>(1),
97+
[=](item<1> I) { this_item<1>(55); });
98+
99+
// This kernel calls sycl::this_item
87100
cgh.parallel_for<class EMU>(range<1>(1),
88101
[=](::item<1> I) { this_item<1>(); });
89-
cgh.parallel_for<class OWL>(range<1>(1), [=](id<1> I) {});
102+
103+
// This kernel does not call sycl::this_item
104+
cgh.parallel_for<class OWL>(range<1>(1), [=](id<1> I) {
105+
class C c;
106+
c.this_item<1>();
107+
});
108+
109+
// This kernel calls sycl::this_item
90110
cgh.parallel_for<class RAT>(range<1>(1), [=](id<1> I) { f(); });
91111
});
92112

sycl/include/CL/sycl/handler.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -816,7 +816,7 @@ class __SYCL_EXPORT handler {
816816
};
817817

818818
range<Dims> AdjustedRange = NumWorkItems;
819-
AdjustedRange.set_range(NewValX);
819+
AdjustedRange.set_range_dim0(NewValX);
820820
#ifdef __SYCL_DEVICE_ONLY__
821821
kernel_parallel_for<NameWT, TransformedArgType>(Wrapper);
822822
#else

sycl/include/CL/sycl/range.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ template <int dimensions = 1> class range : public detail::array<dimensions> {
148148
friend class detail::Builder;
149149

150150
// Adjust the first dim of the range
151-
void set_range(const size_t dim0) { this->common_array[0] = dim0; }
151+
void set_range_dim0(const size_t dim0) { this->common_array[0] = dim0; }
152152
};
153153

154154
#ifdef __cpp_deduction_guides

0 commit comments

Comments
 (0)