gimple.c (gimple_register_type_1): New function, split out from ...
authorRichard Guenther <rguenther@suse.de>
Wed, 18 May 2011 11:34:43 +0000 (11:34 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 18 May 2011 11:34:43 +0000 (11:34 +0000)
2011-05-18  Richard Guenther  <rguenther@suse.de>

* gimple.c (gimple_register_type_1): New function, split out from ...
(gimple_register_type): ... here.  Avoid infinite recursion.

From-SVN: r173857

gcc/ChangeLog
gcc/gimple.c

index 86d68134300a6c4dd3b573b2d6d861278408c50d..a8e1c3c4814ab872996a7c729f657f0e6f43bfe0 100644 (file)
@@ -1,3 +1,8 @@
+2011-05-18  Richard Guenther  <rguenther@suse.de>
+
+       * gimple.c (gimple_register_type_1): New function, split out from ...
+       (gimple_register_type): ... here.  Avoid infinite recursion.
+
 2011-05-18  Ira Rosen  <ira.rosen@linaro.org>
 
        PR tree-optimization/41881
index 831ca31e0e51135b3dc0b706a89e19c44861acba..cd57d5b47c05d553bc4f0ff035435c9c4023372d 100644 (file)
@@ -4487,23 +4487,17 @@ gimple_type_eq (const void *p1, const void *p2)
 }
 
 
-/* Register type T in the global type table gimple_types.
-   If another type T', compatible with T, already existed in
-   gimple_types then return T', otherwise return T.  This is used by
-   LTO to merge identical types read from different TUs.  */
+/* Worker for gimple_register_type.
+   Register type T in the global type table gimple_types.
+   When REGISTERING_MV is false first recurse for the main variant of T.  */
 
-tree
-gimple_register_type (tree t)
+static tree
+gimple_register_type_1 (tree t, bool registering_mv)
 {
   void **slot;
   gimple_type_leader_entry *leader;
   tree mv_leader = NULL_TREE;
 
-  gcc_assert (TYPE_P (t));
-
-  if (!gimple_type_leader)
-    gimple_type_leader = ggc_alloc_cleared_vec_gimple_type_leader_entry_s
-                               (GIMPLE_TYPE_LEADER_SIZE);
   /* If we registered this type before return the cached result.  */
   leader = &gimple_type_leader[TYPE_UID (t) % GIMPLE_TYPE_LEADER_SIZE];
   if (leader->type == t)
@@ -4511,12 +4505,14 @@ gimple_register_type (tree 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.  */
-  if (TYPE_MAIN_VARIANT (t) != t)
-    mv_leader = gimple_register_type (TYPE_MAIN_VARIANT (t));
-
-  if (gimple_types == NULL)
-    gimple_types = htab_create_ggc (16381, gimple_type_hash, gimple_type_eq, 0);
+     up taking typedef ids for structure tags during comparison.
+     It also makes sure that main variants will be merged to main variants.
+     As we are operating on a possibly partially fixed up type graph
+     do not bother to recurse more than once, otherwise we may end up
+     walking in circles.  */
+  if (!registering_mv
+      && TYPE_MAIN_VARIANT (t) != t)
+    mv_leader = gimple_register_type_1 (TYPE_MAIN_VARIANT (t), true);
 
   slot = htab_find_slot (gimple_types, t, INSERT);
   if (*slot
@@ -4602,6 +4598,25 @@ gimple_register_type (tree t)
   return t;
 }
 
+/* Register type T in the global type table gimple_types.
+   If another type T', compatible with T, already existed in
+   gimple_types then return T', otherwise return T.  This is used by
+   LTO to merge identical types read from different TUs.  */
+
+tree
+gimple_register_type (tree t)
+{
+  gcc_assert (TYPE_P (t));
+
+  if (!gimple_type_leader)
+    gimple_type_leader = ggc_alloc_cleared_vec_gimple_type_leader_entry_s
+                               (GIMPLE_TYPE_LEADER_SIZE);
+
+  if (gimple_types == NULL)
+    gimple_types = htab_create_ggc (16381, gimple_type_hash, gimple_type_eq, 0);
+
+  return gimple_register_type_1 (t, false);
+}
 
 /* The TYPE_CANONICAL merging machinery.  It should closely resemble
    the middle-end types_compatible_p function.  It needs to avoid