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