summaryrefslogtreecommitdiff
path: root/lib/SPIRV/Mangler/ParameterType.h
blob: b3ed4a1388c3c5bbe147f359c84009e276972c10 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
//===------------------------- ParameterType.h ---------------------------===//
//
//                              SPIR Tools
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
/*
 * Contributed by: Intel Corporation.
 */

#ifndef SPIRV_MANGLER_PARAMETERTYPE_H
#define SPIRV_MANGLER_PARAMETERTYPE_H

#include "Refcount.h"
#include <string>
#include <vector>

// The Type class hierarchy models the different types in OCL.

namespace SPIR {

// Supported SPIR versions
enum SPIRversion { SPIR12 = 1, SPIR20 = 2 };

// Error Status values
enum MangleError {
  MANGLE_SUCCESS,
  MANGLE_TYPE_NOT_SUPPORTED,
  MANGLE_NULL_FUNC_DESCRIPTOR
};

enum TypePrimitiveEnum {
  PRIMITIVE_FIRST,
  PRIMITIVE_BOOL = PRIMITIVE_FIRST,
  PRIMITIVE_UCHAR,
  PRIMITIVE_CHAR,
  PRIMITIVE_USHORT,
  PRIMITIVE_SHORT,
  PRIMITIVE_UINT,
  PRIMITIVE_INT,
  PRIMITIVE_ULONG,
  PRIMITIVE_LONG,
  PRIMITIVE_HALF,
  PRIMITIVE_FLOAT,
  PRIMITIVE_DOUBLE,
  PRIMITIVE_VOID,
  PRIMITIVE_VAR_ARG,
  PRIMITIVE_STRUCT_FIRST,
  PRIMITIVE_IMAGE_1D_T = PRIMITIVE_STRUCT_FIRST,
  PRIMITIVE_IMAGE_1D_ARRAY_T,
  PRIMITIVE_IMAGE_1D_BUFFER_T,
  PRIMITIVE_IMAGE_2D_T,
  PRIMITIVE_IMAGE_2D_ARRAY_T,
  PRIMITIVE_IMAGE_3D_T,
  PRIMITIVE_IMAGE_2D_MSAA_T,
  PRIMITIVE_IMAGE_2D_ARRAY_MSAA_T,
  PRIMITIVE_IMAGE_2D_MSAA_DEPTH_T,
  PRIMITIVE_IMAGE_2D_ARRAY_MSAA_DEPTH_T,
  PRIMITIVE_IMAGE_2D_DEPTH_T,
  PRIMITIVE_IMAGE_2D_ARRAY_DEPTH_T,
  PRIMITIVE_EVENT_T,
  PRIMITIVE_PIPE_T,
  PRIMITIVE_RESERVE_ID_T,
  PRIMITIVE_QUEUE_T,
  PRIMITIVE_NDRANGE_T,
  PRIMITIVE_CLK_EVENT_T,
  PRIMITIVE_STRUCT_LAST = PRIMITIVE_CLK_EVENT_T,
  PRIMITIVE_SAMPLER_T,
  PRIMITIVE_KERNEL_ENQUEUE_FLAGS_T,
  PRIMITIVE_CLK_PROFILING_INFO,
  PRIMITIVE_MEMORY_ORDER,
  PRIMITIVE_MEMORY_SCOPE,
  PRIMITIVE_LAST = PRIMITIVE_MEMORY_SCOPE,
  PRIMITIVE_NONE,
  // Keep this at the end.
  PRIMITIVE_NUM = PRIMITIVE_NONE
};

enum TypeEnum {
  TYPE_ID_PRIMITIVE,
  TYPE_ID_POINTER,
  TYPE_ID_VECTOR,
  TYPE_ID_ATOMIC,
  TYPE_ID_BLOCK,
  TYPE_ID_STRUCTURE
};

enum TypeAttributeEnum {
  ATTR_QUALIFIER_FIRST = 0,
  ATTR_RESTRICT = ATTR_QUALIFIER_FIRST,
  ATTR_VOLATILE,
  ATTR_CONST,
  ATTR_QUALIFIER_LAST = ATTR_CONST,
  ATTR_ADDR_SPACE_FIRST,
  ATTR_PRIVATE = ATTR_ADDR_SPACE_FIRST,
  ATTR_GLOBAL,
  ATTR_CONSTANT,
  ATTR_LOCAL,
  ATTR_GENERIC,
  ATTR_ADDR_SPACE_LAST = ATTR_GENERIC,
  ATTR_NONE,
  ATTR_NUM = ATTR_NONE
};

// Forward declaration for abstract structure.
struct ParamType;
typedef RefCount<ParamType> RefParamType;

// Forward declaration for abstract structure.
struct TypeVisitor;

struct ParamType {
  /// @brief Constructor.
  /// @param TypeEnum type id.
  ParamType(TypeEnum typeId) : TypeId(typeId){};

