Speeding up type lookup
Martin v. Loewis
martin@loewis.home.cs.tu-berlin.de
Sat Mar 18 09:52:00 GMT 2000
When profiling gcc, I noticed that a measurable amount of time is
spent in type_hash_lookup. Upon further investigation, I found that
this is due to the large number of collisions in the hash table, which
requires a deeper analysis of the types to determine equality. In one
of my examples, there where 250 types for a single hash bucket; for a
trivial 'int main(){}' c++ program, there are up to three collisions.
This patch adds a statistics function printing usage of the hash
table, and increases the size of the hash table. In one example, it
reduced compilation time from 46 seconds to 44 seconds (approx 4%).
The full bootstrap + testsuite was made on i586-pc-linux-gnu, with no
regressions.
Regards,
Martin
2000-03-18 Martin v. Löwis <loewis@informatik.hu-berlin.de>
* tree.c (print_type_hash_statistics): New function.
(dump_tree_statistics): Call it.
(TYPE_HASH_SIZE): Increase to 1009.
Index: tree.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/tree.c,v
retrieving revision 1.125
diff -u -p -r1.125 tree.c
--- tree.c 2000/03/17 22:40:45 1.125
+++ tree.c 2000/03/18 17:30:35
@@ -269,13 +269,14 @@ struct type_hash
While all these live in the same table, they are completely independent,
and the hash code is computed differently for each of these. */
-#define TYPE_HASH_SIZE 59
+#define TYPE_HASH_SIZE 1009
struct type_hash *type_hash_table[TYPE_HASH_SIZE];
static void build_real_from_int_cst_1 PARAMS ((PTR));
static void set_type_quals PARAMS ((tree, int));
static void append_random_chars PARAMS ((char *));
static void mark_type_hash PARAMS ((void *));
+static void print_type_hash_statistics PARAMS((void));
/* If non-null, these are language-specific helper functions for
unsave_expr_now. If present, LANG_UNSAVE is called before its
@@ -4077,6 +4078,29 @@ mark_type_hash (arg)
}
}
+static void
+print_type_hash_statistics ()
+{
+ int min, max=0, total = 0;
+ int i;
+ for (i = 0; i < TYPE_HASH_SIZE; i++)
+ {
+ int count = 0;
+ struct type_hash *it;
+ for (it = type_hash_table[i]; it; it = it->next)
+ count++;
+ if (i == 0)
+ min = count;
+ else if (count < min)
+ min = count;
+ if (count > max)
+ max = count;
+ total += count;
+ }
+ fprintf (stderr, "Type hash: minimum %d, maximum %d, average %f\n",
+ min, max, 1.0 * total / TYPE_HASH_SIZE);
+}
+
/* Compute a hash code for a list of attributes (chain of TREE_LIST nodes
with names in the TREE_PURPOSE slots and args in the TREE_VALUE slots),
by adding the hash codes of the individual attributes. */
@@ -5247,6 +5271,7 @@ dump_tree_statistics ()
print_obstack_statistics ("temporary_obstack", &temporary_obstack);
print_obstack_statistics ("momentary_obstack", &momentary_obstack);
print_obstack_statistics ("temp_decl_obstack", &temp_decl_obstack);
+ print_type_hash_statistics ();
print_lang_statistics ();
}
More information about the Gcc-patches
mailing list