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:
parent
a1aa17011f
commit
b0cc341fd9
@ -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
|
||||
|
175
gcc/gimple.c
175
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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user