Home | History | Annotate | Download | only in src
      1 //===- subzero/src/IceTypes.cpp - Primitive type properties ---------------===//
      2 //
      3 //                        The Subzero Code Generator
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 ///
     10 /// \file
     11 /// \brief Defines a few attributes of Subzero primitive types.
     12 ///
     13 //===----------------------------------------------------------------------===//
     14 
     15 #include "IceTypes.h"
     16 
     17 #include "IceDefs.h"
     18 #include "IceTargetLowering.h"
     19 
     20 #include "llvm/Support/ErrorHandling.h"
     21 
     22 #include <climits>
     23 
     24 namespace Ice {
     25 
     26 namespace {
     27 
     28 const char *TargetArchName[] = {
     29 #define X(tag, str, is_elf64, e_machine, e_flags) str,
     30     TARGETARCH_TABLE
     31 #undef X
     32 };
     33 
     34 // Show tags match between ICETYPE_TABLE and ICETYPE_PROPS_TABLE.
     35 
     36 // Define a temporary set of enum values based on ICETYPE_TABLE
     37 enum {
     38 #define X(tag, sizeLog2, align, elts, elty, str, rcstr) _table_tag_##tag,
     39   ICETYPE_TABLE
     40 #undef X
     41       _enum_table_tag_Names
     42 };
     43 // Define a temporary set of enum values based on ICETYPE_PROPS_TABLE
     44 enum {
     45 #define X(tag, IsVec, IsInt, IsFloat, IsIntArith, IsLoadStore, IsParam,        \
     46           CompareResult)                                                       \
     47   _props_table_tag_##tag,
     48   ICETYPE_PROPS_TABLE
     49 #undef X
     50       _enum_props_table_tag_Names
     51 };
     52 // Assert that tags in ICETYPE_TABLE are also in ICETYPE_PROPS_TABLE.
     53 #define X(tag, sizeLog2, align, elts, elty, str, rcstr)                        \
     54   static_assert(                                                               \
     55       (unsigned)_table_tag_##tag == (unsigned)_props_table_tag_##tag,          \
     56       "Inconsistency between ICETYPE_PROPS_TABLE and ICETYPE_TABLE");
     57 ICETYPE_TABLE
     58 #undef X
     59 // Assert that tags in ICETYPE_PROPS_TABLE is in ICETYPE_TABLE.
     60 #define X(tag, IsVec, IsInt, IsFloat, IsIntArith, IsLoadStore, IsParam,        \
     61           CompareResult)                                                       \
     62   static_assert(                                                               \
     63       (unsigned)_table_tag_##tag == (unsigned)_props_table_tag_##tag,          \
     64       "Inconsistency between ICETYPE_PROPS_TABLE and ICETYPE_TABLE");
     65 ICETYPE_PROPS_TABLE
     66 #undef X
     67 
     68 // Show vector definitions match in ICETYPE_TABLE and ICETYPE_PROPS_TABLE.
     69 
     70 // Define constants for each element size in ICETYPE_TABLE.
     71 enum {
     72 #define X(tag, sizeLog2, align, elts, elty, str, rcstr)                        \
     73   _table_elts_##tag = elts,
     74   ICETYPE_TABLE
     75 #undef X
     76       _enum_table_elts_Elements = 0
     77 };
     78 // Define constants for boolean flag if vector in ICETYPE_PROPS_TABLE.
     79 enum {
     80 #define X(tag, IsVec, IsInt, IsFloat, IsIntArith, IsLoadStore, IsParam,        \
     81           CompareResult)                                                       \
     82   _props_table_IsVec_##tag = IsVec,
     83   ICETYPE_PROPS_TABLE
     84 #undef X
     85 };
     86 // Verify that the number of vector elements is consistent with IsVec.
     87 #define X(tag, IsVec, IsInt, IsFloat, IsIntArith, IsLoadStore, IsParam,        \
     88           CompareResult)                                                       \
     89   static_assert((_table_elts_##tag > 1) == _props_table_IsVec_##tag,           \
     90                 "Inconsistent vector specification in ICETYPE_PROPS_TABLE");
     91 ICETYPE_PROPS_TABLE
     92 #undef X
     93 
     94 struct TypeAttributeFields {
     95   int8_t TypeWidthInBytesLog2;
     96   size_t TypeAlignInBytes;
     97   size_t TypeNumElements;
     98   Type TypeElementType;
     99   const char *DisplayString;
    100   const char *RegClassString;
    101 };
    102 
    103 const struct TypeAttributeFields TypeAttributes[] = {
    104 #define X(tag, sizeLog2, align, elts, elty, str, rcstr)                        \
    105   { sizeLog2, align, elts, IceType_##elty, str, rcstr }                        \
    106   ,
    107     ICETYPE_TABLE
    108 #undef X
    109 };
    110 
    111 struct TypePropertyFields {
    112   bool TypeIsVectorType;
    113   bool TypeIsIntegerType;
    114   bool TypeIsScalarIntegerType;
    115   bool TypeIsVectorIntegerType;
    116   bool TypeIsIntegerArithmeticType;
    117   bool TypeIsFloatingType;
    118   bool TypeIsScalarFloatingType;
    119   bool TypeIsVectorFloatingType;
    120   bool TypeIsBooleanType;
    121   bool TypeIsCallParameterType;
    122   Type CompareResultType;
    123 };
    124 
    125 const TypePropertyFields TypePropertiesTable[] = {
    126 #define X(tag, IsVec, IsInt, IsFloat, IsIntArith, IsBoolean, IsParam,          \
    127           CompareResult)                                                       \
    128   {                                                                            \
    129     IsVec, IsInt, IsInt & !IsVec, IsInt & IsVec, IsIntArith, IsFloat,          \
    130         IsFloat & !IsVec, IsFloat & IsVec, IsBoolean, IsParam,                 \
    131         IceType_##CompareResult                                                \
    132   }                                                                            \
    133   ,
    134     ICETYPE_PROPS_TABLE
    135 #undef X
    136 };
    137 
    138 } // end anonymous namespace
    139 
    140 const char *targetArchString(const TargetArch Arch) {
    141   if (Arch < TargetArch_NUM)
    142     return TargetArchName[Arch];
    143   llvm_unreachable("Invalid target arch for targetArchString");
    144   return "???";
    145 }
    146 
    147 size_t typeWidthInBytes(Type Ty) {
    148   int8_t Shift = typeWidthInBytesLog2(Ty);
    149   return (Shift < 0) ? 0 : 1 << Shift;
    150 }
    151 
    152 int8_t typeWidthInBytesLog2(Type Ty) {
    153   if (Ty < IceType_NUM)
    154     return TypeAttributes[Ty].TypeWidthInBytesLog2;
    155   llvm_unreachable("Invalid type for typeWidthInBytesLog2()");
    156   return 0;
    157 }
    158 
    159 size_t typeAlignInBytes(Type Ty) {
    160   if (Ty < IceType_NUM)
    161     return TypeAttributes[Ty].TypeAlignInBytes;
    162   llvm_unreachable("Invalid type for typeAlignInBytes()");
    163   return 1;
    164 }
    165 
    166 size_t typeNumElements(Type Ty) {
    167   if (Ty < IceType_NUM)
    168     return TypeAttributes[Ty].TypeNumElements;
    169   llvm_unreachable("Invalid type for typeNumElements()");
    170   return 1;
    171 }
    172 
    173 Type typeElementType(Type Ty) {
    174   if (Ty < IceType_NUM)
    175     return TypeAttributes[Ty].TypeElementType;
    176   llvm_unreachable("Invalid type for typeElementType()");
    177   return IceType_void;
    178 }
    179 
    180 Type getPointerType() { return TargetLowering::getPointerType(); }
    181 
    182 bool isVectorType(Type Ty) {
    183   if (Ty < IceType_NUM)
    184     return TypePropertiesTable[Ty].TypeIsVectorType;
    185   llvm_unreachable("Invalid type for isVectorType()");
    186   return false;
    187 }
    188 
    189 bool isBooleanType(Type Ty) {
    190   if (Ty < IceType_NUM)
    191     return TypePropertiesTable[Ty].TypeIsBooleanType;
    192   llvm_unreachable("Invalid type for isBooleanType()");
    193   return false;
    194 }
    195 
    196 bool isIntegerType(Type Ty) {
    197   if (Ty < IceType_NUM)
    198     return TypePropertiesTable[Ty].TypeIsIntegerType;
    199   llvm_unreachable("Invalid type for isIntegerType()");
    200   return false;
    201 }
    202 
    203 bool isScalarIntegerType(Type Ty) {
    204   if (Ty < IceType_NUM)
    205     return TypePropertiesTable[Ty].TypeIsScalarIntegerType;
    206   llvm_unreachable("Invalid type for isScalIntegerType()");
    207   return false;
    208 }
    209 
    210 bool isVectorIntegerType(Type Ty) {
    211   if (Ty < IceType_NUM)
    212     return TypePropertiesTable[Ty].TypeIsVectorIntegerType;
    213   llvm_unreachable("Invalid type for isVectorIntegerType()");
    214   return false;
    215 }
    216 
    217 bool isIntegerArithmeticType(Type Ty) {
    218   if (Ty < IceType_NUM)
    219     return TypePropertiesTable[Ty].TypeIsIntegerArithmeticType;
    220   llvm_unreachable("Invalid type for isIntegerArithmeticType()");
    221   return false;
    222 }
    223 
    224 bool isFloatingType(Type Ty) {
    225   if (Ty < IceType_NUM)
    226     return TypePropertiesTable[Ty].TypeIsFloatingType;
    227   llvm_unreachable("Invalid type for isFloatingType()");
    228   return false;
    229 }
    230 
    231 bool isScalarFloatingType(Type Ty) {
    232   if (Ty < IceType_NUM)
    233     return TypePropertiesTable[Ty].TypeIsScalarFloatingType;
    234   llvm_unreachable("Invalid type for isScalarFloatingType()");
    235   return false;
    236 }
    237 
    238 bool isVectorFloatingType(Type Ty) {
    239   if (Ty < IceType_NUM)
    240     return TypePropertiesTable[Ty].TypeIsVectorFloatingType;
    241   llvm_unreachable("Invalid type for isVectorFloatingType()");
    242   return false;
    243 }
    244 
    245 bool isLoadStoreType(Type Ty) {
    246   if (Ty < IceType_NUM)
    247     return Ty != IceType_void && !isBooleanType(Ty);
    248   llvm_unreachable("Invalid type for isLoadStoreType()");
    249   return false;
    250 }
    251 
    252 bool isCallParameterType(Type Ty) {
    253   if (Ty < IceType_NUM)
    254     return TypePropertiesTable[Ty].TypeIsCallParameterType;
    255   llvm_unreachable("Invalid type for isCallParameterType()");
    256   return false;
    257 }
    258 
    259 Type getCompareResultType(Type Ty) {
    260   if (Ty < IceType_NUM)
    261     return TypePropertiesTable[Ty].CompareResultType;
    262   llvm_unreachable("Invalid type for getCompareResultType");
    263   return IceType_void;
    264 }
    265 
    266 SizeT getScalarIntBitWidth(Type Ty) {
    267   assert(isScalarIntegerType(Ty));
    268   if (Ty == IceType_i1)
    269     return 1;
    270   return typeWidthInBytes(Ty) * CHAR_BIT;
    271 }
    272 
    273 // ======================== Dump routines ======================== //
    274 
    275 const char *typeString(Type Ty) {
    276   if (Ty < IceType_NUM)
    277     return TypeAttributes[Ty].DisplayString;
    278   llvm_unreachable("Invalid type for typeString");
    279   return "???";
    280 }
    281 
    282 const char *regClassString(RegClass C) {
    283   if (static_cast<size_t>(C) < IceType_NUM)
    284     return TypeAttributes[C].RegClassString;
    285   llvm_unreachable("Invalid type for regClassString");
    286   return "???";
    287 }
    288 
    289 void FuncSigType::dump(Ostream &Stream) const {
    290   if (!BuildDefs::dump())
    291     return;
    292   Stream << ReturnType << " (";
    293   bool IsFirst = true;
    294   for (const Type ArgTy : ArgList) {
    295     if (IsFirst) {
    296       IsFirst = false;
    297     } else {
    298       Stream << ", ";
    299     }
    300     Stream << ArgTy;
    301   }
    302   Stream << ")";
    303 }
    304 
    305 } // end of namespace Ice
    306