  /// @brief Destructor.
  virtual ~ParamType(){};

  /// Abstract Methods ///

  /// @brief Visitor service method. (see TypeVisitor for more details).
  ///        When overridden in subclasses, preform a 'double dispatch' to the
  ///        appropriate visit method in the given visitor.
  /// @param TypeVisitor type visitor.
  virtual MangleError accept(TypeVisitor *) const = 0;

  /// @brief Returns a string representation of the underlying type.
  /// @return type as string.
  virtual std::string toString() const = 0;

  /// @brief Returns true if given param type is equal to this type.
  /// @param ParamType given param type.
  /// @return true if given param type is equal to this type and false
  /// otherwise.
  virtual bool equals(const ParamType *) const = 0;

  /// Common Base-Class Methods ///

  /// @brief Returns type id of underlying type.
  /// @return type id.
  TypeEnum getTypeId() const { return TypeId; }

private:
  // @brief Default Constructor.
  ParamType();

protected:
  /// An enumeration to identify the type id of this instance.
  TypeEnum TypeId;
};

struct PrimitiveType : public ParamType {
  /// An enumeration to identify the type id of this class.
  const static TypeEnum enumTy;

  /// @brief Constructor.
  /// @param TypePrimitiveEnum primitive id.
  PrimitiveType(TypePrimitiveEnum);

  /// Implementation of Abstract Methods ///

  /// @brief Visitor service method. (see TypeVisitor for more details).
  ///        When overridden in subclasses, preform a 'double dispatch' to the
  ///        appropriate visit method in the given visitor.
  /// @param TypeVisitor type visitor.
  MangleError accept(TypeVisitor *) const override;

  /// @brief Returns a string representation of the underlying type.
  /// @return type as string.
  std::string toString() const override;

  /// @brief Returns true if given param type is equal to this type.
  /// @param ParamType given param type.
  /// @return true if given param type is equal to this type and false
  /// otherwise.
  bool equals(const ParamType *) const override;

  /// Non-Common Methods ///

  /// @brief Returns the primitive enumeration of the type.
  /// @return primitive type.
  TypePrimitiveEnum getPrimitive() const { return Primitive; }

protected:
  /// An enumeration to identify the primitive type.
  TypePrimitiveEnum Primitive;
};

struct PointerType : public ParamType {
  /// An enumeration to identify the type id of this class.
  const static TypeEnum enumTy;

  /// @brief Constructor.
  /// @param RefParamType the type of pointee (that the pointer points at).
  PointerType(const RefParamType type);

  /// Implementation of Abstract Methods ///

  /// @brief Visitor service method. (see TypeVisitor for more details).
  ///        When overridden in subclasses, preform a 'double dispatch' to the
  ///        appropriate visit method in the given visitor.
  /// @param TypeVisitor type visitor
  MangleError accept(TypeVisitor *) const override;

  /// @brief Returns a string representation of the underlying type.
  /// @return type as string.
  std::string toString() const override;

  /// @brief Returns true if given param type is equal to this type.
  /// @param ParamType given param type.
  /// @return true if given param type is equal to this type and false
  /// otherwise.
  bool equals(const ParamType *) const override;

