This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Bitmap statistics ver 2


Hi,
this is the updated bitmap patch, this time it bootstraps fine with
--enable-gather-detailed-mem-stats.  I've dropped the code conting
number of walks in the datastructure too.

:ADDPATCH middle-end:
Bootstrapped/regtested i686-linux, OK?

2006-07-31  Jan Hubicka  <jh@suse.cz>
	* statistics.h (ALONE_PASS_MEM_STAT, ALONE_MEM_STAT_INFO,
	ALONE_MEM_STAT_DECL): New macros.
	* bitmap.h: Include statistics.h
	(struct bitmap_head_def): Add variant with pointer to bitmap descriptor.
	(bitmap_initialize_stat): Rename from bitmap_initialize; add statistics.
	(bitmap_obstack_alloc_stat, bitmap_gc_alloc_stat): Declare.
	* bitmap.c: Include hashtab.h
	(bitmap_descriptor): New.
	(bitmap_hash): New static variable
	(hash_descriptor, eq_descriptor, bitmap_descriptor, register_overhead):
	New static functions.
	(bitmap_register): New.
	(bitmap_element_free, bitmap_element_allocate, bitmap_elt_clear_from,
	bitmap_obstack_release): Do accounting.
	(bitmap_obstack_alloc_stat): Rename from bitmap_obstack_alloc ; do
	accounting.
	(bitmap_gc_alloc_stat): Likewise.
	(bitmap_obstack_free, bitmap_find_bit): Do statictics.
	(print_statistics, dump_bitmap_statistics): New functions.
	* toplev.c (finalize): Dump bitmap statistics.
Index: bitmap.c
===================================================================
*** bitmap.c	(revision 119546)
--- bitmap.c	(working copy)
*************** Software Foundation, 51 Franklin Street,
*** 28,33 ****
--- 28,121 ----
  #include "obstack.h"
  #include "ggc.h"
  #include "bitmap.h"
+ #include "hashtab.h"
+ 
+ #ifdef GATHER_STATISTICS
+ 
+ /* Store information about each particular bitmap.  */
+ struct bitmap_descriptor
+ {
+   const char *function;
+   const char *file;
+   int line;
+   int allocated;
+   int created;
+   int peak;
+   int current;
+   int nsearches;
+ };
+ 
+ /* Hashtable mapping bitmap names to descriptors.  */
+ static htab_t bitmap_desc_hash;
+ 
+ /* Hashtable helpers.  */
+ static hashval_t
+ hash_descriptor (const void *p)
+ {
+   const struct bitmap_descriptor *d = p;
+   return htab_hash_pointer (d->file) + d->line;
+ }
+ struct loc
+ {
+   const char *file;
+   const char *function;
+   int line;
+ };
+ static int
+ eq_descriptor (const void *p1, const void *p2)
+ {
+   const struct bitmap_descriptor *d = p1;
+   const struct loc *l = p2;
+   return d->file == l->file && d->function == l->function && d->line == l->line;
+ }
+ 
+ /* For given file and line, return descriptor, create new if needed.  */
+ static struct bitmap_descriptor *
+ bitmap_descriptor (const char *file, const char *function, int line)
+ {
+   struct bitmap_descriptor **slot;
+   struct loc loc;
+ 
+   loc.file = file;
+   loc.function = function;
+   loc.line = line;
+ 
+   if (!bitmap_desc_hash)
+     bitmap_desc_hash = htab_create (10, hash_descriptor, eq_descriptor, NULL);
+ 
+   slot = (struct bitmap_descriptor **)
+     htab_find_slot_with_hash (bitmap_desc_hash, &loc,
+ 			      htab_hash_pointer (file) + line,
+ 			      1);
+   if (*slot)
+     return *slot;
+   *slot = xcalloc (sizeof (**slot), 1);
+   (*slot)->file = file;
+   (*slot)->function = function;
+   (*slot)->line = line;
+   return *slot;
+ }
+ 
+ /* Register new bitmap.  */
+ void
+ bitmap_register (bitmap b MEM_STAT_DECL)
+ {
+   b->desc = bitmap_descriptor (_loc_name, _loc_function, _loc_line);
+   b->desc->created++;
+ }
+ 
+ /* Account the overhead.  */
+ static void
+ register_overhead (bitmap b, int amount)
+ {
+   b->desc->current += amount;
+   if (amount > 0)
+     b->desc->allocated += amount;
+   gcc_assert (b->desc->current >= 0);
+   if (b->desc->peak < b->desc->current)
+     b->desc->peak = b->desc->current;
+ }
+ #endif
  
  /* Global data */
  bitmap_element bitmap_zero_bits;  /* An element of all zero bits.  */
