From c4fcd06a10ddacc81f535b165034dbaa93b6005c Mon Sep 17 00:00:00 2001
From: Richard Guenther <rguenther@suse.de>
Date: Fri, 23 Jul 2010 14:01:49 +0000
Subject: [PATCH] lto-symtab.c (lto_symtab_merge): Use gtc_mode enum values.

2010-07-23  Richard Guenther  <rguenther@suse.de>

	* lto-symtab.c (lto_symtab_merge): Use gtc_mode enum
	values.
	(lto_symtab_merge_decls_2): Likewise.
	* tree-ssa.c (useless_type_conversion_p): Likewise.
	* lto-streamer-in.c (input_gimple_stmt): Likewise.
	* gimple.c (gtc_visited2, gtc_ob2): Remove.
	(struct type_pair_d): Make same_p an array indexed by mode.
	Update comment.
	(lookup_type_pair): Update initialization.
	(struct sccs): Adjust same_p type.
	(gimple_types_compatible_p_1, gtc_visit, gimple_types_compatible_p):
	Adjust.
	(print_gimple_types_stats): Likewise.
	* gimple.h (enum gtc_mode): New.
	(gimple_types_compatible_p): Adjust prototype.

From-SVN: r162461
---
 gcc/ChangeLog         |  18 +++++++
 gcc/gimple.c          | 109 ++++++++++++++++--------------------------
 gcc/gimple.h          |   3 +-
 gcc/lto-streamer-in.c |   2 +-
 gcc/lto-symtab.c      |   9 ++--
 gcc/tree-ssa.c        |   2 +-
 6 files changed, 67 insertions(+), 76 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c96691a88c38..eacb59ca7bce 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,21 @@
+2010-07-23  Richard Guenther  <rguenther@suse.de>
+
+	* lto-symtab.c (lto_symtab_merge): Use gtc_mode enum
+	values.
+	(lto_symtab_merge_decls_2): Likewise.
+	* tree-ssa.c (useless_type_conversion_p): Likewise.
+	* lto-streamer-in.c (input_gimple_stmt): Likewise.
+	* gimple.c (gtc_visited2, gtc_ob2): Remove.
+	(struct type_pair_d): Make same_p an array indexed by mode.
+	Update comment.
+	(lookup_type_pair): Update initialization.
+	(struct sccs): Adjust same_p type.
+	(gimple_types_compatible_p_1, gtc_visit, gimple_types_compatible_p):
+	Adjust.
+	(print_gimple_types_stats): Likewise.
+	* gimple.h (enum gtc_mode): New.
+	(gimple_types_compatible_p): Adjust prototype.
+
 2010-07-23  Daniel Jacobowitz  <dan@codesourcery.com>
 
 	* dwarf2out.c (dwarf2out_frame_debug): Check for queued saves
diff --git a/gcc/gimple.c b/gcc/gimple.c
index 8453be0c002d..e3de8344c56f 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -47,8 +47,6 @@ 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
@@ -3157,20 +3155,20 @@ static hashval_t gimple_type_hash (const void *);
 
 /* Structure used to maintain a cache of some type pairs compared by
    gimple_types_compatible_p when comparing aggregate types.  There are
-   four possible values for SAME_P:
+   three possible values for SAME_P:
 
    	-2: The pair (T1, T2) has just been inserted in the table.
-	-1: The pair (T1, T2) is currently being compared.
 	 0: T1 and T2 are different types.
 	 1: T1 and T2 are the same type.
 
-   This table is only used when comparing aggregate types to avoid
-   infinite recursion due to self-referential types.  */
+   The two elements in the SAME_P array are indexed by the comparison
+   mode gtc_mode.  */
+
 struct type_pair_d
 {
   unsigned int uid1;
   unsigned int uid2;
-  int same_p;
+  signed char same_p[2];
 };
 typedef struct type_pair_d *type_pair_t;
 
@@ -3227,7 +3225,8 @@ lookup_type_pair (tree t1, tree t2, htab_t *visited_p, struct obstack *ob_p)
       p = XOBNEW (ob_p, struct type_pair_d);
       p->uid1 = TYPE_UID (t1);
       p->uid2 = TYPE_UID (t2);