  /// Non-Common Methods ///

  /// @brief Returns the type the pointer is pointing at.
  /// @return pointee type.
  const RefParamType &getPointee() const { return PType; }

  /// @brief Sets the address space attribute - default is __private
  /// @param TypeAttributeEnum address space attribute id.
  void setAddressSpace(TypeAttributeEnum attr);

  /// @brief Returns the pointer's address space.
  /// @return pointer's address space.
  TypeAttributeEnum getAddressSpace() const;

  /// @brief Adds or removes a pointer's qualifier.
  /// @param TypeAttributeEnum qual - qualifier to add/remove.
  /// @param bool enabled - true if qualifier should exist false otherwise.
  ///        default is set to false.
  void setQualifier(TypeAttributeEnum qual, bool enabled);

  /// @brief Checks if the pointer has a certain qualifier.
  /// @param TypeAttributeEnum qual - qualifier to check.
  /// @return true if the qualifier exists and false otherwise.
  bool hasQualifier(TypeAttributeEnum qual) const;

private:
  /// The type this pointer is pointing at.
  RefParamType PType;
  /// Array of the pointer's enabled type qualifiers.
  bool Qualifiers[ATTR_QUALIFIER_LAST - ATTR_QUALIFIER_FIRST + 1];
  /// Pointer's address space.
  TypeAttributeEnum Address_space;
};

struct VectorType : public ParamType {
  /// An enumeration to identify the type id of this class.
  const static TypeEnum enumTy;

  /// @brief Constructor.
  /// @param RefParamType the type of each scalar element in the vector.
  /// @param int the length of the vector.
  VectorType(const RefParamType type, int len);

  /// Implementation of Abstract Methods ///

  /// @brief Visitor service method. (see TypeVisitor for more details).
  ///        When overridden in subclasses, preform a 'double dispatch' to the
  ///        appropriate visit method in the given visitor.
  /// @param TypeVisitor type visitor.
  MangleError accept(TypeVisitor *) const override;

  /// @brief Returns a string representation of the underlying type.
  /// @return type as string.
  std::string toString() const override;

  /// @brief Returns true if given param type is equal to this type.
  /// @param ParamType given param type.
  /// @return true if given param type is equal to this type and false
  /// otherwise.
  bool equals(const ParamType *) const override;

  /// Non-Common Methods ///

  /// @brief Returns the type the vector is packing.
  /// @return scalar type.
  const RefParamType &getScalarType() const { return PType; }

  /// @brief Returns the length of the vector type.
  /// @return vector type length.
  int getLength() const { return Len; }

private:
  /// The scalar type of this vector type.
  RefParamType PType;
  /// The length of the vector.
  int Len;
};

struct AtomicType : public ParamType {
  /// an enumeration to identify the type id of this class
  const static TypeEnum enumTy;

  /// @brief Constructor
  /// @param RefParamType the type refernced as atomic.
  AtomicType(const RefParamType type);

  /// Implementation of Abstract Methods ///

  /// @brief visitor service method. (see TypeVisitor for more details).
  ///       When overridden in subclasses, preform a 'double dispatch' to the
  ///       appropriate visit method in the given visitor.
  /// @param TypeVisitor type visitor
  MangleError accept(TypeVisitor *) const override;

  /// @brief returns a string representation of the underlying type.
  /// @return type as string
  std::string toString() const override;

  /// @brief returns true if given param type is equal to this type.
  /// @param ParamType given param type
  /// @return true if given param type is equal to this type and false otherwise
  bool equals(const ParamType *) const override;

  /// Non-Common Methods ///

  /// @brief returns the base type of the atomic parameter.
  /// @return base type
  const RefParamType &getBaseType() const { return PType; }

private:
  /// the type this pointer is pointing at
  RefParamType PType;
};

struct BlockType : public ParamType {
  /// an enumeration to identify the type id of this class
  const static TypeEnum enumTy;

  ///@brief Constructor
  BlockType();

