lto-symtab.c (lto_symtab_merge): Use gimple_types_compatible_p.
authorRichard Guenther <rguenther@suse.de>
Tue, 20 Jul 2010 12:05:59 +0000 (12:05 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 20 Jul 2010 12:05:59 +0000 (12:05 +0000)
2010-07-20  Richard Guenther  <rguenther@suse.de>

* lto-symtab.c (lto_symtab_merge): Use gimple_types_compatible_p.
(lto_symtab_merge_decls_2): Likewise.
* gimple.h (gimple_types_compatible_p): Declare.
* gimple.c (gimple_queue_type_fixup): Remove.
(gimple_fixup_complete_and_incomplete_subtype_p): Likewise.
(gimple_compatible_complete_and_incomplete_type_p): New
function.
(gimple_types_compatible_p): Adjust.
(gimple_register_type): Remove type fixup code.
(print_gimple_types_stats): Adjust.
(free_gimple_type_tables): Likewise.
* lto-streamer-in.c (input_gimple_stmt): Use gimple_types_compatible_p.
* tree-ssa.c (useless_type_conversion_p): Likewise.

From-SVN: r162330

gcc/ChangeLog
gcc/gimple.c
gcc/gimple.h
gcc/lto-streamer-in.c
gcc/lto-symtab.c
gcc/tree-ssa.c

index cb3b1e1..72cd6ae 100644 (file)
@@ -1,5 +1,21 @@
 2010-07-20  Richard Guenther  <rguenther@suse.de>
 
+       * lto-symtab.c (lto_symtab_merge): Use gimple_types_compatible_p.
+       (lto_symtab_merge_decls_2): Likewise.
+       * gimple.h (gimple_types_compatible_p): Declare.
+       * gimple.c (gimple_queue_type_fixup): Remove.
+       (gimple_fixup_complete_and_incomplete_subtype_p): Likewise.
+       (gimple_compatible_complete_and_incomplete_type_p): New
+       function.
+       (gimple_types_compatible_p): Adjust.
+       (gimple_register_type): Remove type fixup code.
+       (print_gimple_types_stats): Adjust.
+       (free_gimple_type_tables): Likewise.
+       * lto-streamer-in.c (input_gimple_stmt): Use gimple_types_compatible_p.
+       * tree-ssa.c (useless_type_conversion_p): Likewise.
+
+2010-07-20  Richard Guenther  <rguenther@suse.de>
+
        PR middle-end/44971
        PR middle-end/44988
        * tree-ssa.c (maybe_optimize_var): New function split out from ...
index 5606da8..a3b1bba 100644 (file)
@@ -47,6 +47,8 @@ static struct pointer_map_t *type_hash_cache;
 /* Global type comparison cache.  */
 static htab_t gtc_visited;
 static struct obstack gtc_ob;
+static htab_t gtc_visited2;
+static struct obstack gtc_ob2;
 
 /* All the tuples have their operand vector (if present) at the very bottom
    of the structure.  Therefore, the offset required to find the
@@ -3323,37 +3325,12 @@ gimple_compare_field_offset (tree f1, tree f2)
   return false;
 }
 
-typedef struct type_fixup_s {
-    tree context;
-    tree *incomplete;
-    tree complete;
-} type_fixup;
-DEF_VEC_O(type_fixup);
-DEF_VEC_ALLOC_O(type_fixup,heap);
-
-static VEC(type_fixup, heap) *gimple_register_type_fixups = NULL;
-
-static void
-gimple_queue_type_fixup (tree context, tree *incomplete, tree complete)
-{
-  type_fixup f;
-  f.context = context;
-  f.incomplete = incomplete;
-  f.complete = complete;
-  VEC_safe_push (type_fixup, heap, gimple_register_type_fixups, &f);
-}
-
-/* If the type *T1P and the type *T2P are a complete and an incomplete
-   variant of the same type return true and queue a fixup for the
-   incomplete one and its CONTEXT.  Return false otherwise.  */
+/* If the type T1 and the type T2 are a complete and an incomplete
+   variant of the same type return true.  */
 
 static bool
-gimple_fixup_complete_and_incomplete_subtype_p (tree context1, tree *t1p,
-                                               tree context2, tree *t2p)
+gimple_compatible_complete_and_incomplete_subtype_p (tree t1, tree t2)
 {
-  tree t1 = *t1p;
-  tree t2 = *t2p;
-
   /* If one pointer points to an incomplete type variant of
      the other pointed-to type they are the same.  */
   if (TREE_CODE (t1) == TREE_CODE (t2)
@@ -3363,30 +3340,15 @@ gimple_fixup_complete_and_incomplete_subtype_p (tree context1, tree *t1p,
       && TYPE_QUALS (t1) == TYPE_QUALS (t2)
       && compare_type_names_p (TYPE_MAIN_VARIANT (t1),
                               TYPE_MAIN_VARIANT (t2), true))
-    {
-      /* Replace the pointed-to incomplete type with the complete one.
-        ???  This simple name-based merging causes at least some
-        of the ICEs in canonicalizing FIELD_DECLs during stmt
-        read.  For example in GCC we have two different struct deps
-        and we mismatch the use in struct cpp_reader in sched-int.h
-        vs. mkdeps.c.  Of course the whole exercise is for TBAA
-        with structs which contain pointers to incomplete types
-        in one unit and to complete ones in another.  So we
-        probably should merge these types only with more context.  */
-      if (COMPLETE_TYPE_P (t2))
-       gimple_queue_type_fixup (context1, t1p, t2);
-      else
-       gimple_queue_type_fixup (context2, t2p, t1);
-      return true;
-    }
+    return true;
   return false;
 }
 
 /* Return 1 iff T1 and T2 are structurally identical.
    Otherwise, return 0.  */
 
-static int
-gimple_types_compatible_p (tree t1, tree t2)
+bool
+gimple_types_compatible_p (tree t1, tree t2, bool for_merging_p)
 {
   type_pair_t p = NULL;
 
@@ -3439,7 +3401,8 @@ gimple_types_compatible_p (tree t1, tree t2)
       /* 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));
+       return gimple_types_compatible_p (TREE_TYPE (t1), TREE_TYPE (t2),
+                                         for_merging_p);
 
       /* For integral types fall thru to more complex checks.  */
     }
@@ -3460,7 +3423,9 @@ gimple_types_compatible_p (tree t1, tree t2)
 
   /* If we've visited this type pair before (in the case of aggregates
      with self-referential types), and we made a decision, return it.  */
-  p = lookup_type_pair (t1, t2, &gtc_visited, &gtc_ob);
+  p = lookup_type_pair (t1, t2,
+                       for_merging_p ? &gtc_visited : &gtc_visited2,
+                       for_merging_p ? &gtc_ob : &gtc_ob2);
   if (p->same_p == 0 || p->same_p == 1)
     {
       /* We have already decided whether T1 and T2 are the
@@ -3489,7 +3454,8 @@ gimple_types_compatible_p (tree t1, tree t2)
     case ARRAY_TYPE:
       /* 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))
+      if (!gimple_types_compatible_p (TREE_TYPE (t1), TREE_TYPE (t2),
+                                     for_merging_p)
          || TYPE_STRING_FLAG (t1) != TYPE_STRING_FLAG (t2)
          || TYPE_NONALIASED_COMPONENT (t1) != TYPE_NONALIASED_COMPONENT (t2))
        goto different_types;
@@ -3538,7 +3504,7 @@ gimple_types_compatible_p (tree t1, tree t2)
     case METHOD_TYPE:
       /* Method types should belong to the same class.  */
       if (!gimple_types_compatible_p (TYPE_METHOD_BASETYPE (t1),
-                                TYPE_METHOD_BASETYPE (t2)))
+                                     TYPE_METHOD_BASETYPE (t2), for_merging_p))
        goto different_types;
 
       /* Fallthru  */
@@ -3546,9 +3512,11 @@ gimple_types_compatible_p (tree t1, tree t2)
     case FUNCTION_TYPE:
       /* Function types are the same if the return type and arguments types
         are the same.  */
-      if (!gimple_fixup_complete_and_incomplete_subtype_p
-            (t1, &TREE_TYPE (t1), t2, &TREE_TYPE (t2))
-         && !gimple_types_compatible_p (TREE_TYPE (t1), TREE_TYPE (t2)))
+      if ((for_merging_p
+          || !gimple_compatible_complete_and_incomplete_subtype_p
+                (TREE_TYPE (t1), TREE_TYPE (t2)))
+         && !gimple_types_compatible_p (TREE_TYPE (t1), TREE_TYPE (t2),
+                                        for_merging_p))
        goto different_types;
 
       if (!targetm.comp_type_attributes (t1, t2))
@@ -3564,10 +3532,12 @@ gimple_types_compatible_p (tree t1, tree t2)
               parms1 && parms2;
               parms1 = TREE_CHAIN (parms1), parms2 = TREE_CHAIN (parms2))
            {
-             if (!gimple_fixup_complete_and_incomplete_subtype_p
-                   (t1, &TREE_VALUE (parms1), t2, &TREE_VALUE (parms2))
+             if ((for_merging_p
+                  || !gimple_compatible_complete_and_incomplete_subtype_p
+                        (TREE_VALUE (parms1), TREE_VALUE (parms2)))
                  && !gimple_types_compatible_p (TREE_VALUE (parms1),
-                                                TREE_VALUE (parms2)))
+                                                TREE_VALUE (parms2),
+                                                for_merging_p))
                goto different_types;
            }
 
