r369373 - [OpenCL] Add const, volatile and pointer builtin handling

Sven van Haastregt via cfe-commits cfe-commits at lists.llvm.org
Tue Aug 20 05:21:03 PDT 2019


Author: svenvh
Date: Tue Aug 20 05:21:03 2019
New Revision: 369373

URL: http://llvm.org/viewvc/llvm-project?rev=369373&view=rev
Log:
[OpenCL] Add const, volatile and pointer builtin handling

Const, volatile, and pointer types were previously available, but not
working.  This patch adds handling for OpenCL builtin functions.

Add TableGen definitions for some atomic and asynchronous builtins to
make use of the new functionality.

Patch by Pierre Gondois and Sven van Haastregt.

Differential Revision: https://reviews.llvm.org/D63442

Modified:
    cfe/trunk/lib/Sema/OpenCLBuiltins.td
    cfe/trunk/test/SemaOpenCL/fdeclare-opencl-builtins.cl
    cfe/trunk/utils/TableGen/ClangOpenCLBuiltinEmitter.cpp

Modified: cfe/trunk/lib/Sema/OpenCLBuiltins.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/OpenCLBuiltins.td?rev=369373&r1=369372&r2=369373&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/OpenCLBuiltins.td (original)
+++ cfe/trunk/lib/Sema/OpenCLBuiltins.td Tue Aug 20 05:21:03 2019
@@ -51,11 +51,6 @@ class QualType<string _Name, bit _IsAbst
   bit IsAbstract = _IsAbstract;
 }
 
-// Helper class to store type access qualifiers (volatile, const, ...).
-class Qualifier<string _QualName> {
-  string QualName = _QualName;
-}
-
 // List of integers.
 class IntList<string _Name, list<int> _List> {
   string Name = _Name;
@@ -79,24 +74,59 @@ class Type<string _Name, QualType _QTNam
   int VecWidth = 1;
   // Is a pointer.
   bit IsPointer = 0;
-  // List of qualifiers associated with the type (volatile, ...)
-  list<Qualifier> QualList = [];
+  // "const" qualifier.
+  bit IsConst = 0;
+  // "volatile" qualifier.
+  bit IsVolatile = 0;
   // Access qualifier. Must be one of ("RO", "WO", "RW").
   string AccessQualifier = "";
   // Address space.
-  string AddrSpace = "clang::LangAS::Default";
+  string AddrSpace = DefaultAS.Name;
 }
 
-// OpenCL vector types (e.g. int2, int3, int16, float8, ...)
+// OpenCL vector types (e.g. int2, int3, int16, float8, ...).
 class VectorType<Type _Ty, int _VecWidth> : Type<_Ty.Name, _Ty.QTName> {
-  int VecWidth = _VecWidth;
+  let VecWidth = _VecWidth;
+  // Inherited fields
+  let IsPointer = _Ty.IsPointer;
+  let IsConst = _Ty.IsConst;
+  let IsVolatile = _Ty.IsVolatile;
+  let AccessQualifier = _Ty.AccessQualifier;
+  let AddrSpace = _Ty.AddrSpace;
 }
 
 // OpenCL pointer types (e.g. int*, float*, ...).
-class PointerType<Type _Ty, AddressSpace _AS = GlobalAS> :
+class PointerType<Type _Ty, AddressSpace _AS = DefaultAS> :
                                       Type<_Ty.Name, _Ty.QTName> {
-  bit IsPointer = 1;
-  string AddrSpace = _AS.Name;
+  let AddrSpace = _AS.Name;
+  // Inherited fields
+  let VecWidth = _Ty.VecWidth;
+  let IsPointer = 1;
+  let IsConst = _Ty.IsConst;
+  let IsVolatile = _Ty.IsVolatile;
+  let AccessQualifier = _Ty.AccessQualifier;
+}
+
+// OpenCL const types (e.g. const int).
+class ConstType<Type _Ty> : Type<_Ty.Name, _Ty.QTName> {
+  let IsConst = 1;
+  // Inherited fields
+  let VecWidth = _Ty.VecWidth;
+  let IsPointer = _Ty.IsPointer;
+  let IsVolatile = _Ty.IsVolatile;
+  let AccessQualifier = _Ty.AccessQualifier;
+  let AddrSpace = _Ty.AddrSpace;
+}
+
+// OpenCL volatile types (e.g. volatile int).
+class VolatileType<Type _Ty> : Type<_Ty.Name, _Ty.QTName> {
+  let IsVolatile = 1;
+  // Inherited fields
+  let VecWidth = _Ty.VecWidth;
+  let IsPointer = _Ty.IsPointer;
+  let IsConst = _Ty.IsConst;
+  let AccessQualifier = _Ty.AccessQualifier;
+  let AddrSpace = _Ty.AddrSpace;
 }
 
 // OpenCL image types (e.g. image2d_t, ...)
