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     ICETYPE_TABLE
107 #undef X
108 };
109 
110 struct TypePropertyFields {
111   bool TypeIsVectorType;
112   bool TypeIsIntegerType;
113   bool TypeIsScalarIntegerType;
114   bool TypeIsVectorIntegerType;
115   bool TypeIsIntegerArithmeticType;
116   bool TypeIsFloatingType;
117   bool TypeIsScalarFloatingType;
118   bool TypeIsVectorFloatingType;
119   bool TypeIsBooleanType;
120   bool TypeIsCallParameterType;
121   Type CompareResultType;
122 };
123 
124 const TypePropertyFields TypePropertiesTable[] = {
125 #define X(tag, IsVec, IsInt, IsFloat, IsIntArith, IsBoolean, IsParam,          \
126           CompareResult)                                                       \
127   {IsVec,      IsInt,   IsInt & !IsVec,         IsInt & IsVec,                 \
128    IsIntArith, IsFloat, IsFloat & !IsVec,       IsFloat & IsVec,               \
129    IsBoolean,  IsParam, IceType_##CompareResult},
130     ICETYPE_PROPS_TABLE
131 #undef X
132 };
133 
134 } // end anonymous namespace
135 
targetArchString(const TargetArch Arch)136 const char *targetArchString(const TargetArch Arch) {
137   if (Arch < TargetArch_NUM)
138     return TargetArchName[Arch];
139   llvm_unreachable("Invalid target arch for targetArchString");
140   return "???";
141 }
142 
typeWidthInBytes(Type Ty)143 size_t typeWidthInBytes(Type Ty) {
144   int8_t Shift = typeWidthInBytesLog2(Ty);
145   return (Shift < 0) ? 0 : 1 << Shift;
146 }
147 
typeWidthInBytesLog2(Type Ty)148 int8_t typeWidthInBytesLog2(Type Ty) {
149   if (Ty < IceType_NUM)
150     return TypeAttributes[Ty].TypeWidthInBytesLog2;
151   llvm_unreachable("Invalid type for typeWidthInBytesLog2()");
152   return 0;
153 }
154 
typeAlignInBytes(Type Ty)155 size_t typeAlignInBytes(Type Ty) {
156   if (Ty < IceType_NUM)
157     return TypeAttributes[Ty].TypeAlignInBytes;
158   llvm_unreachable("Invalid type for typeAlignInBytes()");
159   return 1;
160 }
161 
typeNumElements(Type Ty)162 size_t typeNumElements(Type Ty) {
163   if (Ty < IceType_NUM)
164     return TypeAttributes[Ty].TypeNumElements;
165   llvm_unreachable("Invalid type for typeNumElements()");
166   return 1;
167 }
168 
typeElementType(Type Ty)169 Type typeElementType(Type Ty) {
170   if (Ty < IceType_NUM)
171     return TypeAttributes[Ty].TypeElementType;
172   llvm_unreachable("Invalid type for typeElementType()");
173   return IceType_void;
174 }
175 
getPointerType()176 Type getPointerType() { return TargetLowering::getPointerType(); }
177 
isVectorType(Type Ty)178 bool isVectorType(Type Ty) {
179   if (Ty < IceType_NUM)
180     return TypePropertiesTable[Ty].TypeIsVectorType;
181   llvm_unreachable("Invalid type for isVectorType()");
182   return false;
183 }
184 
isBooleanType(Type Ty)185 bool isBooleanType(Type Ty) {
186   if (Ty < IceType_NUM)
187     return TypePropertiesTable[Ty].TypeIsBooleanType;
188   llvm_unreachable("Invalid type for isBooleanType()");
189   return false;
190 }
191 
isIntegerType(Type Ty)192 bool isIntegerType(Type Ty) {
193   if (Ty < IceType_NUM)
194     return TypePropertiesTable[Ty].TypeIsIntegerType;
195   llvm_unreachable("Invalid type for isIntegerType()");
196   return false;
197 }
198 
isScalarIntegerType(Type Ty)199 bool isScalarIntegerType(Type Ty) {
200   if (Ty < IceType_NUM)
201     return TypePropertiesTable[Ty].TypeIsScalarIntegerType;
202   llvm_unreachable("Invalid type for isScalIntegerType()");
203   return false;
204 }
205 
isVectorIntegerType(Type Ty)206 bool isVectorIntegerType(Type Ty) {
207   if (Ty < IceType_NUM)
208     return TypePropertiesTable[Ty].TypeIsVectorIntegerType;
209   llvm_unreachable("Invalid type for isVectorIntegerType()");
210   return false;
211 }
212 
isIntegerArithmeticType(Type Ty)213 bool isIntegerArithmeticType(Type Ty) {
214   if (Ty < IceType_NUM)
215     return TypePropertiesTable[Ty].TypeIsIntegerArithmeticType;
216   llvm_unreachable("Invalid type for isIntegerArithmeticType()");
217   return false;
218 }
219 
isFloatingType(Type Ty)220 bool isFloatingType(Type Ty) {
221   if (Ty < IceType_NUM)
222     return TypePropertiesTable[Ty].TypeIsFloatingType;
223   llvm_unreachable("Invalid type for isFloatingType()");
224   return false;
225 }
226 
isScalarFloatingType(Type Ty)227 bool isScalarFloatingType(Type Ty) {
228   if (Ty < IceType_NUM)
229     return TypePropertiesTable[Ty].TypeIsScalarFloatingType;
230   llvm_unreachable("Invalid type for isScalarFloatingType()");
231   return false;
232 }
233 
isVectorFloatingType(Type Ty)234 bool isVectorFloatingType(Type Ty) {
235   if (Ty < IceType_NUM)
236     return TypePropertiesTable[Ty].TypeIsVectorFloatingType;
237   llvm_unreachable("Invalid type for isVectorFloatingType()");
238   return false;
239 }
240 
isLoadStoreType(Type Ty)241 bool isLoadStoreType(Type Ty) {
242   if (Ty < IceType_NUM)
243     return Ty != IceType_void && !isBooleanType(Ty);
244   llvm_unreachable("Invalid type for isLoadStoreType()");
245   return false;
246 }
247 
isCallParameterType(Type Ty)248 bool isCallParameterType(Type Ty) {
249   if (Ty < IceType_NUM)
250     return TypePropertiesTable[Ty].TypeIsCallParameterType;
251   llvm_unreachable("Invalid type for isCallParameterType()");
252   return false;
253 }
254 
getCompareResultType(Type Ty)255 Type getCompareResultType(Type Ty) {
256   if (Ty < IceType_NUM)
257     return TypePropertiesTable[Ty].CompareResultType;
258   llvm_unreachable("Invalid type for getCompareResultType");
259   return IceType_void;
260 }
261 
getScalarIntBitWidth(Type Ty)262 SizeT getScalarIntBitWidth(Type Ty) {
263   assert(isScalarIntegerType(Ty));
264   if (Ty == IceType_i1)
265     return 1;
266   return typeWidthInBytes(Ty) * CHAR_BIT;
267 }
268 
269 // ======================== Dump routines ======================== //
270 
typeString(Type Ty)271 const char *typeString(Type Ty) {
272   if (Ty < IceType_NUM)
273     return TypeAttributes[Ty].DisplayString;
274   llvm_unreachable("Invalid type for typeString");
275   return "???";
276 }
277 
regClassString(RegClass C)278 const char *regClassString(RegClass C) {
279   if (static_cast<size_t>(C) < IceType_NUM)
280     return TypeAttributes[C].RegClassString;
281   llvm_unreachable("Invalid type for regClassString");
282   return "???";
283 }
284 
dump(Ostream & Stream) const285 void FuncSigType::dump(Ostream &Stream) const {
286   if (!BuildDefs::dump())
287     return;
288   Stream << ReturnType << " (";
289   bool IsFirst = true;
290   for (const Type ArgTy : ArgList) {
291     if (IsFirst) {
292       IsFirst = false;
293     } else {
294       Stream << ", ";
295     }
296     Stream << ArgTy;
297   }
298   Stream << ")";
299 }
300 
301 } // end of namespace Ice
302