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]

Statistics for varray GGC memory consumption


Hi,
I am somewhat concerned about use of varrays in GGC memory that produce
relatively large amount of garbage (a lot of that without good reason as
we can use malloc scheme instead, just we don't), thus I've implemented
statistics routines.  Quick checking found that for Geralds testcase
does about 13MB of varrays, while tree-SSA does 63MB.  The average
overhead per varray is over 10KB so operands are not to blame here IMO.

I am attaching two versions, one for mainline, other for tree-SSA.

Honza

2004-01-19  Jan Hubicka  <jh@suse.cz>
	* ggc-none.c (ggc_get_size): Implement.
	* toplev.c (finalize): Dump varray.
	* varray.c (varray_ggc_memory_allocated, varrays_created): New static arrays.
	(element): Add printable name.
	(dump_varray_statistics): Dump varrays
	* varray.h (dump_varray_statistics): Declare.
Index: ggc-none.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ggc-none.c,v
retrieving revision 1.15
diff -c -3 -p -r1.15 ggc-none.c
*** ggc-none.c	27 Oct 2003 00:26:52 -0000	1.15
--- ggc-none.c	19 Jan 2004 00:39:08 -0000
*************** ggc_realloc (void *x, size_t size)
*** 60,62 ****
--- 60,70 ----
  {
    return xrealloc (x, size);
  }
+ 
+ size_t
+ ggc_get_size (const void *block ATTRIBUTE_UNUSED)
+ {
+   /* We don't have this information available, but it is used only for gathering
+      statictics in varray.c that is never used with ggc_none.  */
+   return -1;
+ }
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	19 Jan 2004 00:39:08 -0000
*************** finalize (void)
*** 4583,4588 ****
--- 4583,4589 ----
        stringpool_statistics ();
        dump_tree_statistics ();
        dump_rtx_statistics ();
+       dump_varray_statistics ();
      }
  
    /* Free up memory for the benefit of leak detectors.  */
Index: varray.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/varray.c,v
retrieving revision 1.24
diff -c -3 -p -r1.24 varray.c
*** varray.c	16 Jan 2004 07:28:11 -0000	1.24
--- varray.c	19 Jan 2004 00:39:08 -0000
***************
*** 29,34 ****
--- 29,38 ----
  #include "ggc.h"
  
  #define VARRAY_HDR_SIZE (sizeof (struct varray_head_tag) - sizeof (varray_data))
+ #ifdef GATHER_STATISTICS
+ static int varray_ggc_memory_allocated[NUM_VARRAY_DATA];
+ static int varrays_created[NUM_VARRAY_DATA];
+ #endif
  
  /* Do not add any more non-GC items here.  Please either remove or GC
     those items that are not GCed.  */