@@ -242,12 +272,16 @@ def VecNoScalar : IntList<"VecNoScalar",
 def Vec1        : IntList<"Vec1", [1]>;
 
 // Type lists.
+def TLAll   : TypeList<"TLAll", [Char, UChar, Short, UShort, Int, UInt, Long, ULong, Float, Double, Half]>;
 def TLFloat : TypeList<"TLFloat", [Float, Double, Half]>;
 
 def TLAllInts : TypeList<"TLAllInts", [Char, UChar, Short, UShort, Int, UInt, Long, ULong]>;
 
 // GenType definitions for multiple base types (e.g. all floating point types,
 // or all integer types).
+// All types
+def AGenTypeN              : GenericType<"AGenTypeN", TLAll, VecAndScalar>;
+def AGenTypeNNoScalar      : GenericType<"AGenTypeNNoScalar", TLAll, VecNoScalar>;
 // All integer
 def AIGenType1             : GenericType<"AIGenType1", TLAllInts, Vec1>;
 def AIGenTypeN             : GenericType<"AIGenTypeN", TLAllInts, VecAndScalar>;
@@ -294,6 +328,44 @@ foreach RType = [Float, Double, Half, Ch
   }
 }
 
+//--------------------------------------------------------------------
+// OpenCL v1.1 s6.11.10, v1.2 s6.12.10, v2.0 s6.13.10: Async Copies from Global to Local Memory, Local to Global Memory, and Prefetch
+// OpenCL Extension v2.0 s5.1.7 and s6.1.7: Async Copies from Global to Local Memory, Local to Global Memory, and Prefetch
+// --- Table 18 ---
+foreach name = ["async_work_group_copy"] in {
+  def : Builtin<name, [Event, PointerType<AGenTypeN, LocalAS>, PointerType<ConstType<AGenTypeN>, GlobalAS>, Size, Event]>;
+  def : Builtin<name, [Event, PointerType<AGenTypeN, GlobalAS>, PointerType<ConstType<AGenTypeN>, LocalAS>, Size, Event]>;
+}
+foreach name = ["async_work_group_strided_copy"] in {
+  def : Builtin<name, [Event, PointerType<AGenTypeN, LocalAS>, PointerType<ConstType<AGenTypeN>, GlobalAS>, Size, Size, Event]>;
+  def : Builtin<name, [Event, PointerType<AGenTypeN, GlobalAS>, PointerType<ConstType<AGenTypeN>, LocalAS>, Size, Size, Event]>;
+}
+foreach name = ["wait_group_events"] in {
+  def : Builtin<name, [Void, Int, PointerType<Event, GenericAS>]>;
+}
+foreach name = ["prefetch"] in {
+  def : Builtin<name, [Void, PointerType<ConstType<AGenTypeN>, GlobalAS>, Size]>;
+}
+
+//--------------------------------------------------------------------
+// OpenCL v2.0 s6.13.11 - Atomics Functions.
+// Functions that use memory_order and cl_mem_fence_flags enums are not
+// declared here as the TableGen backend does not handle enums.
+
+// OpenCL v1.0 s9.5, s9.6, s9.7 - Atomic Functions for 32-bit integers.
+// --- Table 9.1 ---
+foreach Type = [Int, UInt] in {
+  foreach name = ["atom_add", "atom_sub", "atom_xchg"] in {
+    def : Builtin<name, [Type, PointerType<VolatileType<Type>, GlobalAS>, Type]>;
+  }
+  foreach name = ["atom_inc", "atom_dec"] in {
+    def : Builtin<name, [Type, PointerType<VolatileType<Type>, GlobalAS>]>;
+  }
+  foreach name = ["atom_cmpxchg"] in {
+    def : Builtin<name, [Type, PointerType<VolatileType<Type>, GlobalAS>, Type, Type]>;
+  }
+}
+
 // OpenCL v1.2 s6.12.1: Work-Item Functions
 def get_work_dim : Builtin<"get_work_dim", [UInt]>;
 foreach name = ["get_global_size", "get_global_id", "get_local_size",

Modified: cfe/trunk/test/SemaOpenCL/fdeclare-opencl-builtins.cl
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaOpenCL/fdeclare-opencl-builtins.cl?rev=369373&r1=369372&r2=369373&view=diff
==============================================================================
--- cfe/trunk/test/SemaOpenCL/fdeclare-opencl-builtins.cl (original)
+++ cfe/trunk/test/SemaOpenCL/fdeclare-opencl-builtins.cl Tue Aug 20 05:21:03 2019
@@ -16,6 +16,16 @@ typedef unsigned int uint;
 typedef __SIZE_TYPE__ size_t;
 #endif
 
+kernel void test_pointers(volatile global void *global_p, global const int4 *a) {
+  int i;
+  unsigned int ui;
+
+  prefetch(a, 2);
+
+  atom_add((volatile __global int *)global_p, i);
+  atom_cmpxchg((volatile __global unsigned int *)global_p, ui, ui);
+}
+
 kernel void basic_conversion() {
   double d;
   float f;

Modified: cfe/trunk/utils/TableGen/ClangOpenCLBuiltinEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangOpenCLBuiltinEmitter.cpp?rev=369373&r1=369372&r2=369373&view=diff
==============================================================================
--- cfe/trunk/utils/TableGen/ClangOpenCLBuiltinEmitter.cpp (original)
+++ cfe/trunk/utils/TableGen/ClangOpenCLBuiltinEmitter.cpp Tue Aug 20 05:21:03 2019
@@ -236,10 +236,18 @@ void BuiltinNameEmitter::EmitDeclaration
 
 // Represents a return type or argument type.
 struct OpenCLTypeStruct {
-  // A type (e.g. float, int, ...)
+  // A type (e.g. float, int, ...).
   const OpenCLTypeID ID;
   // Vector size (if applicable; 0 for scalars and generic types).
   const unsigned VectorWidth;
+  // 0 if the type is not a pointer.
+  const bool IsPointer;
+  // 0 if the type is not const.
+  const bool IsConst;
+  // 0 if the type is not volatile.
+  const bool IsVolatile;
+  // Address space of the pointer (if applicable).
+  const LangAS AS;
 };
 
 // One overload of an OpenCL builtin function.
@@ -341,7 +349,11 @@ void BuiltinNameEmitter::EmitTypeTable()
   for (const auto &T : TypeMap) {
     OS << "  // " << T.second << "\n";
     OS << "  {OCLT_" << T.first->getValueAsString("Name") << ", "
-       << T.first->getValueAsInt("VecWidth") << "},\n";
+       << T.first->getValueAsInt("VecWidth") << ", "
+       << T.first->getValueAsBit("IsPointer") << ", "
+       << T.first->getValueAsBit("IsConst") << ", "
+       << T.first->getValueAsBit("IsVolatile") << ", "
+       << T.first->getValueAsString("AddrSpace") << "},\n";
   }
   OS << "};\n\n";
 }
@@ -525,6 +537,28 @@ static void OCL2Qual(ASTContext &Context
       QT[Index] = Context.getExtVectorType(QT[Index], Ty.VectorWidth);
     }
   }
+
+  if (Ty.IsVolatile != 0) {
+    for (unsigned Index = 0; Index < QT.size(); Index++) {
+      QT[Index] = Context.getVolatileType(QT[Index]);
+    }
+  }
+
+  if (Ty.IsConst != 0) {
+    for (unsigned Index = 0; Index < QT.size(); Index++) {
+      QT[Index] = Context.getConstType(QT[Index]);
+    }
+  }
+
+  // Transform the type to a pointer as the last step, if necessary.
+  // Builtin functions only have pointers on [const|volatile], no
+  // [const|volatile] pointers, so this is ok to do it as a last step.
+  if (Ty.IsPointer != 0) {
+    for (unsigned Index = 0; Index < QT.size(); Index++) {
+      QT[Index] = Context.getAddrSpaceQualType(QT[Index], Ty.AS);
+      QT[Index] = Context.getPointerType(QT[Index]);
+    }
+  }
 )";
 
   // End of the "OCL2Qual" function.




More information about the cfe-commits mailing list