diff mbox

[1/n] Improve LTO type merging

Message ID alpine.LNX.2.00.1209111532240.28649@zhemvz.fhfr.qr
State New
Headers show

Commit Message

Richard Biener Sept. 11, 2012, 1:33 p.m. UTC
This removes the unused gtc_mode param and moves lifetime management
of the various tables to a central place, avoiding repeated checks.

LTO bootstrapped on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

2012-09-11  Richard Guenther  <rguenther@suse.de>

	* lto.c (enum gtc_mode): Remove.
	(struct type_pair_d): Adjust.
	(lookup_type_pair): Likewise.
	(gimple_type_leader): Do not mark as deletable.
	(gimple_lookup_type_leader): Adjust.
	(gtc_visit): Likewise.
	(gimple_types_compatible_p_1): Likewise.
	(gimple_types_compatible_p): Likewise.
	(gimple_type_hash): Likewise.
	(gimple_register_type): Likewise.
	(read_cgraph_and_symbols): Manage lifetime of tables
	here.
diff mbox

Patch

Index: gcc/lto/lto.c
===================================================================
--- gcc/lto/lto.c	(revision 191177)
+++ gcc/lto/lto.c	(working copy)
@@ -276,6 +276,8 @@  lto_read_in_decl_state (struct data_in *
   return data;
 }
 
+
+
 /* Global type table.  FIXME, it should be possible to re-use some
    of the type hashing routines in tree.c (type_hash_canon, type_hash_lookup,
    etc), but those assume that types were built with the various
@@ -285,8 +287,6 @@  static GTY((if_marked ("ggc_marked_p"),
 static GTY((if_marked ("tree_int_map_marked_p"), param_is (struct tree_int_map)))
   htab_t type_hash_cache;
 
-enum gtc_mode { GTC_MERGE = 0, GTC_DIAG = 1 };
-
 static hashval_t gimple_type_hash (const void *);
 
 /* Structure used to maintain a cache of some type pairs compared by
@@ -295,16 +295,13 @@  static hashval_t gimple_type_hash (const
 
    	-2: The pair (T1, T2) has just been inserted in the table.
 	 0: T1 and T2 are different types.
-	 1: T1 and T2 are the same type.
-
-   The two elements in the SAME_P array are indexed by the comparison
-   mode gtc_mode.  */
+	 1: T1 and T2 are the same type.  */
 
 struct type_pair_d
 {
   unsigned int uid1;
   unsigned int uid2;
-  signed char same_p[2];
+  signed char same_p;
 };
 typedef struct type_pair_d *type_pair_t;
 DEF_VEC_P(type_pair_t);
@@ -323,9 +320,6 @@  lookup_type_pair (tree t1, tree t2)
   unsigned int index;
   unsigned int uid1, uid2;
 
-  if (type_pair_cache == NULL)
-    type_pair_cache = XCNEWVEC (struct type_pair_d, GIMPLE_TYPE_PAIR_SIZE);
-
   if (TYPE_UID (t1) < TYPE_UID (t2))
     {
       uid1 = TYPE_UID (t1);
@@ -348,8 +342,7 @@  lookup_type_pair (tree t1, tree t2)
 
   type_pair_cache [index].uid1 = uid1;
   type_pair_cache [index].uid2 = uid2;
-  type_pair_cache [index].same_p[0] = -2;
-  type_pair_cache [index].same_p[1] = -2;
+  type_pair_cache [index].same_p = -2;
 
   return &type_pair_cache[index];
 }
@@ -381,7 +374,7 @@  typedef struct GTY(()) gimple_type_leade
 } gimple_type_leader_entry;
 
 #define GIMPLE_TYPE_LEADER_SIZE 16381
-static GTY((deletable, length("GIMPLE_TYPE_LEADER_SIZE")))
+static GTY((length("GIMPLE_TYPE_LEADER_SIZE")))
   gimple_type_leader_entry *gimple_type_leader;
 
 /* Lookup an existing leader for T and return it or NULL_TREE, if
@@ -392,9 +385,6 @@  gimple_lookup_type_leader (tree t)
 {
   gimple_type_leader_entry *leader;
 
-  if (!gimple_type_leader)
-    return NULL_TREE;
-
   leader = &gimple_type_leader[TYPE_UID (t) % GIMPLE_TYPE_LEADER_SIZE];
   if (leader->type != t)
     return NULL_TREE;
@@ -403,7 +393,6 @@  gimple_lookup_type_leader (tree t)
 }
 
 
-
 /* Return true if T1 and T2 have the same name.  If FOR_COMPLETION_P is
    true then if any type has no name return false, otherwise return
    true if both types have no names.  */
