This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Trim down cselib memory usage
>
> > in fact I am thinking about going even further. The cselib produces a
> > lot of VALUE RTX nodes. All these nodes are local to CSE pass and as
> > such, is there something preventing this nodes from being allocated by
> > varpool too?
>
> My only concern with this is that it will make it very difficult to
> later add a GC call inside a pass that uses cselib. You couldn't even
> use ggc_push_context, because the marker routines won't run.
>
> So this sort of depends on the future direction of GCC. Is it likely
> that we'll want to do this? The current passes that use cselib are
> loop, reload, sched, and jump threading. Reload doesn't make much
> garbage, and nor does sched; loop only uses it for a pretty small
> chunk of code; we hope jump threading will go away, and it doesn't
> make much garbage anyway. So it seems like it would probably be OK to
> declare that you can't ever ggc_collect inside cselib.
Hi,
I've tested (i586-pc-gnu-linux) the attached patch (after combinining with my
previous cselib varpoolizing patch). It make GGC memory consumption to go from
26MB to, 24MB at the expesnse of 100Kb allocpool. About 8% saving overall.
OK?
* cselib.c (value_pool): New.
(new_cselib_val): Use pool.
(cselib_init): Initialize value_pool
(cselib_finish): Free pool.
*** cselib.c2 Thu Jan 22 02:22:55 2004
--- cselib.c Thu Jan 22 02:36:50 2004
*************** static cselib_val dummy_val;
*** 130,136 ****
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
--- 130,136 ----
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, value_pool;
/* Allocate a struct elt_list and fill in its two elements with the
*************** new_cselib_val (unsigned int value, enum
*** 694,700 ****
#endif
e->value = value;
! e->u.val_rtx = gen_rtx_VALUE (mode);
CSELIB_VAL_PTR (e->u.val_rtx) = e;
e->addr_list = 0;
e->locs = 0;
--- 694,705 ----
#endif
e->value = value;
! /* We use custom method to allocate this RTL construct because it accounts
! about 8% of overall memory usage. */
! e->u.val_rtx = pool_alloc (value_pool);
! memset (e->u.val_rtx, 0, RTX_HDR_SIZE);
! PUT_CODE (e->u.val_rtx, VALUE);
! PUT_MODE (e->u.val_rtx, mode);
CSELIB_VAL_PTR (e->u.val_rtx) = e;
e->addr_list = 0;
e->locs = 0;
*************** cselib_init (void)
*** 1376,1381 ****
--- 1381,1388 ----
sizeof (struct elt_loc_list), 100);
cselib_val_pool = create_alloc_pool ("cselib_val_list",
sizeof (cselib_val), 100);
+ value_pool = create_alloc_pool ("value",
+ RTX_SIZE (VALUE), 100);
/* This is only created once. */
if (! callmem)
callmem = gen_rtx_MEM (BLKmode, const0_rtx);
*************** cselib_finish (void)
*** 1408,1413 ****
--- 1415,1421 ----
free_alloc_pool (elt_list_pool);
free_alloc_pool (elt_loc_list_pool);
free_alloc_pool (cselib_val_pool);
+ free_alloc_pool (value_pool);
clear_table ();
reg_values = 0;
hash_table = 0;