• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- SPIRVtype.cpp � Class to represent a SPIR-V type ----------*- C++ -*-===//
2 //
3 //                     The LLVM/SPIRV Translator
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 // Copyright (c) 2014 Advanced Micro Devices, Inc. All rights reserved.
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining a
11 // copy of this software and associated documentation files (the "Software"),
12 // to deal with the Software without restriction, including without limitation
13 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 // and/or sell copies of the Software, and to permit persons to whom the
15 // Software is furnished to do so, subject to the following conditions:
16 //
17 // Redistributions of source code must retain the above copyright notice,
18 // this list of conditions and the following disclaimers.
19 // Redistributions in binary form must reproduce the above copyright notice,
20 // this list of conditions and the following disclaimers in the documentation
21 // and/or other materials provided with the distribution.
22 // Neither the names of Advanced Micro Devices, Inc., nor the names of its
23 // contributors may be used to endorse or promote products derived from this
24 // Software without specific prior written permission.
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28 // CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
30 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH
31 // THE SOFTWARE.
32 //
33 //===----------------------------------------------------------------------===//
34 /// \file
35 ///
36 /// This file implements the types defined in SPIRV spec with op codes.
37 ///
38 //===----------------------------------------------------------------------===//
39 
40 #include "SPIRVType.h"
41 #include "SPIRVModule.h"
42 #include "SPIRVDecorate.h"
43 #include "SPIRVValue.h"
44 
45 #include <cassert>
46 
47 namespace SPIRV{
48 
49 SPIRVType*
getArrayElementType() const50 SPIRVType::getArrayElementType() const {
51   assert(OpCode == OpTypeArray && "Not array type");
52   return static_cast<const SPIRVTypeArray *const>(this)->getElementType();
53 }
54 
55 uint64_t
getArrayLength() const56 SPIRVType::getArrayLength() const {
57   assert(OpCode == OpTypeArray && "Not array type");
58   return static_cast<const SPIRVTypeArray *const>(this)->getLength()->
59       getZExtIntValue();
60 }
61 
62 SPIRVWord
getBitWidth() const63 SPIRVType::getBitWidth() const {
64   if (isTypeVector())
65     return getVectorComponentType()->getBitWidth();
66   if (isTypeBool())
67     return 1;
68   return isTypeInt()? getIntegerBitWidth() : getFloatBitWidth();
69 }
70 
71 SPIRVWord
getFloatBitWidth() const72 SPIRVType::getFloatBitWidth()const {
73   assert(OpCode == OpTypeFloat && "Not an integer type");
74   return static_cast<const SPIRVTypeFloat *const>(this)->getBitWidth();
75 }
76 
77 SPIRVWord
getIntegerBitWidth() const78 SPIRVType::getIntegerBitWidth()const {
79   assert((OpCode == OpTypeInt || OpCode == OpTypeBool) &&
80       "Not an integer type");
81   if (isTypeBool())
82     return 1;
83   return static_cast<const SPIRVTypeInt *const>(this)->getBitWidth();
84 }
85 
86 SPIRVType *
getFunctionReturnType() const87 SPIRVType::getFunctionReturnType() const {
88   assert(OpCode == OpTypeFunction);
89   return static_cast<const SPIRVTypeFunction *const>(this)->getReturnType();
90 }
91 
92 SPIRVType *
getPointerElementType() const93 SPIRVType::getPointerElementType()const {
94   assert(OpCode == OpTypePointer && "Not a pointer type");
95   return static_cast<const SPIRVTypePointer *const>(this)->getElementType();
96 }
97 
98 SPIRVStorageClassKind
getPointerStorageClass() const99 SPIRVType::getPointerStorageClass() const {
100   assert(OpCode == OpTypePointer && "Not a pointer type");
101   return static_cast<const SPIRVTypePointer *const>(this)->getStorageClass();
102 }
103 
104 SPIRVType*
getStructMemberType(size_t Index) const105 SPIRVType::getStructMemberType(size_t Index) const {
106   assert(OpCode == OpTypeStruct && "Not struct type");
107   return static_cast<const SPIRVTypeStruct *const>(this)->getMemberType(Index);
108 }
109 
110 SPIRVWord
getStructMemberCount() const111 SPIRVType::getStructMemberCount() const {
112   assert(OpCode == OpTypeStruct && "Not struct type");
113   return static_cast<const SPIRVTypeStruct *const>(this)->getMemberCount();
114 }
115 
116 SPIRVWord
getVectorComponentCount() const117 SPIRVType::getVectorComponentCount() const {
118   assert(OpCode == OpTypeVector && "Not vector type");
119   return static_cast<const SPIRVTypeVector *const>(this)->getComponentCount();
120 }
121 
122 SPIRVType*
getVectorComponentType() const123 SPIRVType::getVectorComponentType() const {
124   assert(OpCode == OpTypeVector && "Not vector type");
125   return static_cast<const SPIRVTypeVector *const>(this)->getComponentType();
126 }
127 
128 bool
isTypeVoid() const129 SPIRVType::isTypeVoid() const {
130   return OpCode == OpTypeVoid;
131 }
132 bool
isTypeArray() const133 SPIRVType::isTypeArray() const {
134   return OpCode == OpTypeArray;
135 }
136 
137 bool
isTypeBool() const138 SPIRVType::isTypeBool()const {
139   return OpCode == OpTypeBool;
140 }
141 
142 bool
isTypeComposite() const143 SPIRVType::isTypeComposite() const {
144   return isTypeVector() || isTypeArray() || isTypeStruct();
145 }
146 
147 bool
isTypeFloat(unsigned Bits) const148 SPIRVType::isTypeFloat(unsigned Bits)const {
149   return isType<SPIRVTypeFloat>(this, Bits);
150 }
151 
152 bool
isTypeOCLImage() const153 SPIRVType::isTypeOCLImage()const {
154   return isTypeImage() && static_cast<const SPIRVTypeImage *>(this)->
155     isOCLImage();
156 }
157 
158 bool
isTypePipe() const159 SPIRVType::isTypePipe()const {
160   return OpCode == OpTypePipe;
161 }
162 
163 bool
isTypePipeStorage() const164 SPIRVType::isTypePipeStorage() const {
165   return OpCode == OpTypePipeStorage;
166 }
167 
168 bool
isTypeReserveId() const169 SPIRVType::isTypeReserveId() const {
170   return OpCode == OpTypeReserveId;
171 }
172 
173 bool
isTypeInt(unsigned Bits) const174 SPIRVType::isTypeInt(unsigned Bits)const {
175   return isType<SPIRVTypeInt>(this, Bits);
176 }
177 
178 bool
isTypePointer() const179 SPIRVType::isTypePointer()const {
180   return OpCode == OpTypePointer;
181 }
182 
183 bool
isTypeOpaque() const184 SPIRVType::isTypeOpaque()const {
185   return OpCode == OpTypeOpaque;
186 }
187 
188 bool
isTypeEvent() const189 SPIRVType::isTypeEvent()const {
190   return OpCode == OpTypeEvent;
191 }
192 
193 bool
isTypeDeviceEvent() const194 SPIRVType::isTypeDeviceEvent()const {
195   return OpCode == OpTypeDeviceEvent;
196 }
197 
198 bool
isTypeSampler() const199 SPIRVType::isTypeSampler()const {
200   return OpCode == OpTypeSampler;
201 }
202 
203 bool
isTypeImage() const204 SPIRVType::isTypeImage()const {
205   return OpCode == OpTypeImage;
206 }
207 
208 bool
isTypeStruct() const209 SPIRVType::isTypeStruct() const {
210   return OpCode == OpTypeStruct;
211 }
212 
213 bool
isTypeVector() const214 SPIRVType::isTypeVector() const {
215   return OpCode == OpTypeVector;
216 }
217 
218 bool
isTypeVectorBool() const219 SPIRVType::isTypeVectorBool() const {
220   return isTypeVector() && getVectorComponentType()->isTypeBool();
221 }
222 
223 bool
isTypeVectorInt() const224 SPIRVType::isTypeVectorInt() const {
225   return isTypeVector() && getVectorComponentType()->isTypeInt();
226 }
227 
228 bool
isTypeVectorFloat() const229 SPIRVType::isTypeVectorFloat() const {
230   return isTypeVector() && getVectorComponentType()->isTypeFloat();
231 }
232 
233 bool
isTypeVectorOrScalarBool() const234 SPIRVType::isTypeVectorOrScalarBool() const {
235   return isTypeBool() || isTypeVectorBool();
236 }
237 
238 bool
isTypeVectorOrScalarInt() const239 SPIRVType::isTypeVectorOrScalarInt() const {
240   return isTypeInt() || isTypeVectorInt();
241 }
242 
243 bool
isTypeVectorOrScalarFloat() const244 SPIRVType::isTypeVectorOrScalarFloat() const {
245   return isTypeFloat() || isTypeVectorFloat();
246 }
247 
248 bool
isPacked() const249 SPIRVTypeStruct::isPacked() const {
250   return hasDecorate(DecorationCPacked);
251 }
252 
253 void
setPacked(bool Packed)254 SPIRVTypeStruct::setPacked(bool Packed) {
255   if (Packed)
256     addDecorate(new SPIRVDecorate(DecorationCPacked, this));
257   else
258     eraseDecorate(DecorationCPacked);
259 }
260 
SPIRVTypeArray(SPIRVModule * M,SPIRVId TheId,SPIRVType * TheElemType,SPIRVConstant * TheLength)261 SPIRVTypeArray::SPIRVTypeArray(SPIRVModule *M, SPIRVId TheId, SPIRVType *TheElemType,
262         SPIRVConstant* TheLength)
263       :SPIRVType(M, 4, OpTypeArray, TheId), ElemType(TheElemType),
264        Length(TheLength->getId()){
265       validate();
266     }
267 
268 void
validate() const269 SPIRVTypeArray::validate()const {
270   SPIRVEntry::validate();
271   ElemType->validate();
272   assert(getValue(Length)->getType()->isTypeInt() &&
273       get<SPIRVConstant>(Length)->getZExtIntValue() > 0);
274 }
275 
276 SPIRVConstant*
getLength() const277 SPIRVTypeArray::getLength() const {
278   return get<SPIRVConstant>(Length);
279 }
280 
_SPIRV_IMP_ENCDEC3(SPIRVTypeArray,Id,ElemType,Length)281 _SPIRV_IMP_ENCDEC3(SPIRVTypeArray, Id, ElemType, Length)
282 
283 void SPIRVTypeForwardPointer::encode(spv_ostream &O) const {
284   getEncoder(O) << Pointer << SC;
285 }
286 
decode(std::istream & I)287 void SPIRVTypeForwardPointer::decode(std::istream &I) {
288   auto Decoder = getDecoder(I);
289   SPIRVId PointerId;
290   Decoder >> PointerId >> SC;
291 }
292 }
293 
294