aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/Makefile.in2
-rw-r--r--gcc/alloc-pool.c125
-rw-r--r--gcc/alloc-pool.h3
-rw-r--r--gcc/toplev.c1
5 files changed, 139 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5829d80310f..55bc44157e1 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,18 @@
2004-01-30 Jan Hubicka <jh@suse.cz>
+ * alloc-pool.c: Include hashtab.h
+ (alloc_pool_descriptor): New structure
+ (alloc_pool_hash): New global variable.
+ (hash_descriptor, eq_descriptor, alloc_pool_descriptor): New.
+ (create_alloc_pool): Update statistics.
+ (free_alloc_pool): Likewise.
+ (pool_alloc): Likewise.
+ (output_info): New structure
+ (print_statistics, dump_alloc_pool_statistics): New function.
+ * alloc-pool.h (alloc_pool_def): Turn name to be constant.
+ (dump_alloc_pool_statistics): Declare.
+ * toplev.c (finalize): Dump statistics.
+
* reload.c (secondary_memlocs_elim_used): New static variable.
(get_secondary_mem): Update it.
(find_reloads): Use it.
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 946b4f75b18..8058c52f26b 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1678,7 +1678,7 @@ unroll.o : unroll.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) insn-co
function.h $(INTEGRATE_H) $(REGS_H) $(RECOG_H) flags.h $(EXPR_H) $(LOOP_H) toplev.h \
hard-reg-set.h varray.h $(BASIC_BLOCK_H) $(TM_P_H) $(PREDICT_H) $(PARAMS_H) \
cfgloop.h
-alloc-pool.o : alloc-pool.c $(CONFIG_H) $(SYSTEM_H) alloc-pool.h
+alloc-pool.o : alloc-pool.c $(CONFIG_H) $(SYSTEM_H) alloc-pool.h $(HASHTAB_H)
flow.o : flow.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
flags.h insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h \
$(RECOG_H) function.h except.h $(EXPR_H) $(GGC_H) $(TM_P_H)
diff --git a/gcc/alloc-pool.c b/gcc/alloc-pool.c
index bdcd42fd139..6a2fa65f4ea 100644
--- a/gcc/alloc-pool.c
+++ b/gcc/alloc-pool.c
@@ -23,6 +23,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
#include "alloc-pool.h"
+#include "hashtab.h"
/* Redefine abort to report an internal error w/o coredump, and
reporting the location of the error in the source file. This logic
@@ -72,6 +73,56 @@ typedef struct allocation_object_def
static ALLOC_POOL_ID_TYPE last_id;
#endif
+#ifdef GATHER_STATISTICS
+
+/* Store infromation about each particular alloc_pool. */
+struct alloc_pool_descriptor
+{
+ const char *name;
+ int allocated;
+ int created;
+ int peak;
+ int current;
+};
+
+/* Hashtable mapping alloc_pool names to descriptors. */
+static htab_t alloc_pool_hash;
+
+/* Hashtable helpers. */
+static hashval_t
+hash_descriptor (const void *p)
+{
+ const struct alloc_pool_descriptor *d = p;
+ return htab_hash_pointer (d->name);
+}
+static int
+eq_descriptor (const void *p1, const void *p2)
+{
+ const struct alloc_pool_descriptor *d = p1;
+ return d->name == p2;
+}
+
+/* For given name, return descriptor, create new if needed. */
+static struct alloc_pool_descriptor *
+alloc_pool_descriptor (const char *name)
+{
+ struct alloc_pool_descriptor **slot;
+
+ if (!alloc_pool_hash)
+ alloc_pool_hash = htab_create (10, hash_descriptor, eq_descriptor, NULL);
+
+ slot = (struct alloc_pool_descriptor **)
+ htab_find_slot_with_hash (alloc_pool_hash, name,
+ htab_hash_pointer (name),
+ 1);
+ if (*slot)
+ return *slot;
+ *slot = xcalloc (sizeof (**slot), 1);
+ (*slot)->name = name;
+ return *slot;
+}
+#endif
+
/* Create a pool of things of size SIZE, with NUM in each block we
allocate. */
@@ -80,6 +131,9 @@ create_alloc_pool (const char *name, size_t size, size_t num)
{
alloc_pool pool;
size_t pool_size, header_size;
+#ifdef GATHER_STATISTICS
+ struct alloc_pool_descriptor *desc;
+#endif
if (!name)
abort ();
@@ -107,7 +161,11 @@ create_alloc_pool (const char *name, size_t size, size_t num)
pool = xmalloc (pool_size);
/* Now init the various pieces of our pool structure. */
- pool->name = xstrdup (name);
+ pool->name = /*xstrdup (name)*/name;
+#ifdef GATHER_STATISTICS
+ desc = alloc_pool_descriptor (name);
+ desc->created++;
+#endif
pool->elt_size = size;
pool->elts_per_block = num;
@@ -139,6 +197,9 @@ void
free_alloc_pool (alloc_pool pool)
{
alloc_pool_list block, next_block;
+#ifdef GATHER_STATISTICS
+ struct alloc_pool_descriptor *desc = alloc_pool_descriptor (pool->name);
+#endif
#ifdef ENABLE_CHECKING
if (!pool)
@@ -150,12 +211,14 @@ free_alloc_pool (alloc_pool pool)
{
next_block = block->next;
free (block);
+#ifdef GATHER_STATISTICS
+ desc->current -= pool->block_size;
+#endif
}
- /* Lastly, free the pool and the name. */
- free (pool->name);
#ifdef ENABLE_CHECKING
memset (pool, 0xaf, sizeof (*pool));
#endif
+ /* Lastly, free the pool. */
free (pool);
}
@@ -165,6 +228,11 @@ pool_alloc (alloc_pool pool)
{
alloc_pool_list header;
char *block;
+#ifdef GATHER_STATISTICS
+ struct alloc_pool_descriptor *desc = alloc_pool_descriptor (pool->name);
+
+ desc->allocated+=pool->elt_size;
+#endif
#ifdef ENABLE_CHECKING
if (!pool)
@@ -181,6 +249,11 @@ pool_alloc (alloc_pool pool)
block = xmalloc (pool->block_size);
block_header = (alloc_pool_list) block;
block += align_eight (sizeof (struct alloc_pool_list_def));
+#ifdef GATHER_STATISTICS
+ desc->current += pool->block_size;
+ if (desc->peak < desc->current)
+ desc->peak = desc->current;
+#endif
/* Throw it on the block list. */
block_header->next = pool->block_list;
@@ -246,3 +319,49 @@ pool_free (alloc_pool pool, void *ptr)
pool->free_list = header;
pool->elts_free++;
}
+/* Output per-alloc_pool statistics. */
+#ifdef GATHER_STATISTICS
+
+/* Used to accumulate statistics about alloc_pool sizes. */
+struct output_info
+{
+ int count;
+ int size;
+};
+
+/* Called via htab_traverse. Output alloc_pool descriptor pointed out by SLOT
+ and update statistics. */
+static int
+print_statistics (void **slot, void *b)
+{
+ struct alloc_pool_descriptor *d = (struct alloc_pool_descriptor *) *slot;
+ struct output_info *i = (struct output_info *) b;
+
+ if (d->allocated)
+ {
+ fprintf (stderr, "%-21s %6d %10d %10d %10d\n", d->name,
+ d->created, d->allocated, d->peak, d->current);
+ i->size += d->allocated;
+ i->count += d->created;
+ }
+ return 1;
+}
+#endif
+
+/* Output per-alloc_pool memory usage statistics. */
+void dump_alloc_pool_statistics (void)
+{
+#ifdef GATHER_STATISTICS
+ struct output_info info;
+
+ fprintf (stderr, "\nAlloc-pool Kind Pools Allocated Peak Leak\n");
+ fprintf (stderr, "-------------------------------------------------------------\n");
+ info.count = 0;
+ info.size = 0;
+ htab_traverse (alloc_pool_hash, print_statistics, &info);
+ fprintf (stderr, "-------------------------------------------------------------\n");
+ fprintf (stderr, "%-20s %7d %10d\n",
+ "Total", info.count, info.size);
+ fprintf (stderr, "-------------------------------------------------------------\n");
+#endif
+}
diff --git a/gcc/alloc-pool.h b/gcc/alloc-pool.h
index 48d017217a9..6364fbcf1ae 100644
--- a/gcc/alloc-pool.h
+++ b/gcc/alloc-pool.h
@@ -32,7 +32,7 @@ typedef struct alloc_pool_list_def
typedef struct alloc_pool_def
{
- char *name;
+ const char *name;
#ifdef ENABLE_CHECKING
ALLOC_POOL_ID_TYPE id;
#endif
@@ -51,4 +51,5 @@ extern alloc_pool create_alloc_pool (const char *, size_t, size_t);
extern void free_alloc_pool (alloc_pool);
extern void *pool_alloc (alloc_pool);
extern void pool_free (alloc_pool, void *);
+extern void dump_alloc_pool_statistics (void);
#endif
diff --git a/gcc/toplev.c b/gcc/toplev.c
index 5154b449cc6..d1e12fa068f 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -4599,6 +4599,7 @@ finalize (void)
dump_tree_statistics ();
dump_rtx_statistics ();
dump_varray_statistics ();
+ dump_alloc_pool_statistics ();
}
/* Free up memory for the benefit of leak detectors. */