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] Add clang implementation for accessor property no_alias #3452

Merged
merged 13 commits into from
Apr 9, 2021
3 changes: 2 additions & 1 deletion clang/lib/CodeGen/CGCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2771,7 +2771,8 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
if (Arg->getType().isRestrictQualified() ||
(CurCodeDecl &&
CurCodeDecl->hasAttr<SYCLIntelKernelArgsRestrictAttr>() &&
Arg->getType()->isPointerType()))
Arg->getType()->isPointerType()) ||
(Arg->hasAttr<RestrictAttr>() && Arg->getType()->isPointerType()))
AI->addAttr(llvm::Attribute::NoAlias);
}

Expand Down
24 changes: 24 additions & 0 deletions clang/lib/Sema/SemaSYCL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ class Util {
/// accessor_property_list class.
static bool isAccessorPropertyListType(const QualType &Ty);

/// Checks whether given clang type is a full specialization of the SYCL
/// no_alias class.
static bool isSyclAccessorNoAliasPropertyType(QualType Ty);

/// Checks whether given clang type is a full specialization of the SYCL
/// buffer_location class.
static bool isSyclBufferLocationType(const QualType &Ty);
Expand Down Expand Up @@ -1742,11 +1746,19 @@ class SyclKernelDeclCreator : public SyclKernelFieldHandler {
for (TemplateArgument::pack_iterator Prop = TemplArg.pack_begin();
Prop != TemplArg.pack_end(); ++Prop) {
QualType PropTy = Prop->getAsType();
if (Util::isSyclAccessorNoAliasPropertyType(PropTy))
handleNoAliasProperty(Param, PropTy, Loc);
if (Util::isSyclBufferLocationType(PropTy))
handleBufferLocationProperty(Param, PropTy, Loc);
}
}

void handleNoAliasProperty(ParmVarDecl *Param, QualType PropTy,
SourceLocation Loc) {
ASTContext &Ctx = SemaRef.getASTContext();
Param->addAttr(RestrictAttr::CreateImplicit(Ctx, Loc));
}

// Obtain an integer value stored in a template parameter of buffer_location
// property to pass it to buffer_location kernel attribute
void handleBufferLocationProperty(ParmVarDecl *Param, QualType PropTy,
Expand Down Expand Up @@ -4313,6 +4325,18 @@ bool Util::isSyclKernelHandlerType(const QualType &Ty) {
return matchQualifiedTypeName(Ty, Scopes);
}

bool Util::isSyclAccessorNoAliasPropertyType(QualType Ty) {
std::array<DeclContextDesc, 6> Scopes = {
Util::DeclContextDesc{Decl::Kind::Namespace, "cl"},
Util::DeclContextDesc{Decl::Kind::Namespace, "sycl"},
Util::DeclContextDesc{Decl::Kind::Namespace, "ONEAPI"},
Util::DeclContextDesc{Decl::Kind::Namespace, "property"},
Util::DeclContextDesc{Decl::Kind::CXXRecord, "no_alias"},
Util::DeclContextDesc{Decl::Kind::ClassTemplateSpecialization,
"instance"}};
return matchQualifiedTypeName(Ty, Scopes);
}

bool Util::isSyclBufferLocationType(const QualType &Ty) {
const StringRef &PropertyName = "buffer_location";
const StringRef &InstanceName = "instance";
Expand Down
9 changes: 9 additions & 0 deletions clang/test/CodeGenSYCL/Inputs/sycl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,15 @@ struct buffer_location {
} // namespace property
} // namespace INTEL

namespace ONEAPI {
namespace property {
// Compile time known accessor property
struct no_alias {
template <bool> class instance {};
};
} // namespace property
} // namespace ONEAPI

namespace ONEAPI {
template <typename... properties>
class accessor_property_list {};
Expand Down
19 changes: 19 additions & 0 deletions clang/test/CodeGenSYCL/accessor_no_alias_property.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// RUN: %clang_cc1 -fsycl-is-device -triple spir64-unknown-unknown-sycldevice -emit-llvm %s -o - | FileCheck %s

// CHECK: define {{.*}}spir_kernel void @_ZTSZ4mainE15kernel_function({{.*}} noalias {{.*}} %_arg_, {{.*}})

#include "Inputs/sycl.hpp"

int main() {
cl::sycl::accessor<int, 1, cl::sycl::access::mode::read_write,
cl::sycl::access::target::global_buffer,
cl::sycl::access::placeholder::false_t,
cl::sycl::ONEAPI::accessor_property_list<
cl::sycl::ONEAPI::property::no_alias::instance<true>>>
accessorA;
cl::sycl::kernel_single_task<class kernel_function>(
[=]() {
accessorA.use();
});
return 0;
}
7 changes: 3 additions & 4 deletions clang/test/CodeGenSYCL/disable_loop_pipelining.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ int main() {
return 0;
}

// CHECK: define dso_local spir_kernel void @"{{.*}}test_kernel1"() #0 !kernel_arg_buffer_location ![[NUM4:[0-9]+]] !disable_loop_pipelining ![[NUM5:[0-9]+]]
// CHECK: define dso_local spir_kernel void @"{{.*}}test_kernel2"() #0 !kernel_arg_buffer_location ![[NUM4]]
// CHECK: define dso_local spir_kernel void @"{{.*}}test_kernel3"() #0 !kernel_arg_buffer_location ![[NUM4]] !disable_loop_pipelining ![[NUM5]]
// CHECK: ![[NUM4]] = !{}
// CHECK: define dso_local spir_kernel void @"{{.*}}test_kernel1"() #0 {{.*}} !disable_loop_pipelining ![[NUM5:[0-9]+]]
// CHECK: define dso_local spir_kernel void @"{{.*}}test_kernel2"() #0 {{.*}}
// CHECK: define dso_local spir_kernel void @"{{.*}}test_kernel3"() #0 {{.*}} !disable_loop_pipelining ![[NUM5]]
// CHECK: ![[NUM5]] = !{i32 1}
9 changes: 4 additions & 5 deletions clang/test/CodeGenSYCL/initiation_interval.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,10 @@ int main() {
return 0;
}

// CHECK: define {{.*}}spir_kernel void @{{.*}}kernel_name1"() #0 !kernel_arg_buffer_location ![[NUM0:[0-9]+]] !initiation_interval ![[NUM1:[0-9]+]]
// CHECK: define {{.*}}spir_kernel void @{{.*}}kernel_name2"() #0 !kernel_arg_buffer_location ![[NUM0]] !initiation_interval ![[NUM42:[0-9]+]]
// CHECK: define {{.*}}spir_kernel void @{{.*}}kernel_name3"() #0 !kernel_arg_buffer_location ![[NUM0]] !initiation_interval ![[NUM2:[0-9]+]]
// CHECK: define {{.*}}spir_kernel void @{{.*}}kernel_name4"() #0 !kernel_arg_buffer_location ![[NUM0]]
// CHECK: ![[NUM0]] = !{}
// CHECK: define {{.*}}spir_kernel void @{{.*}}kernel_name1"() #0 {{.*}} !initiation_interval ![[NUM1:[0-9]+]]
// CHECK: define {{.*}}spir_kernel void @{{.*}}kernel_name2"() #0 {{.*}} !initiation_interval ![[NUM42:[0-9]+]]
// CHECK: define {{.*}}spir_kernel void @{{.*}}kernel_name3"() #0 {{.*}} !initiation_interval ![[NUM2:[0-9]+]]
// CHECK: define {{.*}}spir_kernel void @{{.*}}kernel_name4"() #0 {{.*}}
// CHECK: ![[NUM1]] = !{i32 1}
// CHECK: ![[NUM42]] = !{i32 42}
// CHECK: ![[NUM2]] = !{i32 2}