***************
*** 36,62 ****
  static const struct {
    unsigned char size;
    bool uses_ggc;
  } element[NUM_VARRAY_DATA] = {
!   { sizeof (char), 1 },
!   { sizeof (unsigned char), 1 },
!   { sizeof (short), 1 },
!   { sizeof (unsigned short), 1 },
!   { sizeof (int), 1 },
!   { sizeof (unsigned int), 1 },
!   { sizeof (long), 1 },
!   { sizeof (unsigned long), 1 },
!   { sizeof (HOST_WIDE_INT), 1 },
!   { sizeof (unsigned HOST_WIDE_INT), 1 },
!   { sizeof (void *), 1 },
!   { sizeof (char *), 1 },
!   { sizeof (struct rtx_def *), 1 },
!   { sizeof (struct rtvec_def *), 1 },
!   { sizeof (union tree_node *), 1 },
!   { sizeof (struct bitmap_head_def *), 1 },
!   { sizeof (struct reg_info_def *), 0 },
!   { sizeof (struct const_equiv_data), 0 },
!   { sizeof (struct basic_block_def *), 0 },
!   { sizeof (struct elt_list *), 1 },
  };
  
  /* Allocate a virtual array with NUM_ELEMENT elements, each of which is
--- 40,67 ----
  static const struct {
    unsigned char size;
    bool uses_ggc;
+   const char *name;
  } element[NUM_VARRAY_DATA] = {
!   { sizeof (char), 1, "char" },
!   { sizeof (unsigned char), 1, "unsigned char" },
!   { sizeof (short), 1, "short" },
!   { sizeof (unsigned short), 1, "unsigned short" },
!   { sizeof (int), 1, "int" },
!   { sizeof (unsigned int), 1, "unsigned" },
!   { sizeof (long), 1, "long" },
!   { sizeof (unsigned long), 1, "unsigned long" },
!   { sizeof (HOST_WIDE_INT), 1, "HOST_WIDE_INT" },
!   { sizeof (unsigned HOST_WIDE_INT), 1, "unsigned HOST_WIDE_INT" },
!   { sizeof (void *), 1, "void *" },
!   { sizeof (char *), 1, "char *" },
!   { sizeof (struct rtx_def *), 1, "rtx" },
!   { sizeof (struct rtvec_def *), 1, "rtvec" },
!   { sizeof (union tree_node *), 1, "tree" },
!   { sizeof (struct bitmap_head_def *), 1, "bitmap_head" },
!   { sizeof (struct reg_info_def *), 0, "reg_info" },
!   { sizeof (struct const_equiv_data), 0, "const_equiv_data" },
!   { sizeof (struct basic_block_def *), 0, "basic_block" },
!   { sizeof (struct elt_list *), 1, "elt_list" },
  };
  
  /* Allocate a virtual array with NUM_ELEMENT elements, each of which is
*************** varray_init (size_t num_elements, enum v
*** 68,77 ****
    size_t data_size = num_elements * element[element_kind].size;
    varray_type ptr;
    if (element[element_kind].uses_ggc)
!     ptr = ggc_alloc_cleared (VARRAY_HDR_SIZE + data_size);
    else
      ptr = xcalloc (VARRAY_HDR_SIZE + data_size, 1);
- 
    ptr->num_elements = num_elements;
    ptr->elements_used = 0;
    ptr->type = element_kind;
--- 73,87 ----
    size_t data_size = num_elements * element[element_kind].size;
    varray_type ptr;
    if (element[element_kind].uses_ggc)
!     {
!       ptr = ggc_alloc_cleared (VARRAY_HDR_SIZE + data_size);
! #ifdef GATHER_STATISTICS
!       varray_ggc_memory_allocated[element_kind] += ggc_get_size (ptr);
!       varrays_created[element_kind] ++;
! #endif
!     }
    else
      ptr = xcalloc (VARRAY_HDR_SIZE + data_size, 1);
    ptr->num_elements = num_elements;
    ptr->elements_used = 0;
    ptr->type = element_kind;
*************** varray_grow (varray_type va, size_t n)
*** 93,99 ****
        size_t data_size = n * elem_size;
  
        if (element[va->type].uses_ggc)
! 	va = ggc_realloc (va, VARRAY_HDR_SIZE + data_size);
        else
  	va = xrealloc (va, VARRAY_HDR_SIZE + data_size);
        va->num_elements = n;
--- 103,119 ----
        size_t data_size = n * elem_size;
  
        if (element[va->type].uses_ggc)
! 	{
! #ifdef GATHER_STATISTICS
! 	  varray_type oldva = va;
! #endif
! 	  va = ggc_realloc (va, VARRAY_HDR_SIZE + data_size);
! #ifdef GATHER_STATISTICS
! 	  if (va != oldva)
! 	    varray_ggc_memory_allocated[va->type]
! 	      += ggc_get_size (va);
! #endif
! 	}
        else
  	va = xrealloc (va, VARRAY_HDR_SIZE + data_size);
        va->num_elements = n;
*************** varray_underflow (varray_type va, const 
*** 137,139 ****
--- 157,185 ----
  }
  
  #endif
+ void dump_varray_statistics (void)
+ {
+ #ifdef GATHER_STATISTICS
+   int i;
+   int total = 0;
+   int varrays = 0;
+ 
+   fprintf (stderr, "\nVARRAY Kind            Count      Bytes\n");
+   fprintf (stderr, "---------------------------------------\n");
+   for (i = 0; i < NUM_VARRAY_DATA; i++)
+     {
+       if (varray_ggc_memory_allocated[i])
+ 	{
+ 	  fprintf (stderr, "%-20s %7d %10d\n", element[i].name,
+ 		   varrays_created[i],
+ 		   varray_ggc_memory_allocated[i]);
+ 	  total += varray_ggc_memory_allocated[i];
+ 	  varrays += varrays_created[i];
+ 	}
+     }
+   fprintf (stderr, "---------------------------------------\n");
+   fprintf (stderr, "%-20s %7d %10d\n",
+            "Total", varrays, total);
+   fprintf (stderr, "---------------------------------------\n");
+ #endif
+ }
Index: varray.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/varray.h,v
retrieving revision 1.33
diff -c -3 -p -r1.33 varray.h
*** varray.h	13 Jan 2004 02:43:16 -0000	1.33
--- varray.h	19 Jan 2004 00:39:08 -0000
*************** extern void varray_underflow (varray_typ
*** 326,329 ****
--- 326,330 ----
  #define VARRAY_TOP_CONST_EQUIV(VA)	VARRAY_TOP (VA, const_equiv)
  #define VARRAY_TOP_BB(VA)		VARRAY_TOP (VA, bb)
  
+ extern void dump_varray_statistics (void);
  #endif /* ! GCC_VARRAY_H */



