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); 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. 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). 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. 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. 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. 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 167 void appendArgType(Type ArgType) { ArgList.push_back(ArgType); } 168 169 Type getReturnType() const { return ReturnType; } 170 void setReturnType(Type NewType) { ReturnType = NewType; } 171 SizeT getNumArgs() const { return ArgList.size(); } 172 Type getArgType(SizeT Index) const { 173 assert(Index < ArgList.size()); 174 return ArgList[Index]; 175 } 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