This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH][6/n] LTO type merging cleanup


This streamlines the now separate hashing and comparing functions
for canonical and regular type matching.  It should significantly
shrink the canonical tables (doing more merging) and reduce
the number of hash collisions in the regular tables.

Boostrap & regtest pending on x86_64-unknown-linux-gnu.

Richard.

2011-05-11  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.

Index: gcc/gimple.c
===================================================================
*** gcc/gimple.c	(revision 173655)
--- 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 (t1) == VECTOR_TYPE
!       || TREE_CODE (t1) == COMPLEX_TYPE
!       || TREE_CODE (t1) == OFFSET_TYPE
!       || POINTER_TYPE_P (t1))
      {
        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 ----


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]