Index: ggc-none.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ggc-none.c,v
retrieving revision 1.12.2.3
diff -c -3 -p -r1.12.2.3 ggc-none.c
*** ggc-none.c	13 Nov 2003 02:37:54 -0000	1.12.2.3
--- ggc-none.c	19 Jan 2004 13:42:41 -0000
*************** ggc_realloc (void *x, size_t size)
*** 60,62 ****
--- 60,70 ----
  {
    return xrealloc (x, size);
  }
+ 
+ size_t
+ ggc_get_size (const void *block ATTRIBUTE_UNUSED)
+ {
+   /* We don't have this information available, but it is used only for gathering
+      statictics in varray.c that is never used with ggc_none.  */
+   return -1;
+ }
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/toplev.c,v
retrieving revision 1.654.2.90
diff -c -3 -p -r1.654.2.90 toplev.c
*** toplev.c	14 Jan 2004 07:16:35 -0000	1.654.2.90
--- toplev.c	19 Jan 2004 13:42:41 -0000
*************** finalize (void)
*** 4590,4595 ****
--- 4590,4596 ----
        stringpool_statistics ();
        dump_tree_statistics ();
        dump_rtx_statistics ();
+       dump_varray_statistics ();
      }
  
    /* Free up memory for the benefit of leak detectors.  */
Index: varray.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/varray.c,v
retrieving revision 1.15.2.8
diff -c -3 -p -r1.15.2.8 varray.c
*** varray.c	25 Oct 2003 17:48:24 -0000	1.15.2.8
--- varray.c	19 Jan 2004 13:42:41 -0000
***************
*** 29,34 ****
--- 29,38 ----
  #include "ggc.h"
  
  #define VARRAY_HDR_SIZE (sizeof (struct varray_head_tag) - sizeof (varray_data))
+ #ifdef GATHER_STATISTICS
+ static int varray_ggc_memory_allocated[NUM_VARRAY_DATA];
+ static int varrays_created[NUM_VARRAY_DATA];
+ #endif
  
  /* Do not add any more non-GC items here.  Please either remove or GC those items that
     are not GCed.  */