*************** bitmap_element_free (bitmap head, bitmap
*** 92,97 ****
--- 180,188 ----
        else
  	head->indx = 0;
      }
+ #ifdef GATHER_STATISTICS
+   register_overhead (head, -((int)sizeof (bitmap_element)));
+ #endif
    bitmap_elem_to_freelist (head, elt);
  }
  
*************** bitmap_element_allocate (bitmap head)
*** 139,144 ****
--- 230,238 ----
  	element = GGC_NEW (bitmap_element);
      }
  
+ #ifdef GATHER_STATISTICS
+   register_overhead (head, sizeof (bitmap_element));
+ #endif
    memset (element->bits, 0, sizeof (element->bits));
  
    return element;
*************** bitmap_elt_clear_from (bitmap head, bitm
*** 151,158 ****
--- 245,261 ----
  {
    bitmap_element *prev;
    bitmap_obstack *bit_obstack = head->obstack;
+ #ifdef GATHER_STATISTICS
+   int n;
+ #endif
  
    if (!elt) return;
+ #ifdef GATHER_STATISTICS
+   n = 0;
+   for (prev = elt; prev; prev = prev->next)
+     n++;
+   register_overhead (head, -sizeof (bitmap_element) * n);
+ #endif
  
    prev = elt->prev;
    if (prev)
*************** bitmap_obstack_release (bitmap_obstack *
*** 232,238 ****
     it on the default bitmap obstack.  */
  
  bitmap
! bitmap_obstack_alloc (bitmap_obstack *bit_obstack)
  {
    bitmap map;
  
--- 335,341 ----
     it on the default bitmap obstack.  */
  
  bitmap
! bitmap_obstack_alloc_stat (bitmap_obstack *bit_obstack MEM_STAT_DECL)
  {
    bitmap map;
  
*************** bitmap_obstack_alloc (bitmap_obstack *bi
*** 243,249 ****
      bit_obstack->heads = (void *)map->first;
    else
      map = XOBNEW (&bit_obstack->obstack, bitmap_head);
!   bitmap_initialize (map, bit_obstack);
  
    return map;
  }
--- 346,355 ----
      bit_obstack->heads = (void *)map->first;
    else
      map = XOBNEW (&bit_obstack->obstack, bitmap_head);
!   bitmap_initialize_stat (map, bit_obstack PASS_MEM_STAT);
! #ifdef GATHER_STATISTICS
!   register_overhead (map, sizeof (bitmap_head));
! #endif
  
    return map;
  }
*************** bitmap_obstack_alloc (bitmap_obstack *bi
*** 251,262 ****
  /* Create a new GCd bitmap.  */
  
  bitmap
! bitmap_gc_alloc (void)
  {
    bitmap map;
  
    map = GGC_NEW (struct bitmap_head_def);
!   bitmap_initialize (map, NULL);
  
    return map;
  }
--- 357,371 ----
  /* Create a new GCd bitmap.  */
  
  bitmap
! bitmap_gc_alloc_stat (ALONE_MEM_STAT_DECL)
  {
    bitmap map;
  
    map = GGC_NEW (struct bitmap_head_def);
!   bitmap_initialize_stat (map, NULL PASS_MEM_STAT);
! #ifdef GATHER_STATISTICS
!   register_overhead (map, sizeof (bitmap_head));
! #endif
  
    return map;
  }
*************** bitmap_obstack_free (bitmap map)
*** 270,275 ****
--- 379,387 ----
      {
        bitmap_clear (map);
        map->first = (void *)map->obstack->heads;
+ #ifdef GATHER_STATISTICS
+       register_overhead (map, -((int)sizeof (bitmap_head)));
+ #endif
        map->obstack->heads = map;
      }
  }
*************** bitmap_find_bit (bitmap head, unsigned i
*** 430,435 ****
--- 542,550 ----
    bitmap_element *element;
    unsigned int indx = bit / BITMAP_ELEMENT_ALL_BITS;
  
+ #ifdef GATHER_STATISTICS
+   head->desc->nsearches++;
+ #endif
    if (head->current == 0
        || head->indx == indx)
      return head->current;
*************** bitmap_print (FILE *file, bitmap head, c
*** 1519,1524 ****
--- 1634,1697 ----
      }
    fputs (suffix, file);
  }
+ #ifdef GATHER_STATISTICS
+ 
+ 
+ /* Used to accumulate statistics about bitmap sizes.  */
+ struct output_info
+ {
+   int count;
+   int size;
+ };
+ 
+ /* Called via htab_traverse.  Output bitmap descriptor pointed out by SLOT
+    and update statistics.  */
+ static int
+ print_statistics (void **slot, void *b)
+ {
+   struct bitmap_descriptor *d = (struct bitmap_descriptor *) *slot;
+   struct output_info *i = (struct output_info *) b;
+   char s[4096];
+ 
+   if (d->allocated)
+     {
+       const char *s1 = d->file;
+       const char *s2;
+       while ((s2 = strstr (s1, "gcc/")))
+ 	s1 = s2 + 4;
+       sprintf (s, "%s:%i (%s)", s1, d->line, d->function);
+       s[41] = 0;
+       fprintf (stderr, "%-41s %6d %10d %10d %10d %10d\n", s,
+ 	       d->created, d->allocated, d->peak, d->current, d->nsearches);
+       i->size += d->allocated;
+       i->count += d->created;
+     }
+   return 1;
+ }
+ #endif
+ /* Output per-bitmap memory usage statistics.  */
+ void
+ dump_bitmap_statistics (void)
+ {
+ #ifdef GATHER_STATISTICS
+   struct output_info info;
+ 
+   if (!bitmap_desc_hash)
+     return;
+ 
+   fprintf (stderr, "\nBitmap                                     Overall "
+ 		   "Allocated     Peak        Leak   searched ");
+ 
+   fprintf (stderr, "---------------------------------------------------------------------------------\n");
+   info.count = 0;
+   info.size = 0;
+   htab_traverse (bitmap_desc_hash, print_statistics, &info);
+   fprintf (stderr, "---------------------------------------------------------------------------------\n");
+   fprintf (stderr, "%-40s %7d %10d\n",
+ 	   "Total", info.count, info.size);
+   fprintf (stderr, "---------------------------------------------------------------------------------\n");
+ #endif
+ }
  
  /* Compute hash of bitmap (for purposes of hashing).  */
  hashval_t
Index: bitmap.h
===================================================================
*** bitmap.h	(revision 119546)
--- bitmap.h	(working copy)
*************** Software Foundation, 51 Franklin Street,
*** 22,27 ****
--- 22,28 ----
  #ifndef GCC_BITMAP_H
  #define GCC_BITMAP_H
  #include "hashtab.h"
+ #include "statistics.h"
  
  /* Fundamental storage type for bitmap.  */
  
*************** typedef struct bitmap_element_def GTY(()
*** 68,74 ****
    BITMAP_WORD bits[BITMAP_ELEMENT_WORDS]; /* Bits that are set.  */
  } bitmap_element;
  
! /* Head of bitmap linked list.  */
  typedef struct bitmap_head_def GTY(()) {
    bitmap_element *first;	/* First element in linked list.  */
    bitmap_element *current;	/* Last element looked at.  */
--- 69,81 ----
    BITMAP_WORD bits[BITMAP_ELEMENT_WORDS]; /* Bits that are set.  */
  } bitmap_element;
  
! struct bitmap_descriptor;
! /* Head of bitmap linked list.  
!    The gengtype doesn't cope with ifdefs inside the definition,
!    but for statistics we need bitmap descriptor pointer in.
!    Trick it by two copies of the definition.  This is safe
!    because the bitmap descriptor is not grabagecollected.  */
! #ifndef GATHER_STATISTICS
  typedef struct bitmap_head_def GTY(()) {
    bitmap_element *first;	/* First element in linked list.  */
    bitmap_element *current;	/* Last element looked at.  */
*************** typedef struct bitmap_head_def GTY(()) {
*** 76,82 ****
    bitmap_obstack *obstack;	/* Obstack to allocate elements from.
  				   If NULL, then use ggc_alloc.  */
  } bitmap_head;
! 
  
  /* Global data */
  extern bitmap_element bitmap_zero_bits;	/* Zero bitmap element */
--- 83,98 ----
    bitmap_obstack *obstack;	/* Obstack to allocate elements from.
  				   If NULL, then use ggc_alloc.  */
  } bitmap_head;
! #else
! typedef struct bitmap_head_def {
!   bitmap_element *first;	/* First element in linked list.  */
!   bitmap_element *current;	/* Last element looked at.  */
!   unsigned int indx;		/* Index of last element looked at.  */
!   bitmap_obstack *obstack;	/* Obstack to allocate elements from.
! 				   If NULL, then use ggc_alloc.  */
!   struct bitmap_descriptor *desc;
! } bitmap_head;
! #endif
  
  /* Global data */
  extern bitmap_element bitmap_zero_bits;	/* Zero bitmap element */
*************** extern void bitmap_print (FILE *, bitmap
*** 144,163 ****
  /* Initialize and release a bitmap obstack.  */
  extern void bitmap_obstack_initialize (bitmap_obstack *);
  extern void bitmap_obstack_release (bitmap_obstack *);
  
  /* Initialize a bitmap header.  OBSTACK indicates the bitmap obstack
     to allocate from, NULL for GC'd bitmap.  */
  
  static inline void
! bitmap_initialize (bitmap head, bitmap_obstack *obstack)
  {
    head->first = head->current = NULL;
    head->obstack = obstack;
  }
  
  /* Allocate and free bitmaps from obstack, malloc and gc'd memory.  */
! extern bitmap bitmap_obstack_alloc (bitmap_obstack *obstack);
! extern bitmap bitmap_gc_alloc (void);
  extern void bitmap_obstack_free (bitmap);
  
  /* A few compatibility/functions macros for compatibility with sbitmaps */
--- 160,187 ----
  /* Initialize and release a bitmap obstack.  */
  extern void bitmap_obstack_initialize (bitmap_obstack *);
  extern void bitmap_obstack_release (bitmap_obstack *);
+ extern void bitmap_register (bitmap MEM_STAT_DECL);
+ extern void dump_bitmap_statistics (void);
  
  /* Initialize a bitmap header.  OBSTACK indicates the bitmap obstack
     to allocate from, NULL for GC'd bitmap.  */
  
  static inline void
! bitmap_initialize_stat (bitmap head, bitmap_obstack *obstack MEM_STAT_DECL)
  {
    head->first = head->current = NULL;
    head->obstack = obstack;
+ #ifdef GATHER_STATISTICS
+   bitmap_register (head PASS_MEM_STAT);
+ #endif
  }
+ #define bitmap_initialize(h,o) bitmap_initialize_stat (h,o MEM_STAT_INFO)
  
  /* Allocate and free bitmaps from obstack, malloc and gc'd memory.  */
! extern bitmap bitmap_obstack_alloc_stat (bitmap_obstack *obstack MEM_STAT_DECL);
! #define bitmap_obstack_alloc(t) bitmap_obstack_alloc_stat (t MEM_STAT_INFO)
! extern bitmap bitmap_gc_alloc_stat (ALONE_MEM_STAT_DECL);
! #define bitmap_gc_alloc() bitmap_gc_alloc_stat (ALONE_MEM_STAT_INFO)
  extern void bitmap_obstack_free (bitmap);
  
  /* A few compatibility/functions macros for compatibility with sbitmaps */
Index: toplev.c
===================================================================
*** toplev.c	(revision 119546)
--- toplev.c	(working copy)
*************** finalize (void)
*** 1971,1976 ****
--- 1971,1977 ----
        dump_rtx_statistics ();
        dump_varray_statistics ();
        dump_alloc_pool_statistics ();
+       dump_bitmap_statistics ();
        dump_ggc_loc_statistics ();
      }
  
Index: statistics.h
===================================================================
*** statistics.h	(revision 119546)
--- statistics.h	(working copy)
***************
*** 24,34 ****
--- 24,40 ----
  #define GCC_STATISTICS
  #ifdef GATHER_STATISTICS
  #define MEM_STAT_DECL , const char * ARG_UNUSED (_loc_name), int ARG_UNUSED (_loc_line), const char * ARG_UNUSED (_loc_function)
+ #define ALONE_MEM_STAT_DECL const char * ARG_UNUSED (_loc_name), int ARG_UNUSED (_loc_line), const char * ARG_UNUSED (_loc_function)
  #define PASS_MEM_STAT , _loc_name, _loc_line,  _loc_function
+ #define ALONE_PASS_MEM_STAT _loc_name, _loc_line,  _loc_function
  #define MEM_STAT_INFO , __FILE__, __LINE__, __FUNCTION__
+ #define ALONE_MEM_STAT_INFO __FILE__, __LINE__, __FUNCTION__
  #else
  #define MEM_STAT_DECL
+ #define ALONE_MEM_STAT_DECL void
  #define PASS_MEM_STAT
+ #define ALONE_PASS_MEM_STAT
  #define MEM_STAT_INFO
+ #define ALONE_MEM_STAT_INFO
  #endif
  #endif


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]