-      p->same_p = -2;
+      p->same_p[0] = -2;
+      p->same_p[1] = -2;
       *slot = (void *) p;
     }
 
@@ -3246,7 +3245,7 @@ struct sccs
   bool on_sccstack;
   union {
     hashval_t hash;
-    int same_p;
+    signed char same_p;
   } u;
 };
 
@@ -3366,7 +3365,8 @@ gimple_compatible_complete_and_incomplete_subtype_p (tree t1, tree t2)
 }
 
 static bool
-gimple_types_compatible_p_1 (tree, tree, bool, VEC(type_pair_t, heap) **,
+gimple_types_compatible_p_1 (tree, tree, enum gtc_mode, type_pair_t,
+			     VEC(type_pair_t, heap) **,
 			     struct pointer_map_t *, struct obstack *);
 
 /* DFS visit the edge from the callers type pair with state *STATE to
@@ -3376,7 +3376,7 @@ gimple_types_compatible_p_1 (tree, tree, bool, VEC(type_pair_t, heap) **,
    SCCSTACK, SCCSTATE and SCCSTATE_OBSTACK are state for the DFS walk done.  */
 
 static bool
-gtc_visit (tree t1, tree t2, bool for_merging_p,
+gtc_visit (tree t1, tree t2, enum gtc_mode mode,
 	   struct sccs *state,
 	   VEC(type_pair_t, heap) **sccstack,
 	   struct pointer_map_t *sccstate,
@@ -3456,33 +3456,28 @@ gtc_visit (tree t1, tree t2, bool for_merging_p,
     return false;
 
   /* Allocate a new cache entry for this comparison.  */
-  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)
+  p = lookup_type_pair (t1, t2, &gtc_visited, &gtc_ob);
+  if (p->same_p[mode] == 0 || p->same_p[mode] == 1)
     {
       /* We have already decided whether T1 and T2 are the
 	 same, return the cached result.  */
-      return p->same_p == 1;
+      return p->same_p[mode] == 1;
     }
 
-  gcc_assert (p->same_p == -2);
-
   if ((slot = pointer_map_contains (sccstate, p)) != NULL)
     cstate = (struct sccs *)*slot;
   if (!cstate)
     {
       bool res;
       /* Not yet visited.  DFS recurse.  */
-      res = gimple_types_compatible_p_1 (t1, t2, for_merging_p,
+      res = gimple_types_compatible_p_1 (t1, t2, mode, p,
 					 sccstack, sccstate, sccstate_obstack);
       if (!cstate)
 	cstate = (struct sccs *)* pointer_map_contains (sccstate, p);
       state->low = MIN (state->low, cstate->low);
       /* If the type is no longer on the SCC stack and thus is not part
-	 of the parents SCC mix in its hash value.  Otherwise we will
-	 ignore the type for hashing purposes and return the unaltered
-	 hash value.  */
+	 of the parents SCC, return its state.  Otherwise we will
+	 ignore this pair and assume equality.  */
       if (!cstate->on_sccstack)
 	return res;
     }
@@ -3498,19 +3493,15 @@ gtc_visit (tree t1, tree t2, bool for_merging_p,
    SCCSTACK, SCCSTATE and SCCSTATE_OBSTACK are state for the DFS walk done.  */
 
 static bool
-gimple_types_compatible_p_1 (tree t1, tree t2, bool for_merging_p,
+gimple_types_compatible_p_1 (tree t1, tree t2, enum gtc_mode mode,
+			     type_pair_t p,
 			     VEC(type_pair_t, heap) **sccstack,
 			     struct pointer_map_t *sccstate,
 			     struct obstack *sccstate_obstack)
 {
-  type_pair_t p;
   struct sccs *state;
 
-  /* Allocate a new cache entry for this comparison.  */
-  p = lookup_type_pair (t1, t2,
-			for_merging_p ? &gtc_visited : &gtc_visited2,
-			for_merging_p ? &gtc_ob : &gtc_ob2);
-  gcc_assert (p->same_p == -2);
+  gcc_assert (p->same_p[mode] == -2);
 
   state = XOBNEW (sccstate_obstack, struct sccs);
   *pointer_map_insert (sccstate, p) = state;
@@ -3529,7 +3520,7 @@ gimple_types_compatible_p_1 (tree t1, tree t2, bool for_merging_p,
     {
     case VECTOR_TYPE:
     case COMPLEX_TYPE:
-      if (!gtc_visit (TREE_TYPE (t1), TREE_TYPE (t2), for_merging_p,
+      if (!gtc_visit (TREE_TYPE (t1), TREE_TYPE (t2), mode,
 		      state, sccstack, sccstate, sccstate_obstack))
 	goto different_types;
       goto same_types;
@@ -3537,7 +3528,7 @@ gimple_types_compatible_p_1 (tree t1, tree t2, bool for_merging_p,
     case ARRAY_TYPE:
       /* Array types are the same if the element types are the same and
 	 the number of elements are the same.  */
-      if (!gtc_visit (TREE_TYPE (t1), TREE_TYPE (t2), for_merging_p,
+      if (!gtc_visit (TREE_TYPE (t1), TREE_TYPE (t2), mode,
 		      state, sccstack, sccstate, sccstate_obstack)
 	  || TYPE_STRING_FLAG (t1) != TYPE_STRING_FLAG (t2)
 	  || TYPE_NONALIASED_COMPONENT (t1) != TYPE_NONALIASED_COMPONENT (t2))
@@ -3587,8 +3578,7 @@ gimple_types_compatible_p_1 (tree t1, tree t2, bool for_merging_p,
     case METHOD_TYPE:
       /* Method types should belong to the same class.  */
       if (!gtc_visit (TYPE_METHOD_BASETYPE (t1), TYPE_METHOD_BASETYPE (t2),
-		      for_merging_p,
-		      state, sccstack, sccstate, sccstate_obstack))
+		      mode, state, sccstack, sccstate, sccstate_obstack))
 	goto different_types;
 
       /* Fallthru  */
@@ -3596,10 +3586,10 @@ gimple_types_compatible_p_1 (tree t1, tree t2, bool for_merging_p,
     case FUNCTION_TYPE:
       /* Function types are the same if the return type and arguments types
 	 are the same.  */
-      if ((for_merging_p
+      if ((mode != GTC_DIAG
 	   || !gimple_compatible_complete_and_incomplete_subtype_p
 	         (TREE_TYPE (t1), TREE_TYPE (t2)))
-	  && !gtc_visit (TREE_TYPE (t1), TREE_TYPE (t2), for_merging_p,
+	  && !gtc_visit (TREE_TYPE (t1), TREE_TYPE (t2), mode,
 			 state, sccstack, sccstate, sccstate_obstack))
 	goto different_types;
 
@@ -3616,11 +3606,10 @@ gimple_types_compatible_p_1 (tree t1, tree t2, bool for_merging_p,
 	       parms1 && parms2;
 	       parms1 = TREE_CHAIN (parms1), parms2 = TREE_CHAIN (parms2))
 	    {
-	      if ((for_merging_p
+	      if ((mode == GTC_MERGE
 		   || !gimple_compatible_complete_and_incomplete_subtype_p
 		         (TREE_VALUE (parms1), TREE_VALUE (parms2)))
-		  && !gtc_visit (TREE_VALUE (parms1), TREE_VALUE (parms2),
-				 for_merging_p,
+		  && !gtc_visit (TREE_VALUE (parms1), TREE_VALUE (parms2), mode,
 				 state, sccstack, sccstate, sccstate_obstack))
 		goto different_types;
 	    }
@@ -3633,10 +3622,10 @@ gimple_types_compatible_p_1 (tree t1, tree t2, bool for_merging_p,
 
     case OFFSET_TYPE:
       {
-	if (!gtc_visit (TREE_TYPE (t1), TREE_TYPE (t2), for_merging_p,
+	if (!gtc_visit (TREE_TYPE (t1), TREE_TYPE (t2), mode,
 			state, sccstack, sccstate, sccstate_obstack)
 	    || !gtc_visit (TYPE_OFFSET_BASETYPE (t1),
-			   TYPE_OFFSET_BASETYPE (t2), for_merging_p,
+			   TYPE_OFFSET_BASETYPE (t2), mode,
 			   state, sccstack, sccstate, sccstate_obstack))
 	  goto different_types;
 
@@ -3653,14 +3642,14 @@ gimple_types_compatible_p_1 (tree t1, tree t2, bool for_merging_p,
 
 	/* If one pointer points to an incomplete type variant of
 	   the other pointed-to type they are the same.  */
-	if (!for_merging_p
+	if (mode == GTC_DIAG
 	    && 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 (gtc_visit (TREE_TYPE (t1), TREE_TYPE (t2), for_merging_p,
+	if (gtc_visit (TREE_TYPE (t1), TREE_TYPE (t2), mode,
 		       state, sccstack, sccstate, sccstate_obstack))
 	  goto same_types;
 
@@ -3756,7 +3745,7 @@ gimple_types_compatible_p_1 (tree t1, tree t2, bool for_merging_p,
 	    if (DECL_NAME (f1) != DECL_NAME (f2)
 		|| DECL_NONADDRESSABLE_P (f1) != DECL_NONADDRESSABLE_P (f2)
 		|| !gimple_compare_field_offset (f1, f2)
-		|| !gtc_visit (TREE_TYPE (f1), TREE_TYPE (f2), for_merging_p,
+		|| !gtc_visit (TREE_TYPE (f1), TREE_TYPE (f2), mode,
 			       state, sccstack, sccstate, sccstate_obstack))
 	      goto different_types;
 	  }
@@ -3795,7 +3784,7 @@ pop:
 	  x = VEC_pop (type_pair_t, *sccstack);
 	  cstate = (struct sccs *)*pointer_map_contains (sccstate, x);
 	  cstate->on_sccstack = false;
-	  x->same_p = cstate->u.same_p;
+	  x->same_p[mode] = cstate->u.same_p;
 	}
       while (x != p);
     }
@@ -3808,7 +3797,7 @@ pop:
    are considered different, otherwise they are considered compatible.  */
 
 bool
-gimple_types_compatible_p (tree t1, tree t2, bool for_merging_p)
+gimple_types_compatible_p (tree t1, tree t2, enum gtc_mode mode)
 {
   VEC(type_pair_t, heap) *sccstack = NULL;
   struct pointer_map_t *sccstate;
@@ -3889,21 +3878,19 @@ gimple_types_compatible_p (tree t1, tree t2, bool for_merging_p)
 
   /* 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,
-			for_merging_p ? &gtc_visited : &gtc_visited2,
-			for_merging_p ? &gtc_ob : &gtc_ob2);
-  if (p->same_p == 0 || p->same_p == 1)
+  p = lookup_type_pair (t1, t2, &gtc_visited, &gtc_ob);
+  if (p->same_p[mode] == 0 || p->same_p[mode] == 1)
     {
       /* We have already decided whether T1 and T2 are the
 	 same, return the cached result.  */
-      return p->same_p == 1;
+      return p->same_p[mode] == 1;
     }
 
   /* Now set up the SCC machinery for the comparison.  */
   gtc_next_dfs_num = 1;
   sccstate = pointer_map_create ();
   gcc_obstack_init (&sccstate_obstack);
-  res = gimple_types_compatible_p_1 (t1, t2, for_merging_p,
+  res = gimple_types_compatible_p_1 (t1, t2, mode, p,
 				     &sccstack, sccstate, &sccstate_obstack);
   VEC_free (type_pair_t, heap, sccstack);
   pointer_map_destroy (sccstate);
@@ -4210,7 +4197,7 @@ 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), true);
+				    CONST_CAST_TREE (t2), GTC_MERGE);
 }
 
 
@@ -4323,23 +4310,13 @@ print_gimple_types_stats (void)
   else
     fprintf (stderr, "GIMPLE type table is empty\n");
   if (gtc_visited)
-    fprintf (stderr, "GIMPLE type merging comparison table: size %ld, %ld "
+    fprintf (stderr, "GIMPLE type comparison table: size %ld, %ld "
 	     "elements, %ld searches, %ld collisions (ratio: %f)\n",
 	     (long) htab_size (gtc_visited),
 	     (long) htab_elements (gtc_visited),
 	     (long) gtc_visited->searches,
 	     (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");
 }
@@ -4369,12 +4346,6 @@ 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;
-    }
 }
 
 
diff --git a/gcc/gimple.h b/gcc/gimple.h
index af4799e608df..790998637f0b 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -956,7 +956,8 @@ 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);
+enum gtc_mode { GTC_MERGE = 0, GTC_DIAG = 1 };
+extern bool gimple_types_compatible_p (tree, tree, enum gtc_mode);
 extern void print_gimple_types_stats (void);
 extern void free_gimple_type_tables (void);
 extern tree gimple_unsigned_type (tree);
diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c
index 9d3e7ec94a14..3451b84c076f 100644
--- a/gcc/lto-streamer-in.c
+++ b/gcc/lto-streamer-in.c
@@ -962,7 +962,7 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in,
 		      if (tem == field
 			  || (gimple_types_compatible_p (TREE_TYPE (tem),
 							 TREE_TYPE (field),
-							 false)
+							 GTC_DIAG)
 			      && DECL_NONADDRESSABLE_P (tem)
 				 == DECL_NONADDRESSABLE_P (field)
 			      && gimple_compare_field_offset (tem, field)))
diff --git a/gcc/lto-symtab.c b/gcc/lto-symtab.c
index f7bb9b6e47a0..9e782d578a2b 100644
--- a/gcc/lto-symtab.c
+++ b/gcc/lto-symtab.c
@@ -349,7 +349,7 @@ lto_symtab_merge (lto_symtab_entry_t prevailing, lto_symtab_entry_t entry)
   if (TREE_CODE (decl) == FUNCTION_DECL)
     {
       if (!gimple_types_compatible_p (TREE_TYPE (prevailing_decl),
-				      TREE_TYPE (decl), false))
+				      TREE_TYPE (decl), GTC_DIAG))
 	/* 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
@@ -382,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 (!gimple_types_compatible_p (prevailing_type, type, false))
+  if (!gimple_types_compatible_p (prevailing_type, type, GTC_DIAG))
     {
       if (COMPLETE_TYPE_P (type))
 	return false;
@@ -408,7 +408,8 @@ lto_symtab_merge (lto_symtab_entry_t prevailing, lto_symtab_entry_t entry)
 	    return false;
 
 	  if (!gimple_types_compatible_p (gimple_register_type (tem1),
-					  gimple_register_type (tem2), false))
+					  gimple_register_type (tem2),
+					  GTC_DIAG))
 	    return false;
 	}
 
@@ -603,7 +604,7 @@ lto_symtab_merge_decls_2 (void **slot)
   for (i = 0; VEC_iterate (tree, mismatches, i, decl); ++i)
     {
       if (!gimple_types_compatible_p (TREE_TYPE (prevailing->decl),
-				      TREE_TYPE (decl), false))
+				      TREE_TYPE (decl), GTC_DIAG))
 	diagnosed_p |= warning_at (DECL_SOURCE_LOCATION (decl), 0,
 				   "type of %qD does not match original "
 				   "declaration", decl);
diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c
index c31b0d1ce082..687c6393aaa2 100644
--- a/gcc/tree-ssa.c
+++ b/gcc/tree-ssa.c
@@ -1427,7 +1427,7 @@ useless_type_conversion_p (tree outer_type, tree inner_type)
   else if (AGGREGATE_TYPE_P (inner_type)
 	   && TREE_CODE (inner_type) == TREE_CODE (outer_type))
     return (in_lto_p
-	    && gimple_types_compatible_p (outer_type, inner_type, false));
+	    && gimple_types_compatible_p (outer_type, inner_type, GTC_DIAG));
 
   return false;
 }
-- 
GitLab