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
targetArchString(const TargetArch Arch)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
typeWidthInBytes(Type Ty)147 size_t typeWidthInBytes(Type Ty) {
148 int8_t Shift = typeWidthInBytesLog2(Ty);
149 return (Shift < 0) ? 0 : 1 << Shift;
150 }
151
typeWidthInBytesLog2(Type Ty)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
typeAlignInBytes(Type Ty)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
typeNumElements(Type Ty)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
typeElementType(Type Ty)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
getPointerType()180 Type getPointerType() { return TargetLowering::getPointerType(); }
181
isVectorType(Type Ty)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
isBooleanType(Type Ty)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
isIntegerType(Type Ty)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
isScalarIntegerType(Type Ty)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
isVectorIntegerType(Type Ty)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
isIntegerArithmeticType(Type Ty)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
isFloatingType(Type Ty)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
isScalarFloatingType(Type Ty)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
isVectorFloatingType(Type Ty)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
isLoadStoreType(Type Ty)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
isCallParameterType(Type Ty)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
getCompareResultType(Type Ty)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
getScalarIntBitWidth(Type Ty)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
typeString(Type Ty)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
regClassString(RegClass C)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
dump(Ostream & Stream) const289 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