@@ -535,11 +524,11 @@  gtc_visit (tree t1, tree t2,
 
   /* Allocate a new cache entry for this comparison.  */
   p = lookup_type_pair (t1, t2);
-  if (p->same_p[GTC_MERGE] == 0 || p->same_p[GTC_MERGE] == 1)
+  if (p->same_p == 0 || p->same_p == 1)
     {
       /* We have already decided whether T1 and T2 are the
 	 same, return the cached result.  */
-      return p->same_p[GTC_MERGE] == 1;
+      return p->same_p == 1;
     }
 
   if ((slot = pointer_map_contains (sccstate, p)) != NULL)
@@ -574,7 +563,7 @@  gimple_types_compatible_p_1 (tree t1, tr
 {
   struct sccs *state;
 
-  gcc_assert (p->same_p[GTC_MERGE] == -2);
+  gcc_assert (p->same_p == -2);
 
   state = XOBNEW (sccstate_obstack, struct sccs);
   *pointer_map_insert (sccstate, p) = state;
@@ -861,7 +850,7 @@  pop:
 	  x = VEC_pop (type_pair_t, *sccstack);
 	  cstate = (struct sccs *)*pointer_map_contains (sccstate, x);
 	  cstate->on_sccstack = false;
-	  x->same_p[GTC_MERGE] = state->u.same_p;
+	  x->same_p = state->u.same_p;
 	}
       while (x != p);
     }
@@ -958,11 +947,11 @@  gimple_types_compatible_p (tree t1, tree
   /* 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);
-  if (p->same_p[GTC_MERGE] == 0 || p->same_p[GTC_MERGE] == 1)
+  if (p->same_p == 0 || p->same_p == 1)
     {
       /* We have already decided whether T1 and T2 are the
 	 same, return the cached result.  */
-      return p->same_p[GTC_MERGE] == 1;
+      return p->same_p == 1;
     }
 
   /* Now set up the SCC machinery for the comparison.  */
@@ -1031,8 +1020,6 @@  visit (tree t, struct sccs *state, hashv
   return v;
 }
 
-
-
 /* Hash NAME with the previous hash value V and return it.  */
 
 static hashval_t
@@ -1304,10 +1291,6 @@  gimple_type_hash (const void *p)
   void **slot;
   struct tree_int_map m;
 
-  if (type_hash_cache == NULL)
-    type_hash_cache = htab_create_ggc (512, tree_int_map_hash,
-				       tree_int_map_eq, NULL);
-
   m.base.from = CONST_CAST_TREE (t);
   if ((slot = htab_find_slot (type_hash_cache, &m, NO_INSERT))
       && *slot)
@@ -1325,6 +1308,7 @@  gimple_type_hash (const void *p)
 
   return val;
 }
+
 /* Returns nonzero if P1 and P2 are equal.  */
 
 static int
@@ -1393,14 +1377,6 @@  static 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);
 }
 
@@ -2895,6 +2871,12 @@  read_cgraph_and_symbols (unsigned nfiles
 
   tree_with_vars = htab_create_ggc (101, htab_hash_pointer, htab_eq_pointer,
 				    NULL);
+  type_hash_cache = htab_create_ggc (512, tree_int_map_hash,
+				     tree_int_map_eq, NULL);
+  type_pair_cache = XCNEWVEC (struct type_pair_d, GIMPLE_TYPE_PAIR_SIZE);
+  gimple_type_leader = ggc_alloc_cleared_vec_gimple_type_leader_entry_s
+		        (GIMPLE_TYPE_LEADER_SIZE);
+  gimple_types = htab_create_ggc (16381, gimple_type_hash, gimple_type_eq, 0);
 
   if (!quiet_flag)
     fprintf (stderr, "Reading object files:");
@@ -2965,21 +2947,12 @@  read_cgraph_and_symbols (unsigned nfiles
   lto_fixup_decls (all_file_decl_data);
   htab_delete (tree_with_vars);
   tree_with_vars = NULL;
-  if (gimple_types)
-    {
-      htab_delete (gimple_types);
-      gimple_types = NULL;
-    }
-  if (type_hash_cache)
-    {
-      htab_delete (type_hash_cache);
-      type_hash_cache = NULL;
-    }
-  if (type_pair_cache)
-    {
-      free (type_pair_cache);
-      type_pair_cache = NULL;
-    }
+  htab_delete (gimple_types);
+  gimple_types = NULL;
+  htab_delete (type_hash_cache);
+  type_hash_cache = NULL;
+  free (type_pair_cache);
+  type_pair_cache = NULL;
   gimple_type_leader = NULL;
   free_gimple_type_tables ();
   ggc_collect ();