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