]> gcc.gnu.org Git - gcc.git/commitdiff
gimple.c (gimple_types_compatible_p): Simplify.
authorRichard Guenther <rguenther@suse.de>
Tue, 20 Oct 2009 11:08:30 +0000 (11:08 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 20 Oct 2009 11:08:30 +0000 (11:08 +0000)
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

gcc/ChangeLog
gcc/gimple.c

index 739cdb574bedd1f1e7226e4e2202101cc2541b8d..a631aaa738d13bab456ba155055573ebfe5e27aa 100644 (file)
@@ -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
index 80c2cf468315a284891940fc5c8ee9b9f275badd..d5b1cf7f1c7739fda8a402371f680d27e22554e2 100644 (file)
@@ -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;
+    return 0;
+
+  /* Can't be the same type if they have different CV qualifiers.  */
+  if (TYPE_QUALS (t1) != TYPE_QUALS (t2))
+    return 0;
 
   /* Void types are always the same.  */
   if (TREE_CODE (t1) == VOID_TYPE)
-    goto same_types;
+    return 1;
 
-  /* Can't be the same type if they have different CV qualifiers.  */
-  if (TYPE_QUALS (t1) != TYPE_QUALS (t2))
-    goto different_types;
+  /* 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;
 }
 
This page took 0.108103 seconds and 5 git commands to generate.