Skip to content

Commit 9e2f92e

Browse files
authored
[SYCL] Add clang implementation for accessor property no_alias (#3452)
no_alias is a compile-time-constant accessor property. It exists in cl::sycl::ONEAPI::property scope. When applied the LLVM IR should contain the noalias parameter attribute on the kernel argument corresponding to that accessor. This patch uses clang's RestrictAttr to emit `noalias` i.e., llvm::Attribute::NoAlias.
1 parent bc21ab2 commit 9e2f92e

File tree

4 files changed

+71
-1
lines changed

4 files changed

+71
-1
lines changed

clang/lib/CodeGen/CGCall.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2771,7 +2771,8 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
27712771
if (Arg->getType().isRestrictQualified() ||
27722772
(CurCodeDecl &&
27732773
CurCodeDecl->hasAttr<SYCLIntelKernelArgsRestrictAttr>() &&
2774-
Arg->getType()->isPointerType()))
2774+
Arg->getType()->isPointerType()) ||
2775+
(Arg->hasAttr<RestrictAttr>() && Arg->getType()->isPointerType()))
27752776
AI->addAttr(llvm::Attribute::NoAlias);
27762777
}
27772778

clang/lib/Sema/SemaSYCL.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,10 @@ class Util {
101101
/// accessor_property_list class.
102102
static bool isAccessorPropertyListType(QualType Ty);
103103

104+
/// Checks whether given clang type is a full specialization of the SYCL
105+
/// no_alias class.
106+
static bool isSyclAccessorNoAliasPropertyType(QualType Ty);
107+
104108
/// Checks whether given clang type is a full specialization of the SYCL
105109
/// buffer_location class.
106110
static bool isSyclBufferLocationType(QualType Ty);
@@ -1758,11 +1762,19 @@ class SyclKernelDeclCreator : public SyclKernelFieldHandler {
17581762
for (TemplateArgument::pack_iterator Prop = TemplArg.pack_begin();
17591763
Prop != TemplArg.pack_end(); ++Prop) {
17601764
QualType PropTy = Prop->getAsType();
1765+
if (Util::isSyclAccessorNoAliasPropertyType(PropTy))
1766+
handleNoAliasProperty(Param, PropTy, Loc);
17611767
if (Util::isSyclBufferLocationType(PropTy))
17621768
handleBufferLocationProperty(Param, PropTy, Loc);
17631769
}
17641770
}
17651771

1772+
void handleNoAliasProperty(ParmVarDecl *Param, QualType PropTy,
1773+
SourceLocation Loc) {
1774+
ASTContext &Ctx = SemaRef.getASTContext();
1775+
Param->addAttr(RestrictAttr::CreateImplicit(Ctx, Loc));
1776+
}
1777+
17661778
// Obtain an integer value stored in a template parameter of buffer_location
17671779
// property to pass it to buffer_location kernel attribute
17681780
void handleBufferLocationProperty(ParmVarDecl *Param, QualType PropTy,
@@ -4415,6 +4427,18 @@ bool Util::isSyclKernelHandlerType(QualType Ty) {
44154427
return matchQualifiedTypeName(Ty, Scopes);
44164428
}
44174429

4430+
bool Util::isSyclAccessorNoAliasPropertyType(QualType Ty) {
4431+
std::array<DeclContextDesc, 6> Scopes = {
4432+
Util::DeclContextDesc{Decl::Kind::Namespace, "cl"},
4433+
Util::DeclContextDesc{Decl::Kind::Namespace, "sycl"},
4434+
Util::DeclContextDesc{Decl::Kind::Namespace, "ONEAPI"},
4435+
Util::DeclContextDesc{Decl::Kind::Namespace, "property"},
4436+
Util::DeclContextDesc{Decl::Kind::CXXRecord, "no_alias"},
4437+
Util::DeclContextDesc{Decl::Kind::ClassTemplateSpecialization,
4438+
"instance"}};
4439+
return matchQualifiedTypeName(Ty, Scopes);
4440+
}
4441+
44184442
bool Util::isSyclBufferLocationType(QualType Ty) {
44194443
std::array<DeclContextDesc, 6> Scopes = {
44204444
Util::MakeDeclContextDesc(Decl::Kind::Namespace, "cl"),

clang/test/CodeGenSYCL/Inputs/sycl.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,15 @@ struct buffer_location {
103103
} // namespace property
104104
} // namespace INTEL
105105

106+
namespace ONEAPI {
107+
namespace property {
108+
// Compile time known accessor property
109+
struct no_alias {
110+
template <bool> class instance {};
111+
};
112+
} // namespace property
113+
} // namespace ONEAPI
114+
106115
namespace ONEAPI {
107116
template <typename... properties>
108117
class accessor_property_list {};
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// RUN: %clang_cc1 -fsycl-is-device -triple spir64-unknown-unknown-sycldevice -emit-llvm %s -o - | FileCheck %s
2+
// check that noalias parameter attribute is emitted when no_alias accessor property is used
3+
// CHECK: define {{.*}}spir_kernel void @_ZTSZ4mainE16kernel_function1({{.*}} noalias {{.*}} %_arg_, {{.*}})
4+
5+
// check that noalias parameter attribute is NOT emitted when it is not used
6+
// CHECK: define {{.*}}spir_kernel void @_ZTSZ4mainE16kernel_function2{{.*}} !kernel_arg_buffer_location
7+
// CHECK-NOT: define {{.*}}spir_kernel void @_ZTSZ4mainE16kernel_function2({{.*}} noalias {{.*}}
8+
9+
#include "Inputs/sycl.hpp"
10+
11+
int main() {
12+
cl::sycl::accessor<int, 1, cl::sycl::access::mode::read_write,
13+
cl::sycl::access::target::global_buffer,
14+
cl::sycl::access::placeholder::false_t,
15+
cl::sycl::ONEAPI::accessor_property_list<
16+
cl::sycl::ONEAPI::property::no_alias::instance<true>>>
17+
accessorA;
18+
19+
cl::sycl::accessor<int, 1, cl::sycl::access::mode::read_write,
20+
cl::sycl::access::target::global_buffer,
21+
cl::sycl::access::placeholder::false_t,
22+
cl::sycl::ONEAPI::accessor_property_list<
23+
cl::sycl::INTEL::property::buffer_location::instance<1>>>
24+
accessorB;
25+
26+
cl::sycl::kernel_single_task<class kernel_function1>(
27+
[=]() {
28+
accessorA.use();
29+
});
30+
31+
cl::sycl::kernel_single_task<class kernel_function2>(
32+
[=]() {
33+
accessorB.use();
34+
});
35+
return 0;
36+
}

0 commit comments

Comments
 (0)