gimple.c (gtc_visit): Compare TREE_ADDRESSABLE, handle NULLPTR_TYPE similar to VOID_TYPE.
2011-05-12 Richard Guenther <rguenther@suse.de> * gimple.c (gtc_visit): Compare TREE_ADDRESSABLE, handle NULLPTR_TYPE similar to VOID_TYPE. Defer type-leader lookup until after simple checks. (gimple_types_compatible_p): Likewise. (iterative_hash_gimple_type): Always hash pointer targets and function return and argument types. (iterative_hash_canonical_type): Do not hash TYPE_QUALS, hash TYPE_ALIGN. Do not hash TYPE_MIN/MAX_VALUE. (gimple_canonical_types_compatible_p): Compare TREE_ADDRESSABLE, handle NULLPTR_TYPE similar to VOID_TYPE. Handle non-aggregates completely in the simple compare section. (gimple_register_canonical_type): Query the cache again after registering. From-SVN: r173704
This commit is contained in:
parent
e2a3a5f1ad
commit
61332f7774
|
@ -1,3 +1,19 @@
|
||||||
|
2011-05-12 Richard Guenther <rguenther@suse.de>
|
||||||
|
|
||||||
|
* gimple.c (gtc_visit): Compare TREE_ADDRESSABLE, handle
|
||||||
|
NULLPTR_TYPE similar to VOID_TYPE. Defer type-leader lookup
|
||||||
|
until after simple checks.
|
||||||
|
(gimple_types_compatible_p): Likewise.
|
||||||
|
(iterative_hash_gimple_type): Always hash pointer targets
|
||||||
|
and function return and argument types.
|
||||||
|
(iterative_hash_canonical_type): Do not hash TYPE_QUALS,
|
||||||
|
hash TYPE_ALIGN. Do not hash TYPE_MIN/MAX_VALUE.
|
||||||
|
(gimple_canonical_types_compatible_p): Compare TREE_ADDRESSABLE,
|
||||||
|
handle NULLPTR_TYPE similar to VOID_TYPE. Handle non-aggregates
|
||||||
|
completely in the simple compare section.
|
||||||
|
(gimple_register_canonical_type): Query the cache again after
|
||||||
|
registering.
|
||||||
|
|
||||||
2011-05-12 Richard Guenther <rguenther@suse.de>
|
2011-05-12 Richard Guenther <rguenther@suse.de>
|
||||||
|
|
||||||
PR tree-optimization/48172
|
PR tree-optimization/48172
|
||||||
|
|
349
gcc/gimple.c
349
gcc/gimple.c
|
@ -3489,15 +3489,6 @@ gtc_visit (tree t1, tree t2,
|
||||||
if (t1 == NULL_TREE || t2 == NULL_TREE)
|
if (t1 == NULL_TREE || t2 == NULL_TREE)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* If the types have been previously registered and found equal
|
|
||||||
they still are. */
|
|
||||||
leader1 = gimple_lookup_type_leader (t1);
|
|
||||||
leader2 = gimple_lookup_type_leader (t2);
|
|
||||||
if (leader1 == t2
|
|
||||||
|| t1 == leader2
|
|
||||||
|| (leader1 && leader1 == leader2))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
/* Can't be the same type if the types don't have the same code. */
|
/* Can't be the same type if the types don't have the same code. */
|
||||||
if (TREE_CODE (t1) != TREE_CODE (t2))
|
if (TREE_CODE (t1) != TREE_CODE (t2))
|
||||||
return false;
|
return false;
|
||||||
|
@ -3506,23 +3497,30 @@ gtc_visit (tree t1, tree t2,
|
||||||
if (TYPE_QUALS (t1) != TYPE_QUALS (t2))
|
if (TYPE_QUALS (t1) != TYPE_QUALS (t2))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* Void types are always the same. */
|
if (TREE_ADDRESSABLE (t1) != TREE_ADDRESSABLE (t2))
|
||||||
if (TREE_CODE (t1) == VOID_TYPE)
|
return false;
|
||||||
|
|
||||||
|
/* Void types and nullptr types are always the same. */
|
||||||
|
if (TREE_CODE (t1) == VOID_TYPE
|
||||||
|
|| TREE_CODE (t1) == NULLPTR_TYPE)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
/* Can't be the same type if they have different alignment or mode. */
|
||||||
|
if (TYPE_ALIGN (t1) != TYPE_ALIGN (t2)
|
||||||
|
|| TYPE_MODE (t1) != TYPE_MODE (t2))
|
||||||
|
return false;
|
||||||
|
|
||||||
/* Do some simple checks before doing three hashtable queries. */
|
/* Do some simple checks before doing three hashtable queries. */
|
||||||
if (INTEGRAL_TYPE_P (t1)
|
if (INTEGRAL_TYPE_P (t1)
|
||||||
|| SCALAR_FLOAT_TYPE_P (t1)
|
|| SCALAR_FLOAT_TYPE_P (t1)
|
||||||
|| FIXED_POINT_TYPE_P (t1)
|
|| FIXED_POINT_TYPE_P (t1)
|
||||||
|| TREE_CODE (t1) == VECTOR_TYPE
|
|| TREE_CODE (t1) == VECTOR_TYPE
|
||||||
|| TREE_CODE (t1) == COMPLEX_TYPE
|
|| TREE_CODE (t1) == COMPLEX_TYPE
|
||||||
|| TREE_CODE (t1) == OFFSET_TYPE)
|
|| TREE_CODE (t1) == OFFSET_TYPE
|
||||||
|
|| POINTER_TYPE_P (t1))
|
||||||
{
|
{
|
||||||
/* Can't be the same type if they have different alignment,
|
/* Can't be the same type if they have different sign or precision. */
|
||||||
sign, precision or mode. */
|
if (TYPE_PRECISION (t1) != TYPE_PRECISION (t2)
|
||||||
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))
|
|| TYPE_UNSIGNED (t1) != TYPE_UNSIGNED (t2))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -3536,16 +3534,17 @@ gtc_visit (tree t1, tree t2,
|
||||||
|| FIXED_POINT_TYPE_P (t1))
|
|| FIXED_POINT_TYPE_P (t1))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
/* For integral types fall thru to more complex checks. */
|
/* For other types fall thru to more complex checks. */
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (AGGREGATE_TYPE_P (t1) || POINTER_TYPE_P (t1))
|
/* If the types have been previously registered and found equal
|
||||||
{
|
they still are. */
|
||||||
/* Can't be the same type if they have different alignment or mode. */
|
leader1 = gimple_lookup_type_leader (t1);
|
||||||
if (TYPE_ALIGN (t1) != TYPE_ALIGN (t2)
|
leader2 = gimple_lookup_type_leader (t2);
|
||||||
|| TYPE_MODE (t1) != TYPE_MODE (t2))
|
if (leader1 == t2
|
||||||
return false;
|
|| t1 == leader2
|
||||||
}
|
|| (leader1 && leader1 == leader2))
|
||||||
|
return true;
|
||||||
|
|
||||||
/* If the hash values of t1 and t2 are different the types can't
|
/* 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
|
possibly be the same. This helps keeping the type-pair hashtable
|
||||||
|
@ -3739,10 +3738,6 @@ gimple_types_compatible_p_1 (tree t1, tree t2, type_pair_t p,
|
||||||
goto different_types;
|
goto different_types;
|
||||||
}
|
}
|
||||||
|
|
||||||
case NULLPTR_TYPE:
|
|
||||||
/* There is only one decltype(nullptr). */
|
|
||||||
goto same_types;
|
|
||||||
|
|
||||||
case INTEGER_TYPE:
|
case INTEGER_TYPE:
|
||||||
case BOOLEAN_TYPE:
|
case BOOLEAN_TYPE:
|
||||||
{
|
{
|
||||||
|
@ -3906,15 +3901,6 @@ gimple_types_compatible_p (tree t1, tree t2)
|
||||||
if (t1 == NULL_TREE || t2 == NULL_TREE)
|
if (t1 == NULL_TREE || t2 == NULL_TREE)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* If the types have been previously registered and found equal
|
|
||||||
they still are. */
|
|
||||||
leader1 = gimple_lookup_type_leader (t1);
|
|
||||||
leader2 = gimple_lookup_type_leader (t2);
|
|
||||||
if (leader1 == t2
|
|
||||||
|| t1 == leader2
|
|
||||||
|| (leader1 && leader1 == leader2))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
/* Can't be the same type if the types don't have the same code. */
|
/* Can't be the same type if the types don't have the same code. */
|
||||||
if (TREE_CODE (t1) != TREE_CODE (t2))
|
if (TREE_CODE (t1) != TREE_CODE (t2))
|
||||||
return false;
|
return false;
|
||||||
|
@ -3923,23 +3909,30 @@ gimple_types_compatible_p (tree t1, tree t2)
|
||||||
if (TYPE_QUALS (t1) != TYPE_QUALS (t2))
|
if (TYPE_QUALS (t1) != TYPE_QUALS (t2))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* Void types are always the same. */
|
if (TREE_ADDRESSABLE (t1) != TREE_ADDRESSABLE (t2))
|
||||||
if (TREE_CODE (t1) == VOID_TYPE)
|
return false;
|
||||||
|
|
||||||
|
/* Void types and nullptr types are always the same. */
|
||||||
|
if (TREE_CODE (t1) == VOID_TYPE
|
||||||
|
|| TREE_CODE (t1) == NULLPTR_TYPE)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
/* Can't be the same type if they have different alignment or mode. */
|
||||||
|
if (TYPE_ALIGN (t1) != TYPE_ALIGN (t2)
|
||||||
|
|| TYPE_MODE (t1) != TYPE_MODE (t2))
|
||||||
|
return false;
|
||||||
|
|
||||||
/* Do some simple checks before doing three hashtable queries. */
|
/* Do some simple checks before doing three hashtable queries. */
|
||||||
if (INTEGRAL_TYPE_P (t1)
|
if (INTEGRAL_TYPE_P (t1)
|
||||||
|| SCALAR_FLOAT_TYPE_P (t1)
|
|| SCALAR_FLOAT_TYPE_P (t1)
|
||||||
|| FIXED_POINT_TYPE_P (t1)
|
|| FIXED_POINT_TYPE_P (t1)
|
||||||
|| TREE_CODE (t1) == VECTOR_TYPE
|
|| TREE_CODE (t1) == VECTOR_TYPE
|
||||||
|| TREE_CODE (t1) == COMPLEX_TYPE
|
|| TREE_CODE (t1) == COMPLEX_TYPE
|
||||||
|| TREE_CODE (t1) == OFFSET_TYPE)
|
|| TREE_CODE (t1) == OFFSET_TYPE
|
||||||
|
|| POINTER_TYPE_P (t1))
|
||||||
{
|
{
|
||||||
/* Can't be the same type if they have different alignment,
|
/* Can't be the same type if they have different sign or precision. */
|
||||||
sign, precision or mode. */
|
if (TYPE_PRECISION (t1) != TYPE_PRECISION (t2)
|
||||||
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))
|
|| TYPE_UNSIGNED (t1) != TYPE_UNSIGNED (t2))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -3953,16 +3946,17 @@ gimple_types_compatible_p (tree t1, tree t2)
|
||||||
|| FIXED_POINT_TYPE_P (t1))
|
|| FIXED_POINT_TYPE_P (t1))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
/* For integral types fall thru to more complex checks. */
|
/* For other types fall thru to more complex checks. */
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (AGGREGATE_TYPE_P (t1) || POINTER_TYPE_P (t1))
|
/* If the types have been previously registered and found equal
|
||||||
{
|
they still are. */
|
||||||
/* Can't be the same type if they have different alignment or mode. */
|
leader1 = gimple_lookup_type_leader (t1);
|
||||||
if (TYPE_ALIGN (t1) != TYPE_ALIGN (t2)
|
leader2 = gimple_lookup_type_leader (t2);
|
||||||
|| TYPE_MODE (t1) != TYPE_MODE (t2))
|
if (leader1 == t2
|
||||||
return false;
|
|| t1 == leader2
|
||||||
}
|
|| (leader1 && leader1 == leader2))
|
||||||
|
return true;
|
||||||
|
|
||||||
/* If the hash values of t1 and t2 are different the types can't
|
/* 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
|
possibly be the same. This helps keeping the type-pair hashtable
|
||||||
|
@ -4116,20 +4110,10 @@ iterative_hash_gimple_type (tree type, hashval_t val,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For pointer and reference types, fold in information about the type
|
/* For pointer and reference types, fold in information about the type
|
||||||
pointed to but do not recurse into possibly incomplete types to
|
pointed to. */
|
||||||
avoid hash differences for complete vs. incomplete types. */
|
|
||||||
if (POINTER_TYPE_P (type))
|
if (POINTER_TYPE_P (type))
|
||||||
{
|
v = visit (TREE_TYPE (type), state, v,
|
||||||
if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (type)))
|
sccstack, sccstate, sccstate_obstack);
|
||||||
{
|
|
||||||
v = iterative_hash_hashval_t (TREE_CODE (TREE_TYPE (type)), v);
|
|
||||||
v = iterative_hash_name
|
|
||||||
(TYPE_NAME (TYPE_MAIN_VARIANT (TREE_TYPE (type))), v);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
v = visit (TREE_TYPE (type), state, v,
|
|
||||||
sccstack, sccstate, sccstate_obstack);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* For integer types hash the types min/max values and the string flag. */
|
/* For integer types hash the types min/max values and the string flag. */
|
||||||
if (TREE_CODE (type) == INTEGER_TYPE)
|
if (TREE_CODE (type) == INTEGER_TYPE)
|
||||||
|
@ -4170,29 +4154,13 @@ iterative_hash_gimple_type (tree type, hashval_t val,
|
||||||
v = visit (TYPE_METHOD_BASETYPE (type), state, v,
|
v = visit (TYPE_METHOD_BASETYPE (type), state, v,
|
||||||
sccstack, sccstate, sccstate_obstack);
|
sccstack, sccstate, sccstate_obstack);
|
||||||
|
|
||||||
/* For result types allow mismatch in completeness. */
|
/* Check result and argument types. */
|
||||||
if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (type)))
|
v = visit (TREE_TYPE (type), state, v,
|
||||||
{
|
sccstack, sccstate, sccstate_obstack);
|
||||||
v = iterative_hash_hashval_t (TREE_CODE (TREE_TYPE (type)), v);
|
|
||||||
v = iterative_hash_name
|
|
||||||
(TYPE_NAME (TYPE_MAIN_VARIANT (TREE_TYPE (type))), v);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
v = visit (TREE_TYPE (type), state, v,
|
|
||||||
sccstack, sccstate, sccstate_obstack);
|
|
||||||
|
|
||||||
for (p = TYPE_ARG_TYPES (type), na = 0; p; p = TREE_CHAIN (p))
|
for (p = TYPE_ARG_TYPES (type), na = 0; p; p = TREE_CHAIN (p))
|
||||||
{
|
{
|
||||||
/* For argument types allow mismatch in completeness. */
|
v = visit (TREE_VALUE (p), state, v,
|
||||||
if (RECORD_OR_UNION_TYPE_P (TREE_VALUE (p)))
|
sccstack, sccstate, sccstate_obstack);
|
||||||
{
|
|
||||||
v = iterative_hash_hashval_t (TREE_CODE (TREE_VALUE (p)), v);
|
|
||||||
v = iterative_hash_name
|
|
||||||
(TYPE_NAME (TYPE_MAIN_VARIANT (TREE_VALUE (p))), v);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
v = visit (TREE_VALUE (p), state, v,
|
|
||||||
sccstack, sccstate, sccstate_obstack);
|
|
||||||
na++;
|
na++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4311,19 +4279,20 @@ iterative_hash_canonical_type (tree type, hashval_t val)
|
||||||
only existing types having the same features as the new type will be
|
only existing types having the same features as the new type will be
|
||||||
checked. */
|
checked. */
|
||||||
v = iterative_hash_hashval_t (TREE_CODE (type), 0);
|
v = iterative_hash_hashval_t (TREE_CODE (type), 0);
|
||||||
v = iterative_hash_hashval_t (TYPE_QUALS (type), v);
|
|
||||||
v = iterative_hash_hashval_t (TREE_ADDRESSABLE (type), v);
|
v = iterative_hash_hashval_t (TREE_ADDRESSABLE (type), v);
|
||||||
|
v = iterative_hash_hashval_t (TYPE_ALIGN (type), v);
|
||||||
/* Do not hash the types size as this will cause differences in
|
v = iterative_hash_hashval_t (TYPE_MODE (type), v);
|
||||||
hash values for the complete vs. the incomplete type variant. */
|
|
||||||
|
|
||||||
/* Incorporate common features of numerical types. */
|
/* Incorporate common features of numerical types. */
|
||||||
if (INTEGRAL_TYPE_P (type)
|
if (INTEGRAL_TYPE_P (type)
|
||||||
|| SCALAR_FLOAT_TYPE_P (type)
|
|| SCALAR_FLOAT_TYPE_P (type)
|
||||||
|| FIXED_POINT_TYPE_P (type))
|
|| FIXED_POINT_TYPE_P (type)
|
||||||
|
|| TREE_CODE (type) == VECTOR_TYPE
|
||||||
|
|| TREE_CODE (type) == COMPLEX_TYPE
|
||||||
|
|| TREE_CODE (type) == OFFSET_TYPE
|
||||||
|
|| POINTER_TYPE_P (type))
|
||||||
{
|
{
|
||||||
v = iterative_hash_hashval_t (TYPE_PRECISION (type), v);
|
v = iterative_hash_hashval_t (TYPE_PRECISION (type), v);
|
||||||
v = iterative_hash_hashval_t (TYPE_MODE (type), v);
|
|
||||||
v = iterative_hash_hashval_t (TYPE_UNSIGNED (type), v);
|
v = iterative_hash_hashval_t (TYPE_UNSIGNED (type), v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4332,19 +4301,16 @@ iterative_hash_canonical_type (tree type, hashval_t val)
|
||||||
if (POINTER_TYPE_P (type))
|
if (POINTER_TYPE_P (type))
|
||||||
{
|
{
|
||||||
v = iterative_hash_hashval_t (TYPE_REF_CAN_ALIAS_ALL (type), v);
|
v = iterative_hash_hashval_t (TYPE_REF_CAN_ALIAS_ALL (type), v);
|
||||||
|
v = iterative_hash_hashval_t (TYPE_ADDR_SPACE (TREE_TYPE (type)), v);
|
||||||
|
v = iterative_hash_hashval_t (TYPE_RESTRICT (type), v);
|
||||||
v = iterative_hash_hashval_t (TREE_CODE (TREE_TYPE (type)), v);
|
v = iterative_hash_hashval_t (TREE_CODE (TREE_TYPE (type)), v);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For integer types hash the types min/max values and the string flag. */
|
/* For integer types hash the types min/max values and the string flag. */
|
||||||
if (TREE_CODE (type) == INTEGER_TYPE)
|
if (TREE_CODE (type) == INTEGER_TYPE)
|
||||||
{
|
{
|
||||||
/* OMP lowering can introduce error_mark_node in place of
|
|
||||||
random local decls in types. */
|
|
||||||
if (TYPE_MIN_VALUE (type) != error_mark_node)
|
|
||||||
v = iterative_hash_expr (TYPE_MIN_VALUE (type), v);
|
|
||||||
if (TYPE_MAX_VALUE (type) != error_mark_node)
|
|
||||||
v = iterative_hash_expr (TYPE_MAX_VALUE (type), v);
|
|
||||||
v = iterative_hash_hashval_t (TYPE_STRING_FLAG (type), v);
|
v = iterative_hash_hashval_t (TYPE_STRING_FLAG (type), v);
|
||||||
|
v = iterative_hash_hashval_t (TYPE_IS_SIZETYPE (type), v);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For array types hash their domain and the string flag. */
|
/* For array types hash their domain and the string flag. */
|
||||||
|
@ -4599,27 +4565,32 @@ gimple_canonical_types_compatible_p (tree t1, tree t2)
|
||||||
if (TREE_CODE (t1) != TREE_CODE (t2))
|
if (TREE_CODE (t1) != TREE_CODE (t2))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* Can't be the same type if they have different CV qualifiers. */
|
if (TREE_ADDRESSABLE (t1) != TREE_ADDRESSABLE (t2))
|
||||||
if (TYPE_QUALS (t1) != TYPE_QUALS (t2))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* Void types are always the same. */
|
/* Qualifiers do not matter for canonical type comparison purposes. */
|
||||||
if (TREE_CODE (t1) == VOID_TYPE)
|
|
||||||
|
/* Void types and nullptr types are always the same. */
|
||||||
|
if (TREE_CODE (t1) == VOID_TYPE
|
||||||
|
|| TREE_CODE (t1) == NULLPTR_TYPE)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
/* Do some simple checks before doing three hashtable queries. */
|
/* Can't be the same type if they have different alignment, or mode. */
|
||||||
|
if (TYPE_ALIGN (t1) != TYPE_ALIGN (t2)
|
||||||
|
|| TYPE_MODE (t1) != TYPE_MODE (t2))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* Non-aggregate types can be handled cheaply. */
|
||||||
if (INTEGRAL_TYPE_P (t1)
|
if (INTEGRAL_TYPE_P (t1)
|
||||||
|| SCALAR_FLOAT_TYPE_P (t1)
|
|| SCALAR_FLOAT_TYPE_P (t1)
|
||||||
|| FIXED_POINT_TYPE_P (t1)
|
|| FIXED_POINT_TYPE_P (t1)
|
||||||
|| TREE_CODE (t1) == VECTOR_TYPE
|
|| TREE_CODE (t1) == VECTOR_TYPE
|
||||||
|| TREE_CODE (t1) == COMPLEX_TYPE
|
|| TREE_CODE (t1) == COMPLEX_TYPE
|
||||||
|| TREE_CODE (t1) == OFFSET_TYPE)
|
|| TREE_CODE (t1) == OFFSET_TYPE
|
||||||
|
|| POINTER_TYPE_P (t1))
|
||||||
{
|
{
|
||||||
/* Can't be the same type if they have different alignment,
|
/* Can't be the same type if they have different sign or precision. */
|
||||||
sign, precision or mode. */
|
if (TYPE_PRECISION (t1) != TYPE_PRECISION (t2)
|
||||||
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))
|
|| TYPE_UNSIGNED (t1) != TYPE_UNSIGNED (t2))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -4628,20 +4599,35 @@ gimple_canonical_types_compatible_p (tree t1, tree t2)
|
||||||
|| TYPE_STRING_FLAG (t1) != TYPE_STRING_FLAG (t2)))
|
|| TYPE_STRING_FLAG (t1) != TYPE_STRING_FLAG (t2)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* That's all we need to check for float and fixed-point types. */
|
/* For canonical type comparisons we do not want to build SCCs
|
||||||
if (SCALAR_FLOAT_TYPE_P (t1)
|
so we cannot compare pointed-to types. But we can, for now,
|
||||||
|| FIXED_POINT_TYPE_P (t1))
|
require the same pointed-to type kind and match what
|
||||||
return true;
|
useless_type_conversion_p would do. */
|
||||||
|
if (POINTER_TYPE_P (t1))
|
||||||
|
{
|
||||||
|
/* If the two pointers have different ref-all attributes,
|
||||||
|
they can't be the same type. */
|
||||||
|
if (TYPE_REF_CAN_ALIAS_ALL (t1) != TYPE_REF_CAN_ALIAS_ALL (t2))
|
||||||
|
return false;
|
||||||
|
|
||||||
/* For integral types fall thru to more complex checks. */
|
if (TYPE_ADDR_SPACE (TREE_TYPE (t1))
|
||||||
}
|
!= TYPE_ADDR_SPACE (TREE_TYPE (t2)))
|
||||||
|
return false;
|
||||||
|
|
||||||
else if (AGGREGATE_TYPE_P (t1) || POINTER_TYPE_P (t1))
|
if (TYPE_RESTRICT (t1) != TYPE_RESTRICT (t2))
|
||||||
{
|
return false;
|
||||||
/* Can't be the same type if they have different alignment or mode. */
|
|
||||||
if (TYPE_ALIGN (t1) != TYPE_ALIGN (t2)
|
if (TREE_CODE (TREE_TYPE (t1)) != TREE_CODE (TREE_TYPE (t2)))
|
||||||
|| TYPE_MODE (t1) != TYPE_MODE (t2))
|
return false;
|
||||||
return false;
|
}
|
||||||
|
|
||||||
|
/* Tail-recurse to components. */
|
||||||
|
if (TREE_CODE (t1) == VECTOR_TYPE
|
||||||
|
|| TREE_CODE (t1) == COMPLEX_TYPE)
|
||||||
|
return gimple_canonical_types_compatible_p (TREE_TYPE (t1),
|
||||||
|
TREE_TYPE (t2));
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the hash values of t1 and t2 are different the types can't
|
/* If the hash values of t1 and t2 are different the types can't
|
||||||
|
@ -4669,12 +4655,6 @@ gimple_canonical_types_compatible_p (tree t1, tree t2)
|
||||||
/* Do type-specific comparisons. */
|
/* Do type-specific comparisons. */
|
||||||
switch (TREE_CODE (t1))
|
switch (TREE_CODE (t1))
|
||||||
{
|
{
|
||||||
case VECTOR_TYPE:
|
|
||||||
case COMPLEX_TYPE:
|
|
||||||
if (!gimple_canonical_types_compatible_p (TREE_TYPE (t1), TREE_TYPE (t2)))
|
|
||||||
goto different_types;
|
|
||||||
goto same_types;
|
|
||||||
|
|
||||||
case ARRAY_TYPE:
|
case ARRAY_TYPE:
|
||||||
/* Array types are the same if the element types are the same and
|
/* Array types are the same if the element types are the same and
|
||||||
the number of elements are the same. */
|
the number of elements are the same. */
|
||||||
|
@ -4767,114 +4747,6 @@ gimple_canonical_types_compatible_p (tree t1, tree t2)
|
||||||
goto same_types;
|
goto same_types;
|
||||||
}
|
}
|
||||||
|
|
||||||
case OFFSET_TYPE:
|
|
||||||
{
|
|
||||||
if (!gimple_canonical_types_compatible_p
|
|
||||||
(TREE_TYPE (t1), TREE_TYPE (t2))
|
|
||||||
|| !gimple_canonical_types_compatible_p
|
|
||||||
(TYPE_OFFSET_BASETYPE (t1), TYPE_OFFSET_BASETYPE (t2)))
|
|
||||||
goto different_types;
|
|
||||||
|
|
||||||
goto same_types;
|
|
||||||
}
|
|
||||||
|
|
||||||
case POINTER_TYPE:
|
|
||||||
case REFERENCE_TYPE:
|
|
||||||
{
|
|
||||||
/* If the two pointers have different ref-all attributes,
|
|
||||||
they can't be the same type. */
|
|
||||||
if (TYPE_REF_CAN_ALIAS_ALL (t1) != TYPE_REF_CAN_ALIAS_ALL (t2))
|
|
||||||
goto different_types;
|
|
||||||
|
|
||||||
if (TYPE_ADDR_SPACE (TREE_TYPE (t1))
|
|
||||||
!= TYPE_ADDR_SPACE (TREE_TYPE (t2)))
|
|
||||||
goto different_types;
|
|
||||||
|
|
||||||
if (TYPE_RESTRICT (t1) != TYPE_RESTRICT (t2))
|
|
||||||
goto different_types;
|
|
||||||
|
|
||||||
/* For canonical type comparisons we do not want to build SCCs
|
|
||||||
so we cannot compare pointed-to types. But we can, for now,
|
|
||||||
require the same pointed-to type kind. */
|
|
||||||
if (TREE_CODE (TREE_TYPE (t1)) != TREE_CODE (TREE_TYPE (t2)))
|
|
||||||
goto different_types;
|
|
||||||
|
|
||||||
goto same_types;
|
|
||||||
}
|
|
||||||
|
|
||||||
case NULLPTR_TYPE:
|
|
||||||
/* There is only one decltype(nullptr). */
|
|
||||||
goto same_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:
|
|
||||||
{
|
|
||||||
/* 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;
|
|
||||||
|
|
||||||
for (v1 = TYPE_VALUES (t1), v2 = TYPE_VALUES (t2);
|
|
||||||
v1 && v2;
|
|
||||||
v1 = TREE_CHAIN (v1), v2 = TREE_CHAIN (v2))
|
|
||||||
{
|
|
||||||
tree c1 = TREE_VALUE (v1);
|
|
||||||
tree c2 = TREE_VALUE (v2);
|
|
||||||
|
|
||||||
if (TREE_CODE (c1) == CONST_DECL)
|
|
||||||
c1 = DECL_INITIAL (c1);
|
|
||||||
|
|
||||||
if (TREE_CODE (c2) == CONST_DECL)
|
|
||||||
c2 = DECL_INITIAL (c2);
|
|
||||||
|
|
||||||
if (tree_int_cst_equal (c1, c2) != 1)
|
|
||||||
goto different_types;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If one enumeration has more values than the other, they
|
|
||||||
are not the same. */
|
|
||||||
if (v1 || v2)
|
|
||||||
goto different_types;
|
|
||||||
|
|
||||||
goto same_types;
|
|
||||||
}
|
|
||||||
|
|
||||||
case RECORD_TYPE:
|
case RECORD_TYPE:
|
||||||
case UNION_TYPE:
|
case UNION_TYPE:
|
||||||
case QUAL_UNION_TYPE:
|
case QUAL_UNION_TYPE:
|
||||||
|
@ -4949,6 +4821,9 @@ gimple_register_canonical_type (tree t)
|
||||||
to be the canonical type it will be the one we merge to as well. */
|
to be the canonical type it will be the one we merge to as well. */
|
||||||
t = gimple_register_type (t);
|
t = gimple_register_type (t);
|
||||||
|
|
||||||
|
if (TYPE_CANONICAL (t))
|
||||||
|
return TYPE_CANONICAL (t);
|
||||||
|
|
||||||
/* Always register the main variant first. This is important so we
|
/* Always register the main variant first. This is important so we
|
||||||
pick up the non-typedef variants as canonical, otherwise we'll end
|
pick up the non-typedef variants as canonical, otherwise we'll end
|
||||||
up taking typedef ids for structure tags during comparison. */
|
up taking typedef ids for structure tags during comparison. */
|
||||||
|
|
Loading…
Reference in New Issue