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]

Trim down cselib memory usage


Hi,
as pointed out in other mail, cselib is responsible for 40% GGC memory
consumption while compiling conbine.c.
The datastructures are bnetter to go into allocpool that is whole a lot more
effecient for such kind of data.  Still it would be worthwhile to look on why
there are so many containers needed at first place.

This seems to be responsible for 2% speedup of GCC component test.
and it also shows the real need for statistics on varpool :)

OK for mainline/branch?
Honza

2004-01-20  Jan Hubicka  <jh@suse.cz>
	* cselib.c: Include alloc-pool.h
	(empty_vals, empty_elt_lists, empty_elt_loc_lists): Kill.
	(elt_loc_list_pool, elt_list_pool, cselib_val_pool): Declare.
	(new_elt_list, new_elt_loc_list, unchain_one_elt_list,
	unchain_one_elt_loc_list_pool, unchain_one_value,
	new_cselib_val): Simplify using allocpool.
	(cselib_init): Initialize allocpools.
	(cselib_finish): Finish allocpools.
Index: cselib.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cselib.c,v
retrieving revision 1.32
diff -c -3 -p -r1.32 cselib.c
*** cselib.c	12 Jan 2004 11:15:33 -0000	1.32
--- cselib.c	20 Jan 2004 17:26:10 -0000
*************** Software Foundation, 59 Temple Place - S
*** 40,45 ****
--- 40,46 ----
  #include "hashtab.h"
  #include "cselib.h"
  #include "params.h"
+ #include "alloc-pool.h"
  
  static int entry_and_rtx_equal_p (const void *, const void *);
  static hashval_t get_value_hash (const void *);
*************** static GTY((deletable (""))) varray_type
*** 117,127 ****
     memory for a non-const call instruction.  */
  static GTY(()) rtx callmem;
  
- /* Caches for unused structures.  */
- static GTY((deletable (""))) cselib_val *empty_vals;
- static GTY((deletable (""))) struct elt_list *empty_elt_lists;
- static GTY((deletable (""))) struct elt_loc_list *empty_elt_loc_lists;
- 
  /* Set by discard_useless_locs if it deleted the last location of any
     value.  */
  static int values_became_useless;
--- 118,123 ----
*************** static cselib_val dummy_val;
*** 134,153 ****
     May or may not contain the useless values - the list is compacted
     each time memory is invalidated.  */
  static cselib_val *first_containing_mem = &dummy_val;
  
  
  /* Allocate a struct elt_list and fill in its two elements with the
     arguments.  */
  
