zahiraam created this revision.
zahiraam added reviewers: bader, Naghasan, keryell, Fznamznon, aaron.ballman, 
erichkeane.
Herald added subscribers: jdoerfert, Anastasia, ebevhan, yaxunl.
zahiraam requested review of this revision.
Herald added a project: clang.

Special classes such as accessor, sampler, and stream need additional 
implementation when they are passed from host to device.
This patch is adding a new attribute “sycl_special_class” used to mark SYCL 
classes/struct that need the additional compiler handling.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D114483

Files:
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttrDocs.td
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/Misc/pragma-attribute-supported-attributes-list.test
  clang/test/SemaSYCL/special-class-attribute-on-non-sycl.cpp
  clang/test/SemaSYCL/special-class-attribute.cpp

Index: clang/test/SemaSYCL/special-class-attribute.cpp
===================================================================
--- /dev/null
+++ clang/test/SemaSYCL/special-class-attribute.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -fsycl-is-device -verify %s
+
+// No diagnostics
+class [[clang::sycl_special_class]] class1 {};
+class __attribute__((sycl_special_class)) class2 {};
+
+class class3;
+class [[clang::sycl_special_class]] class3 {};
+
+class class4;
+class __attribute__((sycl_special_class)) class4 {};
+
+class [[clang::sycl_special_class]] struct1 {};
+struct __attribute__((sycl_special_class)) struct2 {};
+
+class [[clang::sycl_special_class]] class5 {};
+class special5 {};
+
+class __attribute__((sycl_special_class)) class6;
+class class6 {};
+
+
+// Only classes
+[[clang::sycl_special_class]] int var1 = 0; // expected-warning {{'sycl_special_class' attribute only applies to classes}}
+__attribute__((sycl_special_class)) int var2 = 0; // expected-warning {{'sycl_special_class' attribute only applies to classes}}
+
+[[clang::sycl_special_class]] void foo1(); // expected-warning {{'sycl_special_class' attribute only applies to classes}}
+__attribute__((sycl_special_class)) void foo2(); // expected-warning {{'sycl_special_class' attribute only applies to classes}}
+
+// Attribute takes no arguments
+class [[clang::sycl_special_class(1)]] class7 {}; // expected-error {{'sycl_special_class' attribute takes no arguments}}
+class __attribute__((sycl_special_class(1))) class8 {}; // expected-error {{'sycl_special_class' attribute takes no arguments}}
+
Index: clang/test/SemaSYCL/special-class-attribute-on-non-sycl.cpp
===================================================================
--- /dev/null
+++ clang/test/SemaSYCL/special-class-attribute-on-non-sycl.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -fsycl-is-device -verify %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -x c++ %s
+
+#ifndef __SYCL_DEVICE_ONLY__
+// expected-warning@+5 {{'sycl_special_class' attribute ignored}}
+#else
+// expected-no-diagnostics
+#endif
+
+class __attribute__((sycl_special_class)) special_class {};
+
Index: clang/test/Misc/pragma-attribute-supported-attributes-list.test
===================================================================
--- clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -154,6 +154,7 @@
 // CHECK-NEXT: ReturnTypestate (SubjectMatchRule_function, SubjectMatchRule_variable_is_parameter)
 // CHECK-NEXT: ReturnsNonNull (SubjectMatchRule_objc_method, SubjectMatchRule_function)
 // CHECK-NEXT: ReturnsTwice (SubjectMatchRule_function)
+// CHECK-NEXT: SYCLSpecialClass (SubjectMatchRule_record)
 // CHECK-NEXT: ScopedLockable (SubjectMatchRule_record)
 // CHECK-NEXT: Section (SubjectMatchRule_function, SubjectMatchRule_variable_is_global, SubjectMatchRule_objc_method, SubjectMatchRule_objc_property)
 // CHECK-NEXT: SetTypestate (SubjectMatchRule_function_is_member)
Index: clang/lib/Sema/SemaDeclAttr.cpp
===================================================================
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -8054,6 +8054,9 @@
   case ParsedAttr::AT_SYCLKernel:
     handleSYCLKernelAttr(S, D, AL);
     break;
+  case ParsedAttr::AT_SYCLSpecialClass:
+    handleSimpleAttribute<SYCLSpecialClassAttr>(S, D, AL);
+    break;
   case ParsedAttr::AT_Format:
     handleFormatAttr(S, D, AL);
     break;
Index: clang/include/clang/Basic/AttrDocs.td
===================================================================
--- clang/include/clang/Basic/AttrDocs.td
+++ clang/include/clang/Basic/AttrDocs.td
@@ -405,6 +405,65 @@
   }];
 }
 
+def SYCLSpecialClassDocs : Documentation {
+  let Category = DocCatStmt;
+  let Content = [{
+The ``__attribute__((sycl_special_class))`` attribute is used in SYCL
+headers to indicate that a class or a struct needs additional implementation when
+it is passed from host to device.
+Special classes/struct will have a mandatory __init method and an optional __finalize
+method (__finalize method method is used only with stream type). __init method gives the
+user additional information required. For instance, the kernel function arguments
+list is derived from the arguments of the __init method. The arguments of the __init method
+are copied into the kernel function argument list and __init and __finalize methods are called
+at the beginning and the end of the kernel, respectively.
+Please note that this is an attribute that is used for internal implementation and not intended
+to be used by external users.
+
+The sntax of the attribute is as follows:
+
+.. code-block:: c++
+
+   class __attribute__((sycl_special_class)) accessor {};
+   class [[clang::sycl_special_class]] accessor {};
+
+This is a code example that illustrates the use of the attribute:
+
+.. code-block:: c++
+
+   class __attribute__((sycl_special_class)) SpecialType {
+   int F1;
+   int F2;
+   void __init(int f1) {
+     F1 = f1;
+     F2 = f1;
+   }
+   void __finalize() {}
+   public:
+     SpecialType() = default;
+     int getF2() const { return F2; }
+   };
+
+   int main () {
+   SpecialType T;
+   cgh.single_task([=]() {
+     T.getF2();
+   });
+}
+
+This would trigger the following kernel entry point in the AST:
+
+.. code-block:: c++
+
+   void __sycl_kernel(int f1) {
+   SpecialType T;
+   T.__init(f1);
+   ...
+   T.__finalize()
+ }
+  }];
+}
+
 def C11NoReturnDocs : Documentation {
   let Category = DocCatFunction;
   let Content = [{
Index: clang/include/clang/Basic/Attr.td
===================================================================
--- clang/include/clang/Basic/Attr.td
+++ clang/include/clang/Basic/Attr.td
@@ -1191,6 +1191,13 @@
   let Documentation = [SYCLKernelDocs];
 }
 
+def SYCLSpecialClass: InheritableAttr {
+  let Spellings = [Clang<"sycl_special_class">];
+  let Subjects = SubjectList<[CXXRecord]>;
+  let LangOpts = [SYCL];
+  let Documentation = [SYCLSpecialClassDocs];
+}
+
 def C11NoReturn : InheritableAttr {
   let Spellings = [Keyword<"_Noreturn">];
   let Subjects = SubjectList<[Function], ErrorDiag>;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to