From: Richard Guenther Date: Thu, 12 May 2011 14:04:29 +0000 (+0000) Subject: gimple.c (gtc_visit): Compare TREE_ADDRESSABLE, handle NULLPTR_TYPE similar to VOID_TYPE. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=61332f77748bd6ea8cb59c15f08a48466940ac95;p=gcc.git gimple.c (gtc_visit): Compare TREE_ADDRESSABLE, handle NULLPTR_TYPE similar to VOID_TYPE. 2011-05-12 Richard Guenther * 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 71cb451cf26..bb84bfd2b41 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2011-05-12 Richard Guenther + + * 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 PR tree-optimization/48172 diff --git a/gcc/gimple.c b/gcc/gimple.c index 2a8f97653d0..c9ac991d3d0 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -3489,15 +3489,6 @@ gtc_visit (tree t1, tree t2, if (t1 == NULL_TREE || t2 == NULL_TREE) 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. */ if (TREE_CODE (t1) != TREE_CODE (t2)) return false; @@ -3506,23 +3497,30 @@ gtc_visit (tree t1, tree t2, if (TYPE_QUALS (t1) != TYPE_QUALS (t2)) return false; - /* Void types are always the same. */ - if (TREE_CODE (t1) == VOID_TYPE) + if (TREE_ADDRESSABLE (t1) != TREE_ADDRESSABLE (t2)) + return false; + + /* Void types and nullptr types are always the same. */ + if (TREE_CODE (t1) == VOID_TYPE + || TREE_CODE (t1) == NULLPTR_TYPE) 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. */ 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 - || 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, - sign, precision or mode. */ - if (TYPE_ALIGN (t1) != TYPE_ALIGN (t2) - || TYPE_PRECISION (t1) != TYPE_PRECISION (t2) - || TYPE_MODE (t1) != TYPE_MODE (t2) + /* Can't be the same type if they have different sign or precision. */ + if (TYPE_PRECISION (t1) != TYPE_PRECISION (t2) || TYPE_UNSIGNED (t1) != TYPE_UNSIGNED (t2)) return false; @@ -3536,16 +3534,17 @@ gtc_visit (tree t1, tree t2, || FIXED_POINT_TYPE_P (t1)) 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)) - { - /* 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; - } + /* 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; /* 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 @@ -3739,10 +3738,6 @@ gimple_types_compatible_p_1 (tree t1, tree t2, type_pair_t p, goto different_types; } - case NULLPTR_TYPE: - /* There is only one decltype(nullptr). */ - goto same_types; - case INTEGER_TYPE: case BOOLEAN_TYPE: { @@ -3906,15 +3901,6 @@ gimple_types_compatible_p (tree t1, tree t2) if (t1 == NULL_TREE || t2 == NULL_TREE) 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. */ if (TREE_CODE (t1) != TREE_CODE (t2)) return false; @@ -3923,23 +3909,30 @@ gimple_types_compatible_p (tree t1, tree t2) if (TYPE_QUALS (t1) != TYPE_QUALS (t2)) return false; - /* Void types are always the same. */ - if (TREE_CODE (t1) == VOID_TYPE) + if (TREE_ADDRESSABLE (t1) != TREE_ADDRESSABLE (t2)) + return false; + + /* Void types and nullptr types are always the same. */ + if (TREE_CODE (t1) == VOID_TYPE + || TREE_CODE (t1) == NULLPTR_TYPE) 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. */ 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 - || 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, - sign, precision or mode. */ - if (TYPE_ALIGN (t1) != TYPE_ALIGN (t2) - || TYPE_PRECISION (t1) != TYPE_PRECISION (t2) - || TYPE_MODE (t1) != TYPE_MODE (t2) + /* Can't be the same type if they have different sign or precision. */ + if (TYPE_PRECISION (t1) != TYPE_PRECISION (t2) || TYPE_UNSIGNED (t1) != TYPE_UNSIGNED (t2)) return false; @@ -3953,16 +3946,17 @@ gimple_types_compatible_p (tree t1, tree t2) || FIXED_POINT_TYPE_P (t1)) 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)) - { - /* 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; - } + /* 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; /* 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 @@ -4116,20 +4110,10 @@ iterative_hash_gimple_type (tree type, hashval_t val, } /* For pointer and reference types, fold in information about the type - pointed to but do not recurse into possibly incomplete types to - avoid hash differences for complete vs. incomplete types. */ + pointed to. */ if (POINTER_TYPE_P (type)) - { - if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (type))) - { - 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); - } + v = visit (TREE_TYPE (type), state, v, + sccstack, sccstate, sccstate_obstack); /* For integer types hash the types min/max values and the string flag. */ 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, sccstack, sccstate, sccstate_obstack); - /* For result types allow mismatch in completeness. */ - if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (type))) - { - 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); - + /* Check result and argument types. */ + 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 argument types allow mismatch in completeness. */ - if (RECORD_OR_UNION_TYPE_P (TREE_VALUE (p))) - { - 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); + v = visit (TREE_VALUE (p), state, v, + sccstack, sccstate, sccstate_obstack); 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 checked. */ 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); - - /* Do not hash the types size as this will cause differences in - hash values for the complete vs. the incomplete type variant. */ + v = iterative_hash_hashval_t (TYPE_ALIGN (type), v); + v = iterative_hash_hashval_t (TYPE_MODE (type), v); /* Incorporate common features of numerical types. */ if (INTEGRAL_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_MODE (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)) { 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); } /* For integer types hash the types min/max values and the string flag. */ 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_IS_SIZETYPE (type), v); } /* 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)) return false; - /* Can't be the same type if they have different CV qualifiers. */ - if (TYPE_QUALS (t1) != TYPE_QUALS (t2)) + if (TREE_ADDRESSABLE (t1) != TREE_ADDRESSABLE (t2)) return false; - /* Void types are always the same. */ - if (TREE_CODE (t1) == VOID_TYPE) + /* Qualifiers do not matter for canonical type comparison purposes. */ + + /* Void types and nullptr types are always the same. */ + if (TREE_CODE (t1) == VOID_TYPE + || TREE_CODE (t1) == NULLPTR_TYPE) 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) || SCALAR_FLOAT_TYPE_P (t1) || FIXED_POINT_TYPE_P (t1) || TREE_CODE (t1) == VECTOR_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, - sign, precision or mode. */ - if (TYPE_ALIGN (t1) != TYPE_ALIGN (t2) - || TYPE_PRECISION (t1) != TYPE_PRECISION (t2) - || TYPE_MODE (t1) != TYPE_MODE (t2) + /* Can't be the same type if they have different sign or precision. */ + if (TYPE_PRECISION (t1) != TYPE_PRECISION (t2) || TYPE_UNSIGNED (t1) != TYPE_UNSIGNED (t2)) return false; @@ -4628,20 +4599,35 @@ gimple_canonical_types_compatible_p (tree t1, tree t2) || TYPE_STRING_FLAG (t1) != TYPE_STRING_FLAG (t2))) return false; - /* 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 true; + /* 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 and match what + 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)) - { - /* 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; + if (TYPE_RESTRICT (t1) != TYPE_RESTRICT (t2)) + return false; + + if (TREE_CODE (TREE_TYPE (t1)) != TREE_CODE (TREE_TYPE (t2))) + 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 @@ -4669,12 +4655,6 @@ gimple_canonical_types_compatible_p (tree t1, tree t2) /* Do type-specific comparisons. */ 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: /* Array types are the same if the element types are the same and the number of elements are the same. */ @@ -4767,114 +4747,6 @@ gimple_canonical_types_compatible_p (tree t1, tree t2) 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 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. */ t = gimple_register_type (t); + if (TYPE_CANONICAL (t)) + return TYPE_CANONICAL (t); + /* Always register the main variant first. This is important so we pick up the non-typedef variants as canonical, otherwise we'll end up taking typedef ids for structure tags during comparison. */