1 //===------------------------- ParameterType.h ---------------------------===//
2 //
3 //                              SPIR Tools
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===---------------------------------------------------------------------===//
9 /*
10  * Contributed by: Intel Corporation.
11  */
12 
13 #ifndef SPIRV_MANGLER_PARAMETERTYPE_H
14 #define SPIRV_MANGLER_PARAMETERTYPE_H
15 
16 #include "Refcount.h"
17 #include <string>
18 #include <vector>
19 
20 // The Type class hierarchy models the different types in OCL.
21 
22 namespace SPIR {
23 
24 // Supported SPIR versions
25 enum SPIRversion { SPIR12 = 1, SPIR20 = 2 };
26 
27 // Error Status values
28 enum MangleError {
29   MANGLE_SUCCESS,
30   MANGLE_TYPE_NOT_SUPPORTED,
31   MANGLE_NULL_FUNC_DESCRIPTOR
32 };
33 
34 enum TypePrimitiveEnum {
35   PRIMITIVE_FIRST,
36   PRIMITIVE_BOOL = PRIMITIVE_FIRST,
37   PRIMITIVE_UCHAR,
38   PRIMITIVE_CHAR,
39   PRIMITIVE_USHORT,
40   PRIMITIVE_SHORT,
41   PRIMITIVE_UINT,
42   PRIMITIVE_INT,
43   PRIMITIVE_ULONG,
44   PRIMITIVE_LONG,
45   PRIMITIVE_HALF,
46   PRIMITIVE_FLOAT,
47   PRIMITIVE_DOUBLE,
48   PRIMITIVE_VOID,
49   PRIMITIVE_VAR_ARG,
50   PRIMITIVE_STRUCT_FIRST,
51   PRIMITIVE_IMAGE1D_RO_T = PRIMITIVE_STRUCT_FIRST,
52   PRIMITIVE_IMAGE1D_ARRAY_RO_T,
53   PRIMITIVE_IMAGE1D_BUFFER_RO_T,
54   PRIMITIVE_IMAGE2D_RO_T,
55   PRIMITIVE_IMAGE2D_ARRAY_RO_T,
56   PRIMITIVE_IMAGE2D_DEPTH_RO_T,
57   PRIMITIVE_IMAGE2D_ARRAY_DEPTH_RO_T,
58   PRIMITIVE_IMAGE2D_MSAA_RO_T,
59   PRIMITIVE_IMAGE2D_ARRAY_MSAA_RO_T,
60   PRIMITIVE_IMAGE2D_MSAA_DEPTH_RO_T,
61   PRIMITIVE_IMAGE2D_ARRAY_MSAA_DEPTH_RO_T,
62   PRIMITIVE_IMAGE3D_RO_T,
63   PRIMITIVE_IMAGE1D_WO_T,
64   PRIMITIVE_IMAGE1D_ARRAY_WO_T,
65   PRIMITIVE_IMAGE1D_BUFFER_WO_T,
66   PRIMITIVE_IMAGE2D_WO_T,
67   PRIMITIVE_IMAGE2D_ARRAY_WO_T,
68   PRIMITIVE_IMAGE2D_DEPTH_WO_T,
69   PRIMITIVE_IMAGE2D_ARRAY_DEPTH_WO_T,
70   PRIMITIVE_IMAGE2D_MSAA_WO_T,
71   PRIMITIVE_IMAGE2D_ARRAY_MSAA_WO_T,
72   PRIMITIVE_IMAGE2D_MSAA_DEPTH_WO_T,
73   PRIMITIVE_IMAGE2D_ARRAY_MSAA_DEPTH_WO_T,
74   PRIMITIVE_IMAGE3D_WO_T,
75   PRIMITIVE_IMAGE1D_RW_T,
76   PRIMITIVE_IMAGE1D_ARRAY_RW_T,
77   PRIMITIVE_IMAGE1D_BUFFER_RW_T,
78   PRIMITIVE_IMAGE2D_RW_T,
79   PRIMITIVE_IMAGE2D_ARRAY_RW_T,
80   PRIMITIVE_IMAGE2D_DEPTH_RW_T,
81   PRIMITIVE_IMAGE2D_ARRAY_DEPTH_RW_T,
82   PRIMITIVE_IMAGE2D_MSAA_RW_T,
83   PRIMITIVE_IMAGE2D_ARRAY_MSAA_RW_T,
84   PRIMITIVE_IMAGE2D_MSAA_DEPTH_RW_T,
85   PRIMITIVE_IMAGE2D_ARRAY_MSAA_DEPTH_RW_T,
86   PRIMITIVE_IMAGE3D_RW_T,
87   PRIMITIVE_EVENT_T,
88   PRIMITIVE_PIPE_RO_T,
89   PRIMITIVE_PIPE_WO_T,
90   PRIMITIVE_RESERVE_ID_T,
91   PRIMITIVE_QUEUE_T,
92   PRIMITIVE_NDRANGE_T,
93   PRIMITIVE_CLK_EVENT_T,
94   PRIMITIVE_STRUCT_LAST = PRIMITIVE_CLK_EVENT_T,
95   PRIMITIVE_SAMPLER_T,
96   PRIMITIVE_KERNEL_ENQUEUE_FLAGS_T,
97   PRIMITIVE_CLK_PROFILING_INFO,
98   PRIMITIVE_MEMORY_ORDER,
99   PRIMITIVE_MEMORY_SCOPE,
100   PRIMITIVE_SUB_GROUP_AVC_MCE_PAYLOAD_T,
101   PRIMITIVE_SUB_GROUP_AVC_IME_PAYLOAD_T,
102   PRIMITIVE_SUB_GROUP_AVC_REF_PAYLOAD_T,
103   PRIMITIVE_SUB_GROUP_AVC_SIC_PAYLOAD_T,
104   PRIMITIVE_SUB_GROUP_AVC_MCE_RESULT_T,
105   PRIMITIVE_SUB_GROUP_AVC_IME_RESULT_T,
106   PRIMITIVE_SUB_GROUP_AVC_REF_RESULT_T,
107   PRIMITIVE_SUB_GROUP_AVC_SIC_RESULT_T,
108   PRIMITIVE_SUB_GROUP_AVC_IME_SINGLE_REF_STREAMOUT_T,
109   PRIMITIVE_SUB_GROUP_AVC_IME_DUAL_REF_STREAMOUT_T,
110   PRIMITIVE_SUB_GROUP_AVC_IME_SINGLE_REF_STREAMIN_T,
111   PRIMITIVE_SUB_GROUP_AVC_IME_DUAL_REF_STREAMIN_T,
112   PRIMITIVE_LAST = PRIMITIVE_SUB_GROUP_AVC_IME_DUAL_REF_STREAMIN_T,
113   PRIMITIVE_NONE,
114   // Keep this at the end.
115   PRIMITIVE_NUM = PRIMITIVE_NONE
116 };
117 
118 enum TypeEnum {
119   TYPE_ID_PRIMITIVE,
120   TYPE_ID_POINTER,
121   TYPE_ID_VECTOR,
122   TYPE_ID_ATOMIC,
123   TYPE_ID_BLOCK,
124   TYPE_ID_STRUCTURE
125 };
126 
127 enum TypeAttributeEnum {
128   ATTR_QUALIFIER_FIRST = 0,
129   ATTR_RESTRICT = ATTR_QUALIFIER_FIRST,
130   ATTR_VOLATILE,
131   ATTR_CONST,
132   ATTR_QUALIFIER_LAST = ATTR_CONST,
133   ATTR_ADDR_SPACE_FIRST,
134   ATTR_PRIVATE = ATTR_ADDR_SPACE_FIRST,
135   ATTR_GLOBAL,
136   ATTR_CONSTANT,
137   ATTR_LOCAL,
138   ATTR_GENERIC,
139   ATTR_GLOBAL_DEVICE,
140   ATTR_GLOBAL_HOST,
141   ATTR_ADDR_SPACE_LAST = ATTR_GLOBAL_HOST,
142   ATTR_NONE,
143   ATTR_NUM = ATTR_NONE
144 };
145 
146 // Forward declaration for abstract structure.
147 struct ParamType;
148 typedef RefCount<ParamType> RefParamType;
149 
150 // Forward declaration for abstract structure.
151 struct TypeVisitor;
152 
153 struct ParamType {
154   /// @brief Constructor.
155   /// @param TypeEnum type id.
ParamTypeParamType156   ParamType(TypeEnum TypeId) : TypeId(TypeId){};
157 
158   /// @brief Destructor.
~ParamTypeParamType159   virtual ~ParamType(){};
160 
161   /// Abstract Methods ///
162 
163   /// @brief Visitor service method. (see TypeVisitor for more details).
164   ///        When overridden in subclasses, preform a 'double dispatch' to the
165   ///        appropriate visit method in the given visitor.
166   /// @param TypeVisitor type visitor.
167   virtual MangleError accept(TypeVisitor *) const = 0;
168 
169   /// @brief Returns a string representation of the underlying type.
170   /// @return type as string.
171   virtual std::string toString() const = 0;
172 
173   /// @brief Returns true if given param type is equal to this type.
174   /// @param ParamType given param type.
175   /// @return true if given param type is equal to this type and false
176   /// otherwise.
177   virtual bool equals(const ParamType *) const = 0;
178 
179   /// Common Base-Class Methods ///
180 
181   /// @brief Returns type id of underlying type.
182   /// @return type id.
getTypeIdParamType183   TypeEnum getTypeId() const { return TypeId; }
184 
185 private:
186   // @brief Default Constructor.
187   ParamType();
188 
189 protected:
190   /// An enumeration to identify the type id of this instance.
191   TypeEnum TypeId;
192 };
193 
194 struct PrimitiveType : public ParamType {
195   /// An enumeration to identify the type id of this class.
196   const static TypeEnum EnumTy;
197 
198   /// @brief Constructor.
199   /// @param TypePrimitiveEnum primitive id.
200   PrimitiveType(TypePrimitiveEnum);
201 
202   /// Implementation of Abstract Methods ///
203 
204   /// @brief Visitor service method. (see TypeVisitor for more details).
205   ///        When overridden in subclasses, preform a 'double dispatch' to the
206   ///        appropriate visit method in the given visitor.
207   /// @param TypeVisitor type visitor.
208   MangleError accept(TypeVisitor *) const override;
209 
210   /// @brief Returns a string representation of the underlying type.
211   /// @return type as string.
212   std::string toString() const override;
213 
214   /// @brief Returns true if given param type is equal to this type.
215   /// @param ParamType given param type.
216   /// @return true if given param type is equal to this type and false
217   /// otherwise.
218   bool equals(const ParamType *) const override;
219 
220   /// Non-Common Methods ///
221 
222   /// @brief Returns the primitive enumeration of the type.
223   /// @return primitive type.
getPrimitivePrimitiveType224   TypePrimitiveEnum getPrimitive() const { return Primitive; }
225 
226 protected:
227   /// An enumeration to identify the primitive type.
228   TypePrimitiveEnum Primitive;
229 };
230 
231 struct PointerType : public ParamType {
232   /// An enumeration to identify the type id of this class.
233   const static TypeEnum EnumTy;
234 
235   /// @brief Constructor.
236   /// @param RefParamType the type of pointee (that the pointer points at).
237   PointerType(const RefParamType Type);
238 
239   /// Implementation of Abstract Methods ///
240 
241   /// @brief Visitor service method. (see TypeVisitor for more details).
242   ///        When overridden in subclasses, preform a 'double dispatch' to the
243   ///        appropriate visit method in the given visitor.
244   /// @param TypeVisitor type visitor
245   MangleError accept(TypeVisitor *) const override;
246 
247   /// @brief Returns a string representation of the underlying type.
248   /// @return type as string.
249   std::string toString() const override;
250 
251   /// @brief Returns true if given param type is equal to this type.
252   /// @param ParamType given param type.
253   /// @return true if given param type is equal to this type and false
254   /// otherwise.
255   bool equals(const ParamType *) const override;
256 
257   /// Non-Common Methods ///
258 
259   /// @brief Returns the type the pointer is pointing at.
260   /// @return pointee type.
getPointeePointerType261   const RefParamType &getPointee() const { return PType; }
262 
263   /// @brief Sets the address space attribute - default is __private
264   /// @param TypeAttributeEnum address space attribute id.
265   void setAddressSpace(TypeAttributeEnum Attr);
266 
267   /// @brief Returns the pointer's address space.
268   /// @return pointer's address space.
269   TypeAttributeEnum getAddressSpace() const;
270 
271   /// @brief Adds or removes a pointer's qualifier.
272   /// @param TypeAttributeEnum qual - qualifier to add/remove.
273   /// @param bool enabled - true if qualifier should exist false otherwise.
274   ///        default is set to false.
275   void setQualifier(TypeAttributeEnum Qual, bool Enabled);
276 
277   /// @brief Checks if the pointer has a certain qualifier.
278   /// @param TypeAttributeEnum qual - qualifier to check.
279   /// @return true if the qualifier exists and false otherwise.
280   bool hasQualifier(TypeAttributeEnum Qual) const;
281 
282 private:
283   /// The type this pointer is pointing at.
284   RefParamType PType;
285   /// Array of the pointer's enabled type qualifiers.
286   bool Qualifiers[ATTR_QUALIFIER_LAST - ATTR_QUALIFIER_FIRST + 1];
287   /// Pointer's address space.
288   TypeAttributeEnum AddressSpace;
289 };
290 
291 struct VectorType : public ParamType {
292   /// An enumeration to identify the type id of this class.
293   const static TypeEnum EnumTy;
294 
295   /// @brief Constructor.
296   /// @param RefParamType the type of each scalar element in the vector.
297   /// @param int the length of the vector.
298   VectorType(const RefParamType Type, int Len);
299 
300   /// Implementation of Abstract Methods ///
301 
302   /// @brief Visitor service method. (see TypeVisitor for more details).
303   ///        When overridden in subclasses, preform a 'double dispatch' to the
304   ///        appropriate visit method in the given visitor.
305   /// @param TypeVisitor type visitor.
306   MangleError accept(TypeVisitor *) const override;
307 
308   /// @brief Returns a string representation of the underlying type.
309   /// @return type as string.
310   std::string toString() const override;
311 
312   /// @brief Returns true if given param type is equal to this type.
313   /// @param ParamType given param type.
314   /// @return true if given param type is equal to this type and false
315   /// otherwise.
316   bool equals(const ParamType *) const override;
317 
318   /// Non-Common Methods ///
319 
320   /// @brief Returns the type the vector is packing.
321   /// @return scalar type.
getScalarTypeVectorType322   const RefParamType &getScalarType() const { return PType; }
323 
324   /// @brief Returns the length of the vector type.
325   /// @return vector type length.
getLengthVectorType326   int getLength() const { return Len; }
327 
328 private:
329   /// The scalar type of this vector type.
330   RefParamType PType;
331   /// The length of the vector.
332   int Len;
333 };
334 
335 struct AtomicType : public ParamType {
336   /// an enumeration to identify the type id of this class
337   const static TypeEnum EnumTy;
338 
339   /// @brief Constructor
340   /// @param RefParamType the type refernced as atomic.
341   AtomicType(const RefParamType Type);
342 
343   /// Implementation of Abstract Methods ///
344 
345   /// @brief visitor service method. (see TypeVisitor for more details).
346   ///       When overridden in subclasses, preform a 'double dispatch' to the
347   ///       appropriate visit method in the given visitor.
348   /// @param TypeVisitor type visitor
349   MangleError accept(TypeVisitor *) const override;
350 
351   /// @brief returns a string representation of the underlying type.
352   /// @return type as string
353   std::string toString() const override;
354 
355   /// @brief returns true if given param type is equal to this type.
356   /// @param ParamType given param type
357   /// @return true if given param type is equal to this type and false otherwise
358   bool equals(const ParamType *) const override;
359 
360   /// Non-Common Methods ///
361 
362   /// @brief returns the base type of the atomic parameter.
363   /// @return base type
getBaseTypeAtomicType364   const RefParamType &getBaseType() const { return PType; }
365 
366 private:
367   /// the type this pointer is pointing at
368   RefParamType PType;
369 };
370 
371 struct BlockType : public ParamType {
372   /// an enumeration to identify the type id of this class
373   const static TypeEnum EnumTy;
374 
375   ///@brief Constructor
376   BlockType();
377 
378   /// Implementation of Abstract Methods ///
379 
380   /// @brief visitor service method. (see TypeVisitor for more details).
381   ///       When overridden in subclasses, preform a 'double dispatch' to the
382   ///       appropriate visit method in the given visitor.
383   /// @param TypeVisitor type visitor
384   MangleError accept(TypeVisitor *) const override;
385 
386   /// @brief returns a string representation of the underlying type.
387   /// @return type as string
388   std::string toString() const override;
389 
390   /// @brief returns true if given param type is equal to this type.
391   /// @param ParamType given param type
392   /// @return true if given param type is equal to this type and false otherwise
393   bool equals(const ParamType *) const override;
394 
395   /// Non-Common Methods ///
396 
397   /// @brief returns the number of parameters of the block.
398   /// @return parameters count
getNumOfParamsBlockType399   unsigned int getNumOfParams() const { return (unsigned int)Params.size(); }
400 
401   ///@brief returns the type of parameter "index" of the block.
402   // @param index the sequential number of the queried parameter
403   ///@return parameter type
getParamBlockType404   const RefParamType &getParam(unsigned int Index) const {
405     assert(Params.size() > Index && "index is OOB");
406     return Params[Index];
407   }
408 
409   ///@brief set the type of parameter "index" of the block.
410   // @param index the sequential number of the queried parameter
411   // @param type the parameter type
setParamBlockType412   void setParam(unsigned int Index, RefParamType Type) {
413     if (Index < getNumOfParams()) {
414       Params[Index] = Type;
415     } else if (Index == getNumOfParams()) {
416       Params.push_back(Type);
417     } else {
418       assert(false && "index is OOB");
419     }
420   }
421 
422 protected:
423   /// an enumeration to identify the primitive type
424   std::vector<RefParamType> Params;
425 };
426 
427 struct UserDefinedType : public ParamType {
428   /// An enumeration to identify the type id of this class.
429   const static TypeEnum EnumTy;
430 
431   /// @brief Constructor.
432   UserDefinedType(const std::string &);
433 
434   /// Implementation of Abstract Methods ///
435 
436   /// @brief Visitor service method. (see TypeVisitor for more details).
437   ///        When overridden in subclasses, preform a 'double dispatch' to the
438   ///        appropriate visit method in the given visitor.
439   /// @param TypeVisitor type visitor.
440   MangleError accept(TypeVisitor *) const override;
441 
442   /// @brief Returns a string representation of the underlying type.
443   /// @return type as string.
444   std::string toString() const override;
445 
446   /// @brief Returns true if given param type is equal to this type.
447   /// @param ParamType given param type.
448   /// @return true if given param type is equal to this type and false
449   /// otherwise.
450   bool equals(const ParamType *) const override;
451 
452 protected:
453   /// The name of the user defined type.
454   std::string Name;
455 };
456 
457 /// @brief Can be overridden so an object of static type Type* will
458 ///        dispatch the correct visit method according to its dynamic type.
459 struct TypeVisitor {
460   SPIRversion SpirVer;
TypeVisitorTypeVisitor461   TypeVisitor(SPIRversion Ver) : SpirVer(Ver) {}
~TypeVisitorTypeVisitor462   virtual ~TypeVisitor() {}
463   virtual MangleError visit(const PrimitiveType *) = 0;
464   virtual MangleError visit(const VectorType *) = 0;
465   virtual MangleError visit(const PointerType *) = 0;
466   virtual MangleError visit(const AtomicType *) = 0;
467   virtual MangleError visit(const BlockType *) = 0;
468   virtual MangleError visit(const UserDefinedType *) = 0;
469 };
470 
471 /// @brief Template dynamic cast function for ParamType derived classes.
472 /// @param ParamType given param type.
473 /// @return required casting type if given param type is an instance if
474 //          that type, NULL otherwise.
dynCast(ParamType * PType)475 template <typename T> T *dynCast(ParamType *PType) {
476   assert(PType && "dyn_cast does not support casting of NULL");
477   return (T::EnumTy == PType->getTypeId()) ? (T *)PType : NULL;
478 }
479 
480 /// @brief Template dynamic cast function for ParamType derived classes
481 ///        (the constant version).
482 /// @param ParamType given param type.
483 /// @return required casting type if given param type is an instance if
484 //          that type, NULL otherwise.
dynCast(const ParamType * PType)485 template <typename T> const T *dynCast(const ParamType *PType) {
486   assert(PType && "dyn_cast does not support casting of NULL");
487   return (T::EnumTy == PType->getTypeId()) ? (const T *)PType : NULL;
488 }
489 
490 } // namespace SPIR
491 #endif // SPIRV_MANGLER_PARAMETERTYPE_H
492