From b0cc341fd953d45f6418b2cbc646706eb3ad3bc5 Mon Sep 17 00:00:00 2001 From: Richard Guenther Date: Tue, 20 Oct 2009 11:08:30 +0000 Subject: [PATCH] gimple.c (gimple_types_compatible_p): Simplify. 2009-10-20 Richard Guenther * gimple.c (gimple_types_compatible_p): Simplify. Move cheap checks before hashtable queries. Add checks for TYPE_NONALIASED_COMPONENT and DECL_NONADDRESSABLE_P. From-SVN: r153010 --- gcc/ChangeLog | 6 ++ gcc/gimple.c | 175 ++++++++++++++++++++++++-------------------------- 2 files changed, 91 insertions(+), 90 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 739cdb574be..a631aaa738d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2009-10-20 Richard Guenther + + * gimple.c (gimple_types_compatible_p): Simplify. Move + cheap checks before hashtable queries. Add checks for + TYPE_NONALIASED_COMPONENT and DECL_NONADDRESSABLE_P. + 2009-10-20 Eric Botcazou * tree-sra.c (build_ref_for_offset_1) : Skip fields diff --git a/gcc/gimple.c b/gcc/gimple.c index 80c2cf46831..d5b1cf7f1c7 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -3174,23 +3174,57 @@ gimple_types_compatible_p (tree t1, tree t2) /* Check first for the obvious case of pointer identity. */ if (t1 == t2) - goto same_types; + return 1; /* Check that we have two types to compare. */ if (t1 == NULL_TREE || t2 == NULL_TREE) - goto different_types; + return 0; /* Can't be the same type if the types don't have the same code. */ if (TREE_CODE (t1) != TREE_CODE (t2)) - goto different_types; - - /* Void types are always the same. */ - if (TREE_CODE (t1) == VOID_TYPE) - goto same_types; + return 0; /* Can't be the same type if they have different CV qualifiers. */ if (TYPE_QUALS (t1) != TYPE_QUALS (t2)) - goto different_types; + return 0; + + /* Void types are always the same. */ + if (TREE_CODE (t1) == VOID_TYPE) + return 1; + + /* For numerical types do some simple checks before doing three + hashtable queries. */ + if (INTEGRAL_TYPE_P (t1) + || SCALAR_FLOAT_TYPE_P (t1) + || FIXED_POINT_TYPE_P (t1) + || TREE_CODE (t1) == VECTOR_TYPE + || TREE_CODE (t1) == COMPLEX_TYPE) + { + /* Can't be the same type if they have different alignment, + sign, precision or mode. */ + if (TYPE_ALIGN (t1) != TYPE_ALIGN (t2) + || TYPE_PRECISION (t1) != TYPE_PRECISION (t2) + || TYPE_MODE (t1) != TYPE_MODE (t2) + || TYPE_UNSIGNED (t1) != TYPE_UNSIGNED (t2)) + return 0; + + if (TREE_CODE (t1) == INTEGER_TYPE + && (TYPE_IS_SIZETYPE (t1) != TYPE_IS_SIZETYPE (t2) + || TYPE_STRING_FLAG (t1) != TYPE_STRING_FLAG (t2))) + return 0; + + /* That's all we need to check for float and fixed-point types. */ + if (SCALAR_FLOAT_TYPE_P (t1) + || FIXED_POINT_TYPE_P (t1)) + return 1; + + /* Perform cheap tail-recursion for vector and complex types. */ + if (TREE_CODE (t1) == VECTOR_TYPE + || TREE_CODE (t1) == COMPLEX_TYPE) + return gimple_types_compatible_p (TREE_TYPE (t1), TREE_TYPE (t2)); + + /* For integral types fall thru to more complex checks. */ + } /* If the hash values of t1 and t2 are different the types can't possibly be the same. This helps keeping the type-pair hashtable @@ -3223,71 +3257,6 @@ gimple_types_compatible_p (tree t1, tree t2) if (!attribute_list_equal (TYPE_ATTRIBUTES (t1), TYPE_ATTRIBUTES (t2))) goto different_types; - /* For numerical types, the bounds must coincide. */ - if (INTEGRAL_TYPE_P (t1) - || SCALAR_FLOAT_TYPE_P (t1) - || FIXED_POINT_TYPE_P (t1)) - { - /* Can't be the same type if they have different size, alignment, - sign, precision or mode. Note that from now on, comparisons - between *_CST nodes must be done using tree_int_cst_equal because - we cannot assume that constants from T1 and T2 will be shared - since T1 and T2 are distinct pointers. */ - if (!tree_int_cst_equal (TYPE_SIZE (t1), TYPE_SIZE (t2)) - || !tree_int_cst_equal (TYPE_SIZE_UNIT (t1), TYPE_SIZE_UNIT (t2)) - || TYPE_ALIGN (t1) != TYPE_ALIGN (t2) - || TYPE_PRECISION (t1) != TYPE_PRECISION (t2) - || TYPE_MODE (t1) != TYPE_MODE (t2) - || TYPE_UNSIGNED (t1) != TYPE_UNSIGNED (t2)) - goto different_types; - - /* For non-enumeral types, check type bounds. FIXME lto, we - cannot check bounds on enumeral types because different front - ends will produce different values. In C, enumeral types are - integers, while in C++ each element will have its own - symbolic value. We should decide how enums are to be - represented in GIMPLE and have each front end lower to that. */ - if (TREE_CODE (t1) != ENUMERAL_TYPE) - { - tree min1 = TYPE_MIN_VALUE (t1); - tree max1 = TYPE_MAX_VALUE (t1); - tree min2 = TYPE_MIN_VALUE (t2); - tree max2 = TYPE_MAX_VALUE (t2); - bool min_equal_p = false; - bool max_equal_p = false; - - /* If either type has a minimum value, the other type must - have the same. */ - if (min1 == NULL_TREE && min2 == NULL_TREE) - min_equal_p = true; - else if (min1 && min2 && operand_equal_p (min1, min2, 0)) - min_equal_p = true; - - /* Likewise, if either type has a maximum value, the other - type must have the same. */ - if (max1 == NULL_TREE && max2 == NULL_TREE) - max_equal_p = true; - else if (max1 && max2 && operand_equal_p (max1, max2, 0)) - max_equal_p = true; - - if (!min_equal_p || !max_equal_p) - goto different_types; - } - - if (TREE_CODE (t1) == INTEGER_TYPE) - { - if (TYPE_IS_SIZETYPE (t1) == TYPE_IS_SIZETYPE (t2) - && TYPE_STRING_FLAG (t1) == TYPE_STRING_FLAG (t2)) - goto same_types; - else - goto different_types; - } - else if (TREE_CODE (t1) == BOOLEAN_TYPE) - goto same_types; - else if (TREE_CODE (t1) == REAL_TYPE) - goto same_types; - } - /* Do type-specific comparisons. */ switch (TREE_CODE (t1)) { @@ -3295,7 +3264,8 @@ gimple_types_compatible_p (tree t1, tree t2) /* Array types are the same if the element types are the same and the number of elements are the same. */ if (!gimple_types_compatible_p (TREE_TYPE (t1), TREE_TYPE (t2)) - || TYPE_STRING_FLAG (t1) != TYPE_STRING_FLAG (t2)) + || TYPE_STRING_FLAG (t1) != TYPE_STRING_FLAG (t2) + || TYPE_NONALIASED_COMPONENT (t1) != TYPE_NONALIASED_COMPONENT (t2)) goto different_types; else { @@ -3406,11 +3376,47 @@ gimple_types_compatible_p (tree t1, tree t2) goto different_types; } + case INTEGER_TYPE: + case BOOLEAN_TYPE: + { + tree min1 = TYPE_MIN_VALUE (t1); + tree max1 = TYPE_MAX_VALUE (t1); + tree min2 = TYPE_MIN_VALUE (t2); + tree max2 = TYPE_MAX_VALUE (t2); + bool min_equal_p = false; + bool max_equal_p = false; + + /* If either type has a minimum value, the other type must + have the same. */ + if (min1 == NULL_TREE && min2 == NULL_TREE) + min_equal_p = true; + else if (min1 && min2 && operand_equal_p (min1, min2, 0)) + min_equal_p = true; + + /* Likewise, if either type has a maximum value, the other + type must have the same. */ + if (max1 == NULL_TREE && max2 == NULL_TREE) + max_equal_p = true; + else if (max1 && max2 && operand_equal_p (max1, max2, 0)) + max_equal_p = true; + + if (!min_equal_p || !max_equal_p) + goto different_types; + + goto same_types; + } + case ENUMERAL_TYPE: { - /* For enumeral types, all the values must be the same. */ + /* FIXME lto, we cannot check bounds on enumeral types because + different front ends will produce different values. + In C, enumeral types are integers, while in C++ each element + will have its own symbolic value. We should decide how enums + are to be represented in GIMPLE and have each front end lower + to that. */ tree v1, v2; + /* For enumeral types, all the values must be the same. */ if (TYPE_VALUES (t1) == TYPE_VALUES (t2)) goto same_types; @@ -3463,6 +3469,7 @@ gimple_types_compatible_p (tree t1, tree t2) { /* The fields must have the same name, offset and type. */ if (DECL_NAME (f1) != DECL_NAME (f2) + || DECL_NONADDRESSABLE_P (f1) != DECL_NONADDRESSABLE_P (f2) || !compare_field_offset (f1, f2) || !gimple_types_compatible_p (TREE_TYPE (f1), TREE_TYPE (f2))) @@ -3477,30 +3484,18 @@ gimple_types_compatible_p (tree t1, tree t2) goto same_types; } - case VECTOR_TYPE: - if (TYPE_VECTOR_SUBPARTS (t1) != TYPE_VECTOR_SUBPARTS (t2)) - goto different_types; - - /* Fallthru */ - case COMPLEX_TYPE: - if (!gimple_types_compatible_p (TREE_TYPE (t1), TREE_TYPE (t2))) - goto different_types; - goto same_types; - default: - goto different_types; + gcc_unreachable (); } /* Common exit path for types that are not compatible. */ different_types: - if (p) - p->same_p = 0; + p->same_p = 0; return 0; /* Common exit path for types that are compatible. */ same_types: - if (p) - p->same_p = 1; + p->same_p = 1; return 1; }