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