aboutsummaryrefslogtreecommitdiff
path: root/gcc/gimple.c
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2009-10-20 11:08:30 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2009-10-20 11:08:30 +0000
commitb0cc341fd953d45f6418b2cbc646706eb3ad3bc5 (patch)
tree15e07df0ee5584959d0495ab360916b560328424 /gcc/gimple.c
parenta1aa17011f52bffc0f3022bc32d87222270dfb8b (diff)
downloadgcc-b0cc341fd953d45f6418b2cbc646706eb3ad3bc5.zip
gcc-b0cc341fd953d45f6418b2cbc646706eb3ad3bc5.tar.gz
gcc-b0cc341fd953d45f6418b2cbc646706eb3ad3bc5.tar.bz2
gimple.c (gimple_types_compatible_p): Simplify.
2009-10-20 Richard Guenther <rguenther@suse.de> * 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
Diffstat (limited to 'gcc/gimple.c')
-rw-r--r--gcc/gimple.c173
1 files changed, 84 insertions, 89 deletions
diff --git a/gcc/gimple.c b/gcc/gimple.c
index 80c2cf4..d5b1cf7 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;
+ return 0;
+
+ /* Can't be the same type if they have different CV qualifiers. */
+ if (TYPE_QUALS (t1) != TYPE_QUALS (t2))
+ return 0;
/* Void types are always the same. */
if (TREE_CODE (t1) == VOID_TYPE)
- goto same_types;
+ return 1;
- /* Can't be the same type if they have different CV qualifiers. */
- if (TYPE_QUALS (t1) != TYPE_QUALS (t2))
- goto different_types;
+ /* 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;
}