Hi, while looking into -ftime-report, I noticed that ggc can take up to 10% of WPA memory while it does almost nothing: it is run just after streaming that explicitly frees memory that becomes unreachable. The first GGC run usually saves at most 1% of memory and then it is never run again. I believe this ought to also help in case we get into swap, since ltranses will also ggc less.
Bootstrapped/regtested x86_64-linux, OK? Honza * lto.c (read_cgraph_and_symbols): Grow ggc memory after streaming. * ggc.h (ggc_grow): New function. * ggc-none.c (ggc_grow): New function. * ggc-page.c (ggc_grow): Likewise. Index: ggc.h =================================================================== --- ggc.h (revision 209170) +++ ggc.h (working copy) @@ -225,6 +225,9 @@ extern const char *ggc_alloc_string_stat function is called, not during allocations. */ extern void ggc_collect (void); +/* Assume that all GGC memory is reachable and grow the limits for next collection. */ +extern void ggc_grow (void); + /* Register an additional root table. This can be useful for some plugins. Does nothing if the passed pointer is NULL. */ extern void ggc_register_root_tab (const struct ggc_root_tab *); Index: lto/lto.c =================================================================== --- lto/lto.c (revision 209170) +++ lto/lto.c (working copy) @@ -2999,6 +3000,10 @@ read_cgraph_and_symbols (unsigned nfiles gimple_canonical_types = NULL; delete canonical_type_hash_cache; canonical_type_hash_cache = NULL; + + /* At this stage we know that majority of GGC memory is reachable. + Growing the limits prevents unnecesary invocation of GGC. */ + ggc_grow (); ggc_collect (); /* Set the hooks so that all of the ipa passes can read in their data. */ Index: ggc-none.c =================================================================== --- ggc-none.c (revision 209170) +++ ggc-none.c (working copy) @@ -63,3 +63,8 @@ ggc_free (void *p) { free (p); } + +void +ggc_grow (void) +{ +} Index: ggc-page.c =================================================================== --- ggc-page.c (revision 209170) +++ ggc-page.c (working copy) @@ -2095,6 +2095,19 @@ ggc_collect (void) fprintf (G.debug_file, "END COLLECTING\n"); } +/* Assume that all GGC memory is reachable and grow the limits for next collection. */ + +void +ggc_grow (void) +{ +#ifndef ENABLE_CHECKING + G.allocated_last_gc = MAX (G.allocated_last_gc, + G.allocated); +#endif + if (!quiet_flag) + fprintf (stderr, " {GC start %luk} ", (unsigned long) G.allocated / 1024); +} + /* Print allocation statistics. */ #define SCALE(x) ((unsigned long) ((x) < 1024*10 \ ? (x) \