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* 50 SPIRVType::getArrayElementType() const { 51 assert(OpCode == OpTypeArray && "Not array type"); 52 return static_cast<const SPIRVTypeArray *const>(this)->getElementType(); 53 } 54 55 uint64_t 56 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 63 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 72 SPIRVType::getFloatBitWidth()const { 73 assert(OpCode == OpTypeFloat && "Not an integer type"); 74 return static_cast<const SPIRVTypeFloat *const>(this)->getBitWidth(); 75 } 76 77 SPIRVWord 78 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 * 87 SPIRVType::getFunctionReturnType() const { 88 assert(OpCode == OpTypeFunction); 89 return static_cast<const SPIRVTypeFunction *const>(this)->getReturnType(); 90 } 91 92 SPIRVType * 93 SPIRVType::getPointerElementType()const { 94 assert(OpCode == OpTypePointer && "Not a pointer type"); 95 return static_cast<const SPIRVTypePointer *const>(this)->getElementType(); 96 } 97 98 SPIRVStorageClassKind 99 SPIRVType::getPointerStorageClass() const { 100 assert(OpCode == OpTypePointer && "Not a pointer type"); 101 return static_cast<const SPIRVTypePointer *const>(this)->getStorageClass(); 102 } 103 104 SPIRVType* 105 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 111 SPIRVType::getStructMemberCount() const { 112 assert(OpCode == OpTypeStruct && "Not struct type"); 113 return static_cast<const SPIRVTypeStruct *const>(this)->getMemberCount(); 114 } 115 116 SPIRVWord 117 SPIRVType::getVectorComponentCount() const { 118 assert(OpCode == OpTypeVector && "Not vector type"); 119 return static_cast<const SPIRVTypeVector *const>(this)->getComponentCount(); 120 } 121 122 SPIRVType* 123 SPIRVType::getVectorComponentType() const { 124 assert(OpCode == OpTypeVector && "Not vector type"); 125 return static_cast<const SPIRVTypeVector *const>(this)->getComponentType(); 126 } 127 128 bool 129 SPIRVType::isTypeVoid() const { 130 return OpCode == OpTypeVoid; 131 } 132 bool 133 SPIRVType::isTypeArray() const { 134 return OpCode == OpTypeArray; 135 } 136 137 bool 138 SPIRVType::isTypeBool()const { 139 return OpCode == OpTypeBool; 140 } 141 142 bool 143 SPIRVType::isTypeComposite() const { 144 return isTypeVector() || isTypeArray() || isTypeStruct(); 145 } 146 147 bool 148 SPIRVType::isTypeFloat(unsigned Bits)const { 149 return isType<SPIRVTypeFloat>(this, Bits); 150 } 151 152 bool 153 SPIRVType::isTypeOCLImage()const { 154 return isTypeImage() && static_cast<const SPIRVTypeImage *>(this)-> 155 isOCLImage(); 156 } 157 158 bool 159 SPIRVType::isTypePipe()const { 160 return OpCode == OpTypePipe; 161 } 162 163 bool 164 SPIRVType::isTypePipeStorage() const { 165 return OpCode == OpTypePipeStorage; 166 } 167 168 bool 169 SPIRVType::isTypeReserveId() const { 170 return OpCode == OpTypeReserveId; 171 } 172 173 bool 174 SPIRVType::isTypeInt(unsigned Bits)const { 175 return isType<SPIRVTypeInt>(this, Bits); 176 } 177 178 bool 179 SPIRVType::isTypePointer()const { 180 return OpCode == OpTypePointer; 181 } 182 183 bool 184 SPIRVType::isTypeOpaque()const { 185 return OpCode == OpTypeOpaque; 186 } 187 188 bool 189 SPIRVType::isTypeEvent()const { 190 return OpCode == OpTypeEvent; 191 } 192 193 bool 194 SPIRVType::isTypeDeviceEvent()const { 195 return OpCode == OpTypeDeviceEvent; 196 } 197 198 bool 199 SPIRVType::isTypeSampler()const { 200 return OpCode == OpTypeSampler; 201 } 202 203 bool 204 SPIRVType::isTypeImage()const { 205 return OpCode == OpTypeImage; 206 } 207 208 bool 209 SPIRVType::isTypeStruct() const { 210 return OpCode == OpTypeStruct; 211 } 212 213 bool 214 SPIRVType::isTypeVector() const { 215 return OpCode == OpTypeVector; 216 } 217 218 bool 219 SPIRVType::isTypeVectorBool() const { 220 return isTypeVector() && getVectorComponentType()->isTypeBool(); 221 } 222 223 bool 224 SPIRVType::isTypeVectorInt() const { 225 return isTypeVector() && getVectorComponentType()->isTypeInt(); 226 } 227 228 bool 229 SPIRVType::isTypeVectorFloat() const { 230 return isTypeVector() && getVectorComponentType()->isTypeFloat(); 231 } 232 233 bool 234 SPIRVType::isTypeVectorOrScalarBool() const { 235 return isTypeBool() || isTypeVectorBool(); 236 } 237 238 bool 239 SPIRVType::isTypeVectorOrScalarInt() const { 240 return isTypeInt() || isTypeVectorInt(); 241 } 242 243 bool 244 SPIRVType::isTypeVectorOrScalarFloat() const { 245 return isTypeFloat() || isTypeVectorFloat(); 246 } 247 248 bool 249 SPIRVTypeStruct::isPacked() const { 250 return hasDecorate(DecorationCPacked); 251 } 252 253 void 254 SPIRVTypeStruct::setPacked(bool Packed) { 255 if (Packed) 256 addDecorate(new SPIRVDecorate(DecorationCPacked, this)); 257 else 258 eraseDecorate(DecorationCPacked); 259 } 260 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 269 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* 277 SPIRVTypeArray::getLength() const { 278 return get<SPIRVConstant>(Length); 279 } 280 281 _SPIRV_IMP_ENCDEC3(SPIRVTypeArray, Id, ElemType, Length) 282 283 void SPIRVTypeForwardPointer::encode(spv_ostream &O) const { 284 getEncoder(O) << Pointer << SC; 285 } 286 287 void SPIRVTypeForwardPointer::decode(std::istream &I) { 288 auto Decoder = getDecoder(I); 289 SPIRVId PointerId; 290 Decoder >> PointerId >> SC; 291 } 292 } 293 294