***************
*** 36,65 ****
  static const struct {
    unsigned char size;
    bool uses_ggc;
  } element[NUM_VARRAY_DATA] = {
!   { sizeof (char), 1 },
!   { sizeof (unsigned char), 1 },
!   { sizeof (short), 1 },
!   { sizeof (unsigned short), 1 },
!   { sizeof (int), 1 },
!   { sizeof (unsigned int), 1 },
!   { sizeof (long), 1 },
!   { sizeof (unsigned long), 1 },
!   { sizeof (HOST_WIDE_INT), 1 },
!   { sizeof (unsigned HOST_WIDE_INT), 1 },
!   { sizeof (void *), 1 },
!   { sizeof (void *), 0 },
!   { sizeof (char *), 1 },
!   { sizeof (struct rtx_def *), 1 },
!   { sizeof (struct rtvec_def *), 1 },
!   { sizeof (union tree_node *), 1 },
!   { sizeof (struct bitmap_head_def *), 1 },
!   { sizeof (struct reg_info_def *), 0 },
!   { sizeof (struct const_equiv_data), 0 },
!   { sizeof (struct basic_block_def *), 0 },
!   { sizeof (struct elt_list *), 1 },
!   { sizeof (struct edge_def *), 0 },
!   { sizeof (tree *), 1 },
  };
  
  /* Allocate a virtual array with NUM_ELEMENT elements, each of which is
--- 40,70 ----
  static const struct {
    unsigned char size;
    bool uses_ggc;
+   const char *name;
  } element[NUM_VARRAY_DATA] = {
!   { sizeof (char), 1, "char" },
!   { sizeof (unsigned char), 1, "unsigned char" },
!   { sizeof (short), 1, "short" },
!   { sizeof (unsigned short), 1, "unsigned short" },
!   { sizeof (int), 1, "int" },
!   { sizeof (unsigned int), 1, "unsigned" },
!   { sizeof (long), 1, "long" },
!   { sizeof (unsigned long), 1, "unsigned long" },
!   { sizeof (HOST_WIDE_INT), 1, "HOST_WIDE_INT" },
!   { sizeof (unsigned HOST_WIDE_INT), 1, "unsigned HOST_WIDE_INT" },
!   { sizeof (void *), 1, "void *" },
!   { sizeof (void *), 0, "void *" },
!   { sizeof (char *), 1, "char *" },
!   { sizeof (struct rtx_def *), 1, "rtx" },
!   { sizeof (struct rtvec_def *), 1, "rtvec" },
!   { sizeof (union tree_node *), 1, "tree" },
!   { sizeof (struct bitmap_head_def *), 1, "bitmap_heap" },
!   { sizeof (struct reg_info_def *), 0, "reg_info" },
!   { sizeof (struct const_equiv_data), 0, "const_equiv" },
!   { sizeof (struct basic_block_def *), 0, "basic_block" },
!   { sizeof (struct elt_list *), 1, "elt_list" },
!   { sizeof (struct edge_def *), 0, "edge_def" },
!   { sizeof (tree *), 1, "tree *" },
  };
  
  /* Allocate a virtual array with NUM_ELEMENT elements, each of which is
*************** varray_init (size_t num_elements, enum v
*** 71,80 ****
    size_t data_size = num_elements * element[element_kind].size;
    varray_type ptr;
    if (element[element_kind].uses_ggc)
!     ptr = ggc_alloc_cleared (VARRAY_HDR_SIZE + data_size);
    else
      ptr = xcalloc (VARRAY_HDR_SIZE + data_size, 1);
- 
    ptr->num_elements = num_elements;
    ptr->elements_used = 0;
    ptr->type = element_kind;
--- 76,90 ----
    size_t data_size = num_elements * element[element_kind].size;
    varray_type ptr;
    if (element[element_kind].uses_ggc)
!     {
!       ptr = ggc_alloc_cleared (VARRAY_HDR_SIZE + data_size);
! #ifdef GATHER_STATISTICS
!       varray_ggc_memory_allocated[element_kind] += ggc_get_size (ptr);
!       varrays_created[element_kind] ++;
! #endif
!     }
    else
      ptr = xcalloc (VARRAY_HDR_SIZE + data_size, 1);
    ptr->num_elements = num_elements;
    ptr->elements_used = 0;
    ptr->type = element_kind;
*************** varray_grow (varray_type va, size_t n)
*** 96,102 ****
        size_t data_size = n * elem_size;
  
        if (element[va->type].uses_ggc)
! 	va = ggc_realloc (va, VARRAY_HDR_SIZE + data_size);
        else
  	va = xrealloc (va, VARRAY_HDR_SIZE + data_size);
        va->num_elements = n;
--- 106,122 ----
        size_t data_size = n * elem_size;
  
        if (element[va->type].uses_ggc)
! 	{
! #ifdef GATHER_STATISTICS
! 	  varray_type oldva = va;
! #endif
! 	  va = ggc_realloc (va, VARRAY_HDR_SIZE + data_size);
! #ifdef GATHER_STATISTICS
! 	  if (va != oldva)
! 	    varray_ggc_memory_allocated[va->type]
! 	      += ggc_get_size (va);
! #endif
! 	}
        else
  	va = xrealloc (va, VARRAY_HDR_SIZE + data_size);
        va->num_elements = n;
*************** varray_copy (varray_type v1, varray_type
*** 152,155 ****
--- 172,201 ----
    data_size = element[v2->type].size * v2->num_elements;
    memcpy (v1->data.c, v2->data.c, data_size);
    v1->elements_used = v2->elements_used;
+ }
+ void dump_varray_statistics (void)
+ {
+ #ifdef GATHER_STATISTICS
+   int i;
+   int total = 0;
+   int varrays = 0;
+ 
+   fprintf (stderr, "\nVARRAY Kind            Count      Bytes\n");
+   fprintf (stderr, "---------------------------------------\n");
+   for (i = 0; i < NUM_VARRAY_DATA; i++)
+     {
+       if (varray_ggc_memory_allocated[i])
+ 	{
+ 	  fprintf (stderr, "%-20s %7d %10d\n", element[i].name,
+ 		   varrays_created[i],
+ 		   varray_ggc_memory_allocated[i]);
+ 	  total += varray_ggc_memory_allocated[i];
+ 	  varrays += varrays_created[i];
+ 	}
+     }
+   fprintf (stderr, "---------------------------------------\n");
+   fprintf (stderr, "%-20s %7d %10d\n",
+            "Total", varrays, total);
+   fprintf (stderr, "---------------------------------------\n");
+ #endif
  }
Index: varray.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/varray.h,v
retrieving revision 1.28.2.8
diff -c -3 -p -r1.28.2.8 varray.h
*** varray.h	8 Dec 2003 12:58:23 -0000	1.28.2.8
--- varray.h	19 Jan 2004 13:42:41 -0000
*************** extern void varray_check_failed (varray_
*** 347,350 ****
--- 347,351 ----
  #define VARRAY_TOP_EDGE(VA)		VARRAY_TOP (VA, e)
  #define VARRAY_TOP_TREE_PTR(VA)		VARRAY_TOP (VA, tp)
  
+ extern void dump_varray_statistics (void);
  #endif /* ! GCC_VARRAY_H */


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