This improves hashing and comparing both regular and canonical type
merging.

Bootstrapped and tested on x86_64-unknonw-linux-gnu and SPEC2k6 tested,
applied to trunk.

Richard.

2011-05-12  Richard Guenther  <rguent...@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.

Index: gcc/gimple.c
===================================================================
*** gcc/gimple.c        (revision 173702)
--- gcc/gimple.c        (working copy)
*************** gtc_visit (tree t1, tree t2,
*** 3489,3503 ****
    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;
--- 3489,3494 ----
*************** gtc_visit (tree t1, tree t2,
*** 3506,3528 ****
    if (TYPE_QUALS (t1) != TYPE_QUALS (t2))
      return false;
  
!   /* Void types are always the same.  */
!   if (TREE_CODE (t1) == VOID_TYPE)
      return true;
  
    /* 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)
      {
!       /* 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 false;
  
--- 3497,3526 ----
    if (TYPE_QUALS (t1) != TYPE_QUALS (t2))
      return false;
  
!   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
!       || POINTER_TYPE_P (t1))
      {
!       /* 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;
  
*************** gtc_visit (tree t1, tree t2,
*** 3536,3551 ****
          || FIXED_POINT_TYPE_P (t1))
        return true;
  
!       /* For integral 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 hash values of t1 and t2 are different the types can't
       possibly be the same.  This helps keeping the type-pair hashtable
--- 3534,3550 ----
          || FIXED_POINT_TYPE_P (t1))
        return true;
  
!       /* For other types fall thru to more complex checks.  */
      }
  
!   /* 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
*************** gimple_types_compatible_p_1 (tree t1, tr
*** 3739,3748 ****
        goto different_types;
        }
  
-     case NULLPTR_TYPE:
-       /* There is only one decltype(nullptr).  */
-       goto same_types;
- 
      case INTEGER_TYPE:
      case BOOLEAN_TYPE:
        {
--- 3738,3743 ----
*************** gimple_types_compatible_p (tree t1, tree
*** 3906,3920 ****
    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;
--- 3901,3906 ----
*************** gimple_types_compatible_p (tree t1, tree
*** 3923,3945 ****
    if (TYPE_QUALS (t1) != TYPE_QUALS (t2))
      return false;
  
!   /* Void types are always the same.  */
!   if (TREE_CODE (t1) == VOID_TYPE)
      return true;
  
    /* 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)
      {
!       /* 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 false;
  
--- 3909,3938 ----
    if (TYPE_QUALS (t1) != TYPE_QUALS (t2))
      return false;
  
!   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
!       || POINTER_TYPE_P (t1))
      {
!       /* 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;
  
*************** gimple_types_compatible_p (tree t1, tree
*** 3953,3968 ****
          || FIXED_POINT_TYPE_P (t1))
        return true;
  
!       /* For integral 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 hash values of t1 and t2 are different the types can't
       possibly be the same.  This helps keeping the type-pair hashtable
--- 3946,3962 ----
          || FIXED_POINT_TYPE_P (t1))
        return true;
  
!       /* For other types fall thru to more complex checks.  */
      }
  
!   /* 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
*************** iterative_hash_gimple_type (tree type, h
*** 4116,4135 ****
      }
  
    /* 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.  */
    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);
!     }
  
    /* For integer types hash the types min/max values and the string flag.  */
    if (TREE_CODE (type) == INTEGER_TYPE)
--- 4110,4119 ----
      }
  
    /* For pointer and reference types, fold in information about the type
!      pointed to.  */
    if (POINTER_TYPE_P (type))
!     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)
*************** iterative_hash_gimple_type (tree type, h
*** 4170,4198 ****
        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);
! 
        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);
          na++;
        }
  
--- 4154,4166 ----
        v = visit (TYPE_METHOD_BASETYPE (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))
        {
!         v = visit (TREE_VALUE (p), state, v,
!                    sccstack, sccstate, sccstate_obstack);
          na++;
        }
  
*************** iterative_hash_canonical_type (tree type
*** 4311,4329 ****
       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.  */
  
    /* Incorporate common features of numerical types.  */
    if (INTEGRAL_TYPE_P (type)
        || SCALAR_FLOAT_TYPE_P (type)
!       || FIXED_POINT_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);
      }
  
--- 4279,4298 ----
       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 (TREE_ADDRESSABLE (type), v);
!   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)
!       || 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_UNSIGNED (type), v);
      }
  
*************** iterative_hash_canonical_type (tree type
*** 4332,4350 ****
    if (POINTER_TYPE_P (type))
      {
        v = iterative_hash_hashval_t (TYPE_REF_CAN_ALIAS_ALL (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);
      }
  
    /* For array types hash their domain and the string flag.  */
--- 4301,4316 ----
    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)
      {
        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.  */
*************** gimple_canonical_types_compatible_p (tre
*** 4599,4625 ****
    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))
      return false;
  
!   /* Void types are always the same.  */
!   if (TREE_CODE (t1) == VOID_TYPE)
      return true;
  
!   /* 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)
      {
!       /* 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 false;
  
--- 4565,4596 ----
    if (TREE_CODE (t1) != TREE_CODE (t2))
      return false;
  
!   if (TREE_ADDRESSABLE (t1) != TREE_ADDRESSABLE (t2))
      return false;
  
!   /* 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;
  
!   /* 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
!       || POINTER_TYPE_P (t1))
      {
!       /* 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;
  
*************** gimple_canonical_types_compatible_p (tre
*** 4628,4647 ****
              || 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 integral 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 hash values of t1 and t2 are different the types can't
--- 4599,4633 ----
              || TYPE_STRING_FLAG (t1) != TYPE_STRING_FLAG (t2)))
        return false;
  
!       /* 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;
! 
!         if (TYPE_ADDR_SPACE (TREE_TYPE (t1))
!             != TYPE_ADDR_SPACE (TREE_TYPE (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
*************** gimple_canonical_types_compatible_p (tre
*** 4669,4680 ****
    /* 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.  */
--- 4655,4660 ----
*************** gimple_canonical_types_compatible_p (tre
*** 4767,4880 ****
          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:
--- 4747,4752 ----
*************** gimple_register_canonical_type (tree t)
*** 4949,4954 ****
--- 4821,4829 ----
       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.  */

Reply via email to