Allocpool statistics

Jan Hubicka jh@suse.cz
Wed Jan 21 23:17:00 GMT 2004


Hi,
this patch adds statistics for allocpools.  It is mostly cut&past from
varrays except that it removes code to strdup xstrdup used to save copy
of allocpool name.
THis confuse my hashtable and I think it can safely go as we always pass
the static strings anyway.

Honza

	* alloc-poo.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.
Index: alloc-pool.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/alloc-pool.c,v
retrieving revision 1.9
diff -c -3 -p -r1.9 alloc-pool.c
*** alloc-pool.c	21 Dec 2003 14:08:32 -0000	1.9
--- alloc-pool.c	21 Jan 2004 22:42:39 -0000
*************** Software Foundation, 59 Temple Place - S
*** 23,28 ****
--- 23,29 ----
  #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
*************** typedef struct allocation_object_def
*** 73,78 ****
--- 74,129 ----
  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.  */
  
*************** create_alloc_pool (const char *name, siz
*** 81,86 ****
--- 132,140 ----
  {
    alloc_pool pool;
    size_t pool_size, header_size;
+ #ifdef GATHER_STATISTICS
+   struct alloc_pool_descriptor *desc;
+ #endif
  
    if (!name)
      abort ();
*************** create_alloc_pool (const char *name, siz
*** 108,114 ****
    pool = xmalloc (pool_size);
  
    /* Now init the various pieces of our pool structure.  */
!   pool->name = xstrdup (name);
    pool->elt_size = size;
    pool->elts_per_block = num;
  
--- 162,172 ----
    pool = xmalloc (pool_size);
  
    /* Now init the various pieces of our pool structure.  */
!   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;
  
*************** void
*** 140,145 ****
--- 198,206 ----
  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)
*************** free_alloc_pool (alloc_pool pool)
*** 151,159 ****
      {
        next_block = block->next;
        free (block);
      }
!   /* Lastly, free the pool and the name.  */
!   free (pool->name);
    free (pool);
  }
  
--- 212,222 ----
      {
        next_block = block->next;
        free (block);
+ #ifdef GATHER_STATISTICS
+       desc->current -= pool->block_size;
+ #endif
      }
!   /* Lastly, free the pool.  */
    free (pool);
  }
  
*************** pool_alloc (alloc_pool pool)
*** 163,168 ****
--- 226,236 ----
  {
    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)
*************** pool_alloc (alloc_pool pool)
*** 179,184 ****
--- 247,257 ----
        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;
*************** pool_free (alloc_pool pool, void *ptr)
*** 241,244 ****
--- 315,364 ----
    header->next = pool->free_list;
    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
  }
Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Makefile.in,v
retrieving revision 1.1229
diff -c -3 -p -r1.1229 Makefile.in
*** Makefile.in	20 Jan 2004 20:36:18 -0000	1.1229
--- Makefile.in	21 Jan 2004 22:42:53 -0000
*************** unroll.o : unroll.c $(CONFIG_H) $(SYSTEM
*** 1677,1683 ****
     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
  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)
--- 1677,1683 ----
     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 $(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)
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/toplev.c,v
retrieving revision 1.865
diff -c -3 -p -r1.865 toplev.c
*** toplev.c	17 Jan 2004 12:28:57 -0000	1.865
--- toplev.c	21 Jan 2004 22:48:42 -0000
*************** finalize (void)
*** 4583,4588 ****
--- 4585,4591 ----
        stringpool_statistics ();
        dump_tree_statistics ();
        dump_rtx_statistics ();
+       dump_alloc_pool_statistics ();
      }
  
    /* Free up memory for the benefit of leak detectors.  */
Index: alloc-pool.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/alloc-pool.h,v
retrieving revision 1.3
diff -c -3 -p -r1.3 alloc-pool.h
*** alloc-pool.h	15 Jun 2003 13:43:30 -0000	1.3
--- alloc-pool.h	21 Jan 2004 22:48:42 -0000
*************** typedef struct alloc_pool_list_def
*** 32,38 ****
  
  typedef struct alloc_pool_def
  {
!   char *name;
  #ifdef ENABLE_CHECKING
    ALLOC_POOL_ID_TYPE id;
  #endif
--- 32,38 ----
  
  typedef struct alloc_pool_def
  {
!   const char *name;
  #ifdef ENABLE_CHECKING
    ALLOC_POOL_ID_TYPE id;
  #endif
*************** extern alloc_pool create_alloc_pool (con
*** 51,54 ****
--- 51,55 ----
  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



More information about the Gcc-patches mailing list