Chromium Code Reviews| Index: src/IceTypes.cpp |
| diff --git a/src/IceTypes.cpp b/src/IceTypes.cpp |
| index 0724e5146d116225e9351cf8074dc3c455d88446..2b10f6e35ecf0314773391c26cf468a9243b4f0c 100644 |
| --- a/src/IceTypes.cpp |
| +++ b/src/IceTypes.cpp |
| @@ -14,17 +14,76 @@ |
| #include "IceDefs.h" |
| #include "IceTypes.h" |
| +#include "llvm/ADT/STLExtras.h" |
| + |
| namespace Ice { |
| namespace { |
| -const struct { |
| +// Dummy function to make sure the two type tables have the same |
| +// enumerated types. |
| +void xIceTypeMacroIntegrityCheck() { |
|
jvoung (off chromium)
2014/07/31 16:18:29
you might have to put an "__attribute__((unused))"
Jim Stichnoth
2014/08/01 18:05:33
Definitely, as this had to be added in IceTargetLo
Karl
2014/08/25 17:46:53
Acknowledged.
Karl
2014/08/25 17:46:53
Done.
|
| + |
| + // 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, size, align, elts, elty, str) _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, IsIntAritArith) _props_table_tag_##tag, |
|
jvoung (off chromium)
2014/07/31 16:18:29
IsIntAritArith -> IsIntArith
Karl
2014/08/25 17:46:53
Done.
|
| + 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, size, align, elts, elty, str) \ |
| + STATIC_ASSERT((unsigned)_table_tag_##tag == (unsigned)_props_table_tag_##tag); |
| + ICETYPE_TABLE; |
| +#undef X |
| +// Assert that tags in ICETYPE_PROPS_TABLE is in ICETYPE_TABLE. |
| +#define X(tag, IsVec, IsInt, IsFloat, IsIntArith) \ |
| + STATIC_ASSERT((unsigned)_table_tag_##tag == (unsigned)_props_table_tag_##tag); |
| + 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, size, align, elts, elty, str) _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) \ |
| + _props_table_IsVec_##tag = IsVec, |
| + ICETYPE_PROPS_TABLE |
| +#undef X |
| + }; |
| +// Verify that the number of vector elements consistent with IsVec. |
|
jvoung (off chromium)
2014/07/31 16:18:29
number of vector elements *is* consistent with IsV
Karl
2014/08/25 17:46:53
Done.
|
| +#define X(tag, IsVec, IsInt, IsFloat, IsIntArith) \ |
| + STATIC_ASSERT((_table_elts_##tag > 1) == _props_table_IsVec_##tag); |
| + ICETYPE_PROPS_TABLE; |
| +#undef X |
| +} |
| + |
| +struct TypeAttributeFields { |
| size_t TypeWidthInBytes; |
| size_t TypeAlignInBytes; |
| size_t TypeNumElements; |
| Type TypeElementType; |
| const char *DisplayString; |
| -} TypeAttributes[] = { |
| +}; |
| + |
| +static const struct TypeAttributeFields TypeAttributes[] = { |
|
Jim Stichnoth
2014/08/01 18:05:34
Don't need "static" inside an anonymous namespace.
Karl
2014/08/25 17:46:53
Done.
|
| #define X(tag, size, align, elts, elty, str) \ |
| { size, align, elts, elty, str } \ |
| , |
| @@ -32,58 +91,119 @@ const struct { |
| #undef X |
| }; |
| -const size_t TypeAttributesSize = |
| - sizeof(TypeAttributes) / sizeof(*TypeAttributes); |
| +struct TypePropertyFields { |
| + bool TypeIsVectorType; |
| + bool TypeIsIntegerType; |
| + bool TypeIsScalarIntegerType; |
| + bool TypeIsVectorIntegerType; |
| + bool TypeIsIntegerArithmeticType; |
| + bool TypeIsFloatingType; |
| + bool TypeIsScalarFloatingType; |
| + bool TypeIsVectorFloatingType; |
| +}; |
| + |
| +static const TypePropertyFields TypePropertiesTable[] = { |
| +#define X(tag, IsVec, IsInt, IsFloat, IsIntArith) \ |
| + { \ |
| + IsVec, IsInt, IsInt && !IsVec, IsInt && IsVec, IsIntArith, IsFloat, \ |
| + IsFloat && !IsVec, IsFloat && IsVec \ |
| + } \ |
| + , |
| + ICETYPE_PROPS_TABLE |
| +#undef X |
| +}; |
| } // end anonymous namespace |
| size_t typeWidthInBytes(Type Ty) { |
| - size_t Width = 0; |
| size_t Index = static_cast<size_t>(Ty); |
| - if (Index < TypeAttributesSize) { |
| - Width = TypeAttributes[Index].TypeWidthInBytes; |
| - } else { |
| - llvm_unreachable("Invalid type for typeWidthInBytes()"); |
| - } |
| - return Width; |
| + if (Index < llvm::array_lengthof(TypeAttributes)) |
|
Jim Stichnoth
2014/08/01 18:05:33
For all instances of llvm::array_lengthof(TypeAttr
Karl
2014/08/25 17:46:53
Changed to use IceType_NUM.
|
| + return TypeAttributes[Index].TypeWidthInBytes; |
| + llvm_unreachable("Invalid type for typeWidthInBytes()"); |
|
jvoung (off chromium)
2014/07/31 16:18:29
Could you leave the return after llvm_unreachable?
Karl
2014/08/25 17:46:53
Done.
|
| } |
| size_t typeAlignInBytes(Type Ty) { |
| - size_t Align = 0; |
| size_t Index = static_cast<size_t>(Ty); |
| - if (Index < TypeAttributesSize) { |
| - Align = TypeAttributes[Index].TypeAlignInBytes; |
| - } else { |
| - llvm_unreachable("Invalid type for typeAlignInBytes()"); |
| - } |
| - return Align; |
| + if (Index < llvm::array_lengthof(TypeAttributes)) |
| + return TypeAttributes[Index].TypeAlignInBytes; |
| + llvm_unreachable("Invalid type for typeAlignInBytes()"); |
| } |
| size_t typeNumElements(Type Ty) { |
| - size_t NumElements = 0; |
| size_t Index = static_cast<size_t>(Ty); |
| - if (Index < TypeAttributesSize) { |
| - NumElements = TypeAttributes[Index].TypeNumElements; |
| - } else { |
| - llvm_unreachable("Invalid type for typeNumElements()"); |
| - } |
| - return NumElements; |
| + if (Index < llvm::array_lengthof(TypeAttributes)) |
| + return TypeAttributes[Index].TypeNumElements; |
| + llvm_unreachable("Invalid type for typeNumElements()"); |
| } |
| Type typeElementType(Type Ty) { |
| - Type ElementType = IceType_void; |
| size_t Index = static_cast<size_t>(Ty); |
| - if (Index < TypeAttributesSize) { |
| - ElementType = TypeAttributes[Index].TypeElementType; |
| - } else { |
| - llvm_unreachable("Invalid type for typeElementType()"); |
| - } |
| - return ElementType; |
| + if (Index < llvm::array_lengthof(TypeAttributes)) |
| + return TypeAttributes[Index].TypeElementType; |
| + llvm_unreachable("Invalid type for typeElementType()"); |
| +} |
| + |
| +bool isVectorType(Type Ty) { |
| + size_t Index = static_cast<size_t>(Ty); |
| + if (Index < llvm::array_lengthof(TypePropertiesTable)) |
| + return TypePropertiesTable[Index].TypeIsVectorType; |
| + llvm_unreachable("Invalid type for isVectorType()"); |
| +} |
| + |
| +bool isIntegerType(Type Ty) { |
| + size_t Index = static_cast<size_t>(Ty); |
| + if (Index < llvm::array_lengthof(TypePropertiesTable)) |
| + return TypePropertiesTable[Index].TypeIsIntegerType; |
| + llvm_unreachable("Invalid type for isIntegerType()"); |
| +} |
| + |
| +bool isScalarIntegerType(Type Ty) { |
| + size_t Index = static_cast<size_t>(Ty); |
| + if (Index < llvm::array_lengthof(TypePropertiesTable)) |
| + return TypePropertiesTable[Index].TypeIsScalarIntegerType; |
| + llvm_unreachable("Invalid type for isScalIntegerType()"); |
| +} |
| + |
| +bool isVectorIntegerType(Type Ty) { |
| + size_t Index = static_cast<size_t>(Ty); |
| + if (Index < llvm::array_lengthof(TypePropertiesTable)) |
| + return TypePropertiesTable[Index].TypeIsVectorIntegerType; |
| + llvm_unreachable("Invalid type for isVectorIntegerType()"); |
| } |
| +bool isIntegerArithmeticType(Type Ty) { |
| + size_t Index = static_cast<size_t>(Ty); |
| + if (Index < llvm::array_lengthof(TypePropertiesTable)) |
| + return TypePropertiesTable[Index].TypeIsIntegerArithmeticType; |
| + llvm_unreachable("Invalid type for isIntegerArithmeticType()"); |
| +} |
| + |
| +bool isFloatingType(Type Ty) { |
| + size_t Index = static_cast<size_t>(Ty); |
| + if (Index < llvm::array_lengthof(TypePropertiesTable)) |
| + return TypePropertiesTable[Index].TypeIsFloatingType; |
| + llvm_unreachable("Invalid type for isFloatingType()"); |
| +} |
| + |
| +bool isScalarFloatingType(Type Ty) { |
| + size_t Index = static_cast<size_t>(Ty); |
| + if (Index < llvm::array_lengthof(TypePropertiesTable)) |
| + return TypePropertiesTable[Index].TypeIsScalarFloatingType; |
| + llvm_unreachable("Invalid type for isScalarFloatingType()"); |
| +} |
| + |
| +bool isVectorFloatingType(Type Ty) { |
| + size_t Index = static_cast<size_t>(Ty); |
| + if (Index < llvm::array_lengthof(TypePropertiesTable)) |
| + return TypePropertiesTable[Index].TypeIsVectorFloatingType; |
| + llvm_unreachable("Invalid type for isVectorFloatingType()"); |
| +} |
| + |
| +// ======================== Dump routines ======================== // |
| + |
| const char *typeString(Type Ty) { |
| size_t Index = static_cast<size_t>(Ty); |
| - if (Index < TypeAttributesSize) { |
| + if (Index < llvm::array_lengthof(TypeAttributes)) { |
| return TypeAttributes[Index].DisplayString; |
| } |
| llvm_unreachable("Invalid type for typeString"); |