Home | History | Annotate | Download | only in libSPIRV
      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