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
This commit is contained in:
Richard Guenther 2009-10-20 11:08:30 +00:00 committed by Richard Biener
parent a1aa17011f
commit b0cc341fd9
2 changed files with 91 additions and 90 deletions

View File

@ -1,3 +1,9 @@
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.
2009-10-20 Eric Botcazou <ebotcazou@adacore.com>
* tree-sra.c (build_ref_for_offset_1) <RECORD_TYPE>: Skip fields

View File

@ -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;
}