• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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