| //===- subzero/src/IceTypes.cpp - Primitive type properties ---------------===// |
| // |
| // The Subzero Code Generator |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| /// |
| /// \file |
| /// \brief Defines a few attributes of Subzero primitive types. |
| /// |
| //===----------------------------------------------------------------------===// |
| |
| #include "IceTypes.h" |
| |
| #include "IceDefs.h" |
| #include "IceTargetLowering.h" |
| |
| #include "llvm/Support/ErrorHandling.h" |
| |
| #include <climits> |
| |
| namespace Ice { |
| |
| namespace { |
| |
| const char *TargetArchName[] = { |
| #define X(tag, str, is_elf64, e_machine, e_flags) str, |
| TARGETARCH_TABLE |
| #undef X |
| }; |
| |
| // Show tags match between ICETYPE_TABLE and ICETYPE_PROPS_TABLE. |
| |
| // Define a temporary set of enum values based on ICETYPE_TABLE |
| enum { |
| #define X(tag, sizeLog2, align, elts, elty, str, rcstr) _table_tag_##tag, |
| ICETYPE_TABLE |
| #undef X |
| _enum_table_tag_Names |
| }; |
| // Define a temporary set of enum values based on ICETYPE_PROPS_TABLE |
| enum { |
| #define X(tag, IsVec, IsInt, IsFloat, IsIntArith, IsLoadStore, IsParam, \ |
| CompareResult) \ |
| _props_table_tag_##tag, |
| ICETYPE_PROPS_TABLE |
| #undef X |
| _enum_props_table_tag_Names |
| }; |
| // Assert that tags in ICETYPE_TABLE are also in ICETYPE_PROPS_TABLE. |
| #define X(tag, sizeLog2, align, elts, elty, str, rcstr) \ |
| static_assert( \ |
| (unsigned)_table_tag_##tag == (unsigned)_props_table_tag_##tag, \ |
| "Inconsistency between ICETYPE_PROPS_TABLE and ICETYPE_TABLE"); |
| ICETYPE_TABLE |
| #undef X |
| // Assert that tags in ICETYPE_PROPS_TABLE is in ICETYPE_TABLE. |
| #define X(tag, IsVec, IsInt, IsFloat, IsIntArith, IsLoadStore, IsParam, \ |
| CompareResult) \ |
| static_assert( \ |
| (unsigned)_table_tag_##tag == (unsigned)_props_table_tag_##tag, \ |
| "Inconsistency between ICETYPE_PROPS_TABLE and ICETYPE_TABLE"); |
| ICETYPE_PROPS_TABLE |
| #undef X |
| |
| // Show vector definitions match in ICETYPE_TABLE and ICETYPE_PROPS_TABLE. |
| |
| // Define constants for each element size in ICETYPE_TABLE. |
| enum { |
| #define X(tag, sizeLog2, align, elts, elty, str, rcstr) \ |
| _table_elts_##tag = elts, |
| ICETYPE_TABLE |
| #undef X |
| _enum_table_elts_Elements = 0 |
| }; |
| // Define constants for boolean flag if vector in ICETYPE_PROPS_TABLE. |
| enum { |
| #define X(tag, IsVec, IsInt, IsFloat, IsIntArith, IsLoadStore, IsParam, \ |
| CompareResult) \ |
| _props_table_IsVec_##tag = IsVec, |
| ICETYPE_PROPS_TABLE |
| #undef X |
| }; |
| // Verify that the number of vector elements is consistent with IsVec. |
| #define X(tag, IsVec, IsInt, IsFloat, IsIntArith, IsLoadStore, IsParam, \ |
| CompareResult) \ |
| static_assert((_table_elts_##tag > 1) == _props_table_IsVec_##tag, \ |
| "Inconsistent vector specification in ICETYPE_PROPS_TABLE"); |
| ICETYPE_PROPS_TABLE |
| #undef X |
| |
| struct TypeAttributeFields { |
| int8_t TypeWidthInBytesLog2; |
| size_t TypeAlignInBytes; |
| size_t TypeNumElements; |
| Type TypeElementType; |
| const char *DisplayString; |
| const char *RegClassString; |
| }; |
| |
| const struct TypeAttributeFields TypeAttributes[] = { |
| #define X(tag, sizeLog2, align, elts, elty, str, rcstr) \ |
| {sizeLog2, align, elts, IceType_##elty, str, rcstr}, |
| ICETYPE_TABLE |
| #undef X |
| }; |
| |
| struct TypePropertyFields { |
| bool TypeIsVectorType; |
| bool TypeIsIntegerType; |
| bool TypeIsScalarIntegerType; |
| bool TypeIsVectorIntegerType; |
| bool TypeIsIntegerArithmeticType; |
| bool TypeIsFloatingType; |
| bool TypeIsScalarFloatingType; |
| bool TypeIsVectorFloatingType; |
| bool TypeIsBooleanType; |
| bool TypeIsCallParameterType; |
| Type CompareResultType; |
| }; |
| |
| const TypePropertyFields TypePropertiesTable[] = { |
| #define X(tag, IsVec, IsInt, IsFloat, IsIntArith, IsBoolean, IsParam, \ |
| CompareResult) \ |
| {IsVec, IsInt, IsInt & !IsVec, IsInt & IsVec, \ |
| IsIntArith, IsFloat, IsFloat & !IsVec, IsFloat & IsVec, \ |
| IsBoolean, IsParam, IceType_##CompareResult}, |
| ICETYPE_PROPS_TABLE |
| #undef X |
| }; |
| |
| } // end anonymous namespace |
| |
| const char *targetArchString(const TargetArch Arch) { |
| if (Arch < TargetArch_NUM) |
| return TargetArchName[Arch]; |
| llvm_unreachable("Invalid target arch for targetArchString"); |
| return "???"; |
| } |
| |
| size_t typeWidthInBytes(Type Ty) { |
| int8_t Shift = typeWidthInBytesLog2(Ty); |
| return (Shift < 0) ? 0 : 1 << Shift; |
| } |
| |
| int8_t typeWidthInBytesLog2(Type Ty) { |
| if (Ty < IceType_NUM) |
| return TypeAttributes[Ty].TypeWidthInBytesLog2; |
| llvm_unreachable("Invalid type for typeWidthInBytesLog2()"); |
| return 0; |
| } |
| |
| size_t typeAlignInBytes(Type Ty) { |
| if (Ty < IceType_NUM) |
| return TypeAttributes[Ty].TypeAlignInBytes; |
| llvm_unreachable("Invalid type for typeAlignInBytes()"); |
| return 1; |
| } |
| |
| size_t typeNumElements(Type Ty) { |
| if (Ty < IceType_NUM) |
| return TypeAttributes[Ty].TypeNumElements; |
| llvm_unreachable("Invalid type for typeNumElements()"); |
| return 1; |
| } |
| |
| Type typeElementType(Type Ty) { |
| if (Ty < IceType_NUM) |
| return TypeAttributes[Ty].TypeElementType; |
| llvm_unreachable("Invalid type for typeElementType()"); |
| return IceType_void; |
| } |
| |
| Type getPointerType() { return TargetLowering::getPointerType(); } |
| |
| bool isVectorType(Type Ty) { |
| if (Ty < IceType_NUM) |
| return TypePropertiesTable[Ty].TypeIsVectorType; |
| llvm_unreachable("Invalid type for isVectorType()"); |
| return false; |
| } |
| |
| bool isBooleanType(Type Ty) { |
| if (Ty < IceType_NUM) |
| return TypePropertiesTable[Ty].TypeIsBooleanType; |
| llvm_unreachable("Invalid type for isBooleanType()"); |
| return false; |
| } |
| |
| bool isIntegerType(Type Ty) { |
| if (Ty < IceType_NUM) |
| return TypePropertiesTable[Ty].TypeIsIntegerType; |
| llvm_unreachable("Invalid type for isIntegerType()"); |
| return false; |
| } |
| |
| bool isScalarIntegerType(Type Ty) { |
| if (Ty < IceType_NUM) |
| return TypePropertiesTable[Ty].TypeIsScalarIntegerType; |
| llvm_unreachable("Invalid type for isScalIntegerType()"); |
| return false; |
| } |
| |
| bool isVectorIntegerType(Type Ty) { |
| if (Ty < IceType_NUM) |
| return TypePropertiesTable[Ty].TypeIsVectorIntegerType; |
| llvm_unreachable("Invalid type for isVectorIntegerType()"); |
| return false; |
| } |
| |
| bool isIntegerArithmeticType(Type Ty) { |
| if (Ty < IceType_NUM) |
| return TypePropertiesTable[Ty].TypeIsIntegerArithmeticType; |
| llvm_unreachable("Invalid type for isIntegerArithmeticType()"); |
| return false; |
| } |
| |
| bool isFloatingType(Type Ty) { |
| if (Ty < IceType_NUM) |
| return TypePropertiesTable[Ty].TypeIsFloatingType; |
| llvm_unreachable("Invalid type for isFloatingType()"); |
| return false; |
| } |
| |
| bool isScalarFloatingType(Type Ty) { |
| if (Ty < IceType_NUM) |
| return TypePropertiesTable[Ty].TypeIsScalarFloatingType; |
| llvm_unreachable("Invalid type for isScalarFloatingType()"); |
| return false; |
| } |
| |
| bool isVectorFloatingType(Type Ty) { |
| if (Ty < IceType_NUM) |
| return TypePropertiesTable[Ty].TypeIsVectorFloatingType; |
| llvm_unreachable("Invalid type for isVectorFloatingType()"); |
| return false; |
| } |
| |
| bool isLoadStoreType(Type Ty) { |
| if (Ty < IceType_NUM) |
| return Ty != IceType_void && !isBooleanType(Ty); |
| llvm_unreachable("Invalid type for isLoadStoreType()"); |
| return false; |
| } |
| |
| bool isCallParameterType(Type Ty) { |
| if (Ty < IceType_NUM) |
| return TypePropertiesTable[Ty].TypeIsCallParameterType; |
| llvm_unreachable("Invalid type for isCallParameterType()"); |
| return false; |
| } |
| |
| Type getCompareResultType(Type Ty) { |
| if (Ty < IceType_NUM) |
| return TypePropertiesTable[Ty].CompareResultType; |
| llvm_unreachable("Invalid type for getCompareResultType"); |
| return IceType_void; |
| } |
| |
| SizeT getScalarIntBitWidth(Type Ty) { |
| assert(isScalarIntegerType(Ty)); |
| if (Ty == IceType_i1) |
| return 1; |
| return typeWidthInBytes(Ty) * CHAR_BIT; |
| } |
| |
| // ======================== Dump routines ======================== // |
| |
| const char *typeString(Type Ty) { |
| if (Ty < IceType_NUM) |
| return TypeAttributes[Ty].DisplayString; |
| llvm_unreachable("Invalid type for typeString"); |
| return "???"; |
| } |
| |
| const char *regClassString(RegClass C) { |
| if (static_cast<size_t>(C) < IceType_NUM) |
| return TypeAttributes[C].RegClassString; |
| llvm_unreachable("Invalid type for regClassString"); |
| return "???"; |
| } |
| |
| void FuncSigType::dump(Ostream &Stream) const { |
| if (!BuildDefs::dump()) |
| return; |
| Stream << ReturnType << " ("; |
| bool IsFirst = true; |
| for (const Type ArgTy : ArgList) { |
| if (IsFirst) { |
| IsFirst = false; |
| } else { |
| Stream << ", "; |
| } |
| Stream << ArgTy; |
| } |
| Stream << ")"; |
| } |
| |
| } // end of namespace Ice |