! static struct elt_list *
  new_elt_list (struct elt_list *next, cselib_val *elt)
  {
!   struct elt_list *el = empty_elt_lists;
! 
!   if (el)
!     empty_elt_lists = el->next;
!   else
!     el = ggc_alloc (sizeof (struct elt_list));
    el->next = next;
    el->elt = elt;
    return el;
--- 130,146 ----
     May or may not contain the useless values - the list is compacted
     each time memory is invalidated.  */
  static cselib_val *first_containing_mem = &dummy_val;
+ static alloc_pool elt_loc_list_pool, elt_list_pool, cselib_val_pool;
  
  
  /* Allocate a struct elt_list and fill in its two elements with the
     arguments.  */
  
! static inline struct elt_list *
  new_elt_list (struct elt_list *next, cselib_val *elt)
  {
!   struct elt_list *el;
!   el = pool_alloc (elt_list_pool);
    el->next = next;
    el->elt = elt;
    return el;
*************** new_elt_list (struct elt_list *next, cse
*** 156,170 ****
  /* Allocate a struct elt_loc_list and fill in its two elements with the
     arguments.  */
  
! static struct elt_loc_list *
  new_elt_loc_list (struct elt_loc_list *next, rtx loc)
  {
!   struct elt_loc_list *el = empty_elt_loc_lists;
! 
!   if (el)
!     empty_elt_loc_lists = el->next;
!   else
!     el = ggc_alloc (sizeof (struct elt_loc_list));
    el->next = next;
    el->loc = loc;
    el->canon_loc = NULL;
--- 149,159 ----
  /* Allocate a struct elt_loc_list and fill in its two elements with the
     arguments.  */
  
! static inline struct elt_loc_list *
  new_elt_loc_list (struct elt_loc_list *next, rtx loc)
  {
!   struct elt_loc_list *el;
!   el = pool_alloc (elt_loc_list_pool);
    el->next = next;
    el->loc = loc;
    el->canon_loc = NULL;
*************** new_elt_loc_list (struct elt_loc_list *n
*** 176,189 ****
  /* The elt_list at *PL is no longer needed.  Unchain it and free its
     storage.  */
  
! static void
  unchain_one_elt_list (struct elt_list **pl)
  {
    struct elt_list *l = *pl;
  
    *pl = l->next;
!   l->next = empty_elt_lists;
!   empty_elt_lists = l;
  }
  
  /* Likewise for elt_loc_lists.  */
--- 165,177 ----
  /* The elt_list at *PL is no longer needed.  Unchain it and free its
     storage.  */
  
! static inline void
  unchain_one_elt_list (struct elt_list **pl)
  {
    struct elt_list *l = *pl;
  
    *pl = l->next;
!   pool_free (elt_list_pool, l);
  }
  
  /* Likewise for elt_loc_lists.  */
*************** unchain_one_elt_loc_list (struct elt_loc
*** 194,201 ****
    struct elt_loc_list *l = *pl;
  
    *pl = l->next;
!   l->next = empty_elt_loc_lists;
!   empty_elt_loc_lists = l;
  }
  
  /* Likewise for cselib_vals.  This also frees the addr_list associated with
--- 182,188 ----
    struct elt_loc_list *l = *pl;
  
    *pl = l->next;
!   pool_free (elt_loc_list_pool, l);
  }
  
  /* Likewise for cselib_vals.  This also frees the addr_list associated with
*************** unchain_one_value (cselib_val *v)
*** 207,214 ****
    while (v->addr_list)
      unchain_one_elt_list (&v->addr_list);
  
!   v->u.next_free = empty_vals;
!   empty_vals = v;
  }
  
  /* Remove all entries from the hash table.  Also used during
--- 194,200 ----
    while (v->addr_list)
      unchain_one_elt_list (&v->addr_list);
  
!   pool_free (cselib_val_pool, v);
  }
  
  /* Remove all entries from the hash table.  Also used during
*************** hash_rtx (rtx x, enum machine_mode mode,
*** 697,714 ****
  /* Create a new value structure for VALUE and initialize it.  The mode of the
     value is MODE.  */
  
! static cselib_val *
  new_cselib_val (unsigned int value, enum machine_mode mode)
  {
!   cselib_val *e = empty_vals;
! 
!   if (e)
!     empty_vals = e->u.next_free;
!   else
!     e = ggc_alloc (sizeof (cselib_val));
  
    if (value == 0)
      abort ();
  
    e->value = value;
    e->u.val_rtx = gen_rtx_VALUE (mode);
--- 683,697 ----
  /* Create a new value structure for VALUE and initialize it.  The mode of the
     value is MODE.  */
  
! static inline cselib_val *
  new_cselib_val (unsigned int value, enum machine_mode mode)
  {
!   cselib_val *e = pool_alloc (cselib_val_pool);
  
+ #ifdef ENABLE_CHECKING
    if (value == 0)
      abort ();
+ #endif
  
    e->value = value;
    e->u.val_rtx = gen_rtx_VALUE (mode);
*************** cselib_update_varray_sizes (void)
*** 1403,1408 ****
--- 1386,1397 ----
  void
  cselib_init (void)
  {
+   elt_list_pool = create_alloc_pool ("elt_list", 
+ 				     sizeof (struct elt_list), 10);
+   elt_loc_list_pool = create_alloc_pool ("elt_loc_list", 
+ 				         sizeof (struct elt_loc_list), 10);
+   cselib_val_pool = create_alloc_pool ("cselib_val_list", 
+ 				       sizeof (cselib_val), 10);
    /* This is only created once.  */
    if (! callmem)
      callmem = gen_rtx_MEM (BLKmode, const0_rtx);
*************** cselib_init (void)
*** 1428,1433 ****
--- 1417,1425 ----
  void
  cselib_finish (void)
  {
+   free_alloc_pool (elt_list_pool);
+   free_alloc_pool (elt_loc_list_pool);
+   free_alloc_pool (cselib_val_pool);
    clear_table ();
    reg_values_old = reg_values;
    reg_values = 0;


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