  /// Implementation of Abstract Methods ///

  /// @brief visitor service method. (see TypeVisitor for more details).
  ///       When overridden in subclasses, preform a 'double dispatch' to the
  ///       appropriate visit method in the given visitor.
  /// @param TypeVisitor type visitor
  MangleError accept(TypeVisitor *) const override;

  /// @brief returns a string representation of the underlying type.
  /// @return type as string
  std::string toString() const override;

  /// @brief returns true if given param type is equal to this type.
  /// @param ParamType given param type
  /// @return true if given param type is equal to this type and false otherwise
  bool equals(const ParamType *) const override;

  /// Non-Common Methods ///

  /// @brief returns the number of parameters of the block.
  /// @return parameters count
  unsigned int getNumOfParams() const { return (unsigned int)Params.size(); }

  ///@brief returns the type of parameter "index" of the block.
  // @param index the sequential number of the queried parameter
  ///@return parameter type
  const RefParamType &getParam(unsigned int index) const {
    assert(Params.size() > index && "index is OOB");
    return Params[index];
  }

  ///@brief set the type of parameter "index" of the block.
  // @param index the sequential number of the queried parameter
  // @param type the parameter type
  void setParam(unsigned int index, RefParamType type) {
    if (index < getNumOfParams()) {
      Params[index] = type;
    } else if (index == getNumOfParams()) {
      Params.push_back(type);
    } else {
      assert(false && "index is OOB");
    }
  }

protected:
  /// an enumeration to identify the primitive type
  std::vector<RefParamType> Params;
};

struct UserDefinedType : public ParamType {
  /// An enumeration to identify the type id of this class.
  const static TypeEnum enumTy;

  /// @brief Constructor.
  UserDefinedType(const std::string &);

  /// Implementation of Abstract Methods ///

  /// @brief Visitor service method. (see TypeVisitor for more details).
  ///        When overridden in subclasses, preform a 'double dispatch' to the
  ///        appropriate visit method in the given visitor.
  /// @param TypeVisitor type visitor.
  MangleError accept(TypeVisitor *) const override;

  /// @brief Returns a string representation of the underlying type.
  /// @return type as string.
  std::string toString() const override;

  /// @brief Returns true if given param type is equal to this type.
  /// @param ParamType given param type.
  /// @return true if given param type is equal to this type and false
  /// otherwise.
  bool equals(const ParamType *) const override;

protected:
  /// The name of the user defined type.
  std::string Name;
};

/// @brief Can be overridden so an object of static type Type* will
///        dispatch the correct visit method according to its dynamic type.
struct TypeVisitor {
  SPIRversion spirVer;
  TypeVisitor(SPIRversion ver) : spirVer(ver) {}
  virtual ~TypeVisitor() {}
  virtual MangleError visit(const PrimitiveType *) = 0;
  virtual MangleError visit(const VectorType *) = 0;
  virtual MangleError visit(const PointerType *) = 0;
  virtual MangleError visit(const AtomicType *) = 0;
  virtual MangleError visit(const BlockType *) = 0;
  virtual MangleError visit(const UserDefinedType *) = 0;
};

/// @brief Template dynamic cast function for ParamType derived classes.
/// @param ParamType given param type.
/// @return required casting type if given param type is an instance if
//          that type, NULL otherwise.
template <typename T> T *dyn_cast(ParamType *pType) {
  assert(pType && "dyn_cast does not support casting of NULL");
  return (T::enumTy == pType->getTypeId()) ? (T *)pType : NULL;
}

/// @brief Template dynamic cast function for ParamType derived classes
///        (the constant version).
/// @param ParamType given param type.
/// @return required casting type if given param type is an instance if
//          that type, NULL otherwise.
template <typename T> const T *dyn_cast(const ParamType *pType) {
  assert(pType && "dyn_cast does not support casting of NULL");
  return (T::enumTy == pType->getTypeId()) ? (const T *)pType : NULL;
}

} // namespace SPIR
#endif // SPIRV_MANGLER_PARAMETERTYPE_H