1 //===- subzero/src/IceTypes.h - Primitive ICE types -------------*- C++ -*-===//
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 Declares a few properties of the primitive types allowed in Subzero.
12 /// Every Subzero source file is expected to include IceTypes.h.
13 ///
14 //===----------------------------------------------------------------------===//
15
16 #ifndef SUBZERO_SRC_ICETYPES_H
17 #define SUBZERO_SRC_ICETYPES_H
18
19 #include "IceDefs.h"
20 #include "IceTypes.def"
21
22 namespace Ice {
23
24 enum Type {
25 #define X(tag, sizeLog2, align, elts, elty, str, rcstr) IceType_##tag,
26 ICETYPE_TABLE
27 #undef X
28 IceType_NUM
29 };
30
31 /// RegClass indicates the physical register class that a Variable may be
32 /// register-allocated from. By default, a variable's register class is
33 /// directly associated with its type. However, the target lowering may define
34 /// additional target-specific register classes by extending the set of enum
35 /// values.
36 enum RegClass : uint8_t {
37 // Define RC_void, RC_i1, RC_i8, etc.
38 #define X(tag, sizeLog2, align, elts, elty, str, rcstr) \
39 RC_##tag = IceType_##tag,
40 ICETYPE_TABLE
41 #undef X
42 RC_Target,
43 // Leave plenty of space for target-specific values.
44 RC_Max = std::numeric_limits<uint8_t>::max()
45 };
46 static_assert(RC_Target == static_cast<RegClass>(IceType_NUM),
47 "Expected RC_Target and IceType_NUM to be the same");
48
49 enum TargetArch {
50 #define X(tag, str, is_elf64, e_machine, e_flags) tag,
51 TARGETARCH_TABLE
52 #undef X
53 TargetArch_NUM
54 };
55
56 const char *targetArchString(TargetArch Arch);
57
58 inline Ostream &operator<<(Ostream &Stream, TargetArch Arch) {
59 return Stream << targetArchString(Arch);
60 }
61
62 /// The list of all target instruction sets. Individual targets will map this to
63 /// include only what is valid for the target.
64 enum TargetInstructionSet {
65 // Represents baseline that can be assumed for a target (usually "Begin").
66 BaseInstructionSet,
67 X86InstructionSet_Begin,
68 X86InstructionSet_SSE2 = X86InstructionSet_Begin,
69 X86InstructionSet_SSE4_1,
70 X86InstructionSet_End,
71 ARM32InstructionSet_Begin,
72 ARM32InstructionSet_Neon = ARM32InstructionSet_Begin,
73 ARM32InstructionSet_HWDivArm,
74 ARM32InstructionSet_End,
75 };
76
77 enum OptLevel { Opt_m1, Opt_0, Opt_1, Opt_2 };
78
79 size_t typeWidthInBytes(Type Ty);
80 int8_t typeWidthInBytesLog2(Type Ty);
81 size_t typeAlignInBytes(Type Ty);
82 size_t typeNumElements(Type Ty);
83 Type typeElementType(Type Ty);
84 const char *typeString(Type Ty);
typeStdString(Type Ty)85 inline std::string typeStdString(Type Ty) { return typeString(Ty); }
86 const char *regClassString(RegClass C);
87
88 Type getPointerType();
89
90 bool isVectorType(Type Ty);
91
92 bool isBooleanType(Type Ty); // scalar or vector
93 bool isIntegerType(Type Ty); // scalar or vector
94 bool isScalarIntegerType(Type Ty);
95 bool isVectorIntegerType(Type Ty);
96 bool isIntegerArithmeticType(Type Ty);
97
98 bool isFloatingType(Type Ty); // scalar or vector
99 bool isScalarFloatingType(Type Ty);
100 bool isVectorFloatingType(Type Ty);
101
102 /// Returns true if the given type can be used in a load instruction.
103 bool isLoadStoreType(Type Ty);
104
105 /// Returns true if the given type can be used as a parameter type in a call.
106 bool isCallParameterType(Type Ty);
107
108 /// Returns true if the given type can be used as the return type of a call.
isCallReturnType(Type Ty)109 inline bool isCallReturnType(Type Ty) {
110 return Ty == IceType_void || isCallParameterType(Ty);
111 }
112
113 /// Returns type generated by applying the compare instructions (icmp and fcmp)
114 /// to arguments of the given type. Returns IceType_void if compare is not
115 /// allowed.
116 Type getCompareResultType(Type Ty);
117
118 /// Returns the number of bits in a scalar integer type.
119 SizeT getScalarIntBitWidth(Type Ty);
120
121 /// Check if a type is byte sized (slight optimization over typeWidthInBytes).
isByteSizedType(Type Ty)122 inline bool isByteSizedType(Type Ty) {
123 bool result = Ty == IceType_i8 || Ty == IceType_i1;
124 assert(result == (1 == typeWidthInBytes(Ty)));
125 return result;
126 }
127
128 /// Check if Ty is byte sized and specifically i8. Assert that it's not byte
129 /// sized due to being an i1.
isByteSizedArithType(Type Ty)130 inline bool isByteSizedArithType(Type Ty) {
131 assert(Ty != IceType_i1);
132 return Ty == IceType_i8;
133 }
134
135 /// Return true if Ty is i32. This asserts that Ty is either i32 or i64.
isInt32Asserting32Or64(Type Ty)136 inline bool isInt32Asserting32Or64(Type Ty) {
137 bool result = Ty == IceType_i32;
138 assert(result || Ty == IceType_i64);
139 return result;
140 }
141
142 /// Return true if Ty is f32. This asserts that Ty is either f32 or f64.
isFloat32Asserting32Or64(Type Ty)143 inline bool isFloat32Asserting32Or64(Type Ty) {
144 bool result = Ty == IceType_f32;
145 assert(result || Ty == IceType_f64);
146 return result;
147 }
148
149 template <typename StreamType>
150 inline StreamType &operator<<(StreamType &Str, const Type &Ty) {
151 Str << typeString(Ty);
152 return Str;
153 }
154
155 /// Models a type signature for a function.
156 class FuncSigType {
157 FuncSigType &operator=(const FuncSigType &Ty) = delete;
158
159 public:
160 using ArgListType = std::vector<Type>;
161
162 /// Creates a function signature type with the given return type. Parameter
163 /// types should be added using calls to appendArgType.
164 FuncSigType() = default;
165 FuncSigType(const FuncSigType &Ty) = default;
166
appendArgType(Type ArgType)167 void appendArgType(Type ArgType) { ArgList.push_back(ArgType); }
168
getReturnType()169 Type getReturnType() const { return ReturnType; }
setReturnType(Type NewType)170 void setReturnType(Type NewType) { ReturnType = NewType; }
getNumArgs()171 SizeT getNumArgs() const { return ArgList.size(); }
getArgType(SizeT Index)172 Type getArgType(SizeT Index) const {
173 assert(Index < ArgList.size());
174 return ArgList[Index];
175 }
getArgList()176 const ArgListType &getArgList() const { return ArgList; }
177 void dump(Ostream &Stream) const;
178
179 private:
180 /// The return type.
181 Type ReturnType = IceType_void;
182 /// The list of parameters.
183 ArgListType ArgList;
184 };
185
186 inline Ostream &operator<<(Ostream &Stream, const FuncSigType &Sig) {
187 Sig.dump(Stream);
188 return Stream;
189 }
190
191 } // end of namespace Ice
192
193 #endif // SUBZERO_SRC_ICETYPES_H
194