@@ -3579,9 +3549,11 @@ gimple_types_compatible_p (tree t1, tree t2)
 
     case OFFSET_TYPE:
       {
-       if (!gimple_types_compatible_p (TREE_TYPE (t1), TREE_TYPE (t2))
+       if (!gimple_types_compatible_p (TREE_TYPE (t1), TREE_TYPE (t2),
+                                       for_merging_p)
            || !gimple_types_compatible_p (TYPE_OFFSET_BASETYPE (t1),
-                                          TYPE_OFFSET_BASETYPE (t2)))
+                                          TYPE_OFFSET_BASETYPE (t2),
+                                          for_merging_p))
          goto different_types;
 
        goto same_types;
@@ -3597,13 +3569,15 @@ gimple_types_compatible_p (tree t1, tree t2)
 
        /* If one pointer points to an incomplete type variant of
           the other pointed-to type they are the same.  */
-       if (gimple_fixup_complete_and_incomplete_subtype_p
-             (t1, &TREE_TYPE (t1), t2, &TREE_TYPE (t2)))
+       if (!for_merging_p
+           && gimple_compatible_complete_and_incomplete_subtype_p
+                (TREE_TYPE (t1), TREE_TYPE (t2)))
          goto same_types;
 
        /* Otherwise, pointer and reference types are the same if the
           pointed-to types are the same.  */
-       if (gimple_types_compatible_p (TREE_TYPE (t1), TREE_TYPE (t2)))
+       if (gimple_types_compatible_p (TREE_TYPE (t1), TREE_TYPE (t2),
+                                      for_merging_p))
          goto same_types;
 
        goto different_types;
@@ -3699,7 +3673,7 @@ gimple_types_compatible_p (tree t1, tree t2)
                || DECL_NONADDRESSABLE_P (f1) != DECL_NONADDRESSABLE_P (f2)
                || !gimple_compare_field_offset (f1, f2)
                || !gimple_types_compatible_p (TREE_TYPE (f1),
-                                              TREE_TYPE (f2)))
+                                              TREE_TYPE (f2), for_merging_p))
              goto different_types;
          }
 
@@ -4040,7 +4014,8 @@ gimple_type_eq (const void *p1, const void *p2)
 {
   const_tree t1 = (const_tree) p1;
   const_tree t2 = (const_tree) p2;
-  return gimple_types_compatible_p (CONST_CAST_TREE (t1), CONST_CAST_TREE (t2));
+  return gimple_types_compatible_p (CONST_CAST_TREE (t1),
+                                   CONST_CAST_TREE (t2), true);
 }
 
 
@@ -4070,14 +4045,11 @@ gimple_register_type (tree t)
   if (gimple_types == NULL)
     gimple_types = htab_create (16381, gimple_type_hash, gimple_type_eq, 0);
 
-  gcc_assert (VEC_empty (type_fixup, gimple_register_type_fixups));
   slot = htab_find_slot (gimple_types, t, INSERT);
   if (*slot
       && *(tree *)slot != t)
     {
       tree new_type = (tree) *((tree *) slot);
-      unsigned i;
-      type_fixup *f;
 
       /* Do not merge types with different addressability.  */
       gcc_assert (TREE_ADDRESSABLE (t) == TREE_ADDRESSABLE (new_type));
@@ -4129,11 +4101,6 @@ gimple_register_type (tree t)
 
       TYPE_CANONICAL (t) = new_type;
       t = new_type;
-
-      for (i = 0;
-          VEC_iterate (type_fixup, gimple_register_type_fixups, i, f); ++i)
-       if (f->context == t)
-         *(f->incomplete) = f->complete;
     }
   else
     {
@@ -4141,7 +4108,6 @@ gimple_register_type (tree t)
       *slot = (void *) t;
     }
 
-  VEC_truncate (type_fixup, gimple_register_type_fixups, 0);
   return t;
 }
 
@@ -4162,7 +4128,7 @@ print_gimple_types_stats (void)
   else
     fprintf (stderr, "GIMPLE type table is empty\n");
   if (gtc_visited)
-    fprintf (stderr, "GIMPLE type comparison table: size %ld, %ld "
+    fprintf (stderr, "GIMPLE type merging comparison table: size %ld, %ld "
             "elements, %ld searches, %ld collisions (ratio: %f)\n",
             (long) htab_size (gtc_visited),
             (long) htab_elements (gtc_visited),
@@ -4170,6 +4136,16 @@ print_gimple_types_stats (void)
             (long) gtc_visited->collisions,
             htab_collisions (gtc_visited));
   else
+    fprintf (stderr, "GIMPLE type merging comparison table is empty\n");
+  if (gtc_visited2)
+    fprintf (stderr, "GIMPLE type comparison table: size %ld, %ld "
+            "elements, %ld searches, %ld collisions (ratio: %f)\n",
+            (long) htab_size (gtc_visited2),
+            (long) htab_elements (gtc_visited2),
+            (long) gtc_visited2->searches,
+            (long) gtc_visited2->collisions,
+            htab_collisions (gtc_visited2));
+  else
     fprintf (stderr, "GIMPLE type comparison table is empty\n");
 }
 
@@ -4198,6 +4174,12 @@ free_gimple_type_tables (void)
       obstack_free (&gtc_ob, NULL);
       gtc_visited = NULL;
     }
+  if (gtc_visited2)
+    {
+      htab_delete (gtc_visited2);
+      obstack_free (&gtc_ob2, NULL);
+      gtc_visited2 = NULL;
+    }
 }
 
 
index ec7fc93..af4799e 100644 (file)
@@ -956,6 +956,7 @@ extern tree get_call_expr_in (tree t);
 extern void recalculate_side_effects (tree);
 extern bool gimple_compare_field_offset (tree, tree);
 extern tree gimple_register_type (tree);
+extern bool gimple_types_compatible_p (tree, tree, bool);
 extern void print_gimple_types_stats (void);
 extern void free_gimple_type_tables (void);
 extern tree gimple_unsigned_type (tree);
index 274418e..9d3e7ec 100644 (file)
@@ -960,7 +960,9 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in,
                  for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem))
                    {
                      if (tem == field
-                         || (TREE_TYPE (tem) == TREE_TYPE (field)
+                         || (gimple_types_compatible_p (TREE_TYPE (tem),
+                                                        TREE_TYPE (field),
+                                                        false)
                              && DECL_NONADDRESSABLE_P (tem)
                                 == DECL_NONADDRESSABLE_P (field)
                              && gimple_compare_field_offset (tem, field)))
index 978bccb..f7bb9b6 100644 (file)
@@ -348,7 +348,8 @@ lto_symtab_merge (lto_symtab_entry_t prevailing, lto_symtab_entry_t entry)
 
   if (TREE_CODE (decl) == FUNCTION_DECL)
     {
-      if (TREE_TYPE (prevailing_decl) != TREE_TYPE (decl))
+      if (!gimple_types_compatible_p (TREE_TYPE (prevailing_decl),
+                                     TREE_TYPE (decl), false))
        /* If we don't have a merged type yet...sigh.  The linker
           wouldn't complain if the types were mismatched, so we
           probably shouldn't either.  Just use the type from
@@ -381,7 +382,7 @@ lto_symtab_merge (lto_symtab_entry_t prevailing, lto_symtab_entry_t entry)
      fixup process didn't yet run.  */
   prevailing_type = gimple_register_type (prevailing_type);
   type = gimple_register_type (type);
-  if (prevailing_type != type)
+  if (!gimple_types_compatible_p (prevailing_type, type, false))
     {
       if (COMPLETE_TYPE_P (type))
        return false;
@@ -406,7 +407,8 @@ lto_symtab_merge (lto_symtab_entry_t prevailing, lto_symtab_entry_t entry)
          if (TREE_CODE (tem1) != TREE_CODE (tem2))
            return false;
 
-         if (gimple_register_type (tem1) != gimple_register_type (tem2))
+         if (!gimple_types_compatible_p (gimple_register_type (tem1),
+                                         gimple_register_type (tem2), false))
            return false;
        }
 
@@ -600,7 +602,8 @@ lto_symtab_merge_decls_2 (void **slot)
   /* Diagnose all mismatched re-declarations.  */
   for (i = 0; VEC_iterate (tree, mismatches, i, decl); ++i)
     {
-      if (TREE_TYPE (prevailing->decl) != TREE_TYPE (decl))
+      if (!gimple_types_compatible_p (TREE_TYPE (prevailing->decl),
+                                     TREE_TYPE (decl), false))
        diagnosed_p |= warning_at (DECL_SOURCE_LOCATION (decl), 0,
                                   "type of %qD does not match original "
                                   "declaration", decl);
index bba49ff..d4c519f 100644 (file)
@@ -1426,7 +1426,7 @@ useless_type_conversion_p (tree outer_type, tree inner_type)
      compared types.  */
   else if (AGGREGATE_TYPE_P (inner_type)
           && TREE_CODE (inner_type) == TREE_CODE (outer_type))
-    return false;
+    return gimple_types_compatible_p (outer_type, inner_type, false);
 
   return false;
 }