> Hello. > > After my param to option transformation, we lost automatic GGC > detection. It's because init_ggc_heuristics is called before > init_options_struct which memsets all the values to zero first. > > I've tested the patch with --enable-checking=release and I hope > Honza can test it more?
You should be able to measure the difference building tramp3d on enable-checking=release compiler. I will include the patch in my next round of Firefox benchmark (probably tonight) unless you beat me. Honza > > Patch can bootstrap on x86_64-linux-gnu and survives regression tests. > > Ready to be installed? > Thanks, > Martin > > gcc/ChangeLog: > > 2019-11-18 Martin Liska <mli...@suse.cz> > > * ggc-common.c (ggc_rlimit_bound): Move to opts.c > (ggc_min_expand_heuristic): Likewise. > (ggc_min_heapsize_heuristic): Likewise. > (init_ggc_heuristics): Likewise. > * ggc.h (init_ggc_heuristics): Remove declaration. > * opts.c (ggc_rlimit_bound): Moved here from ggc-common.c. > (ggc_min_expand_heuristic): Likewise. > (ggc_min_heapsize_heuristic): Likewise. > (init_ggc_heuristics): Likewise. > (init_options_struct): Init GGC params. > * toplev.c (general_init): Remove call to init_ggc_heuristics. > --- > gcc/ggc-common.c | 103 --------------------------------------------- > gcc/ggc.h | 3 -- > gcc/opts.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++ > gcc/toplev.c | 4 -- > 4 files changed, 106 insertions(+), 110 deletions(-) > > > diff --git a/gcc/ggc-common.c b/gcc/ggc-common.c > index f6e393d7bb6..86aab015b91 100644 > --- a/gcc/ggc-common.c > +++ b/gcc/ggc-common.c > @@ -715,109 +715,6 @@ mmap_gt_pch_use_address (void *base, size_t size, int > fd, size_t offset) > } > #endif /* HAVE_MMAP_FILE */ > > -#if !defined ENABLE_GC_CHECKING && !defined ENABLE_GC_ALWAYS_COLLECT > - > -/* Modify the bound based on rlimits. */ > -static double > -ggc_rlimit_bound (double limit) > -{ > -#if defined(HAVE_GETRLIMIT) > - struct rlimit rlim; > -# if defined (RLIMIT_AS) > - /* RLIMIT_AS is what POSIX says is the limit on mmap. Presumably > - any OS which has RLIMIT_AS also has a working mmap that GCC will use. > */ > - if (getrlimit (RLIMIT_AS, &rlim) == 0 > - && rlim.rlim_cur != (rlim_t) RLIM_INFINITY > - && rlim.rlim_cur < limit) > - limit = rlim.rlim_cur; > -# elif defined (RLIMIT_DATA) > - /* ... but some older OSs bound mmap based on RLIMIT_DATA, or we > - might be on an OS that has a broken mmap. (Others don't bound > - mmap at all, apparently.) */ > - if (getrlimit (RLIMIT_DATA, &rlim) == 0 > - && rlim.rlim_cur != (rlim_t) RLIM_INFINITY > - && rlim.rlim_cur < limit > - /* Darwin has this horribly bogus default setting of > - RLIMIT_DATA, to 6144Kb. No-one notices because RLIMIT_DATA > - appears to be ignored. Ignore such silliness. If a limit > - this small was actually effective for mmap, GCC wouldn't even > - start up. */ > - && rlim.rlim_cur >= 8 * 1024 * 1024) > - limit = rlim.rlim_cur; > -# endif /* RLIMIT_AS or RLIMIT_DATA */ > -#endif /* HAVE_GETRLIMIT */ > - > - return limit; > -} > - > -/* Heuristic to set a default for GGC_MIN_EXPAND. */ > -static int > -ggc_min_expand_heuristic (void) > -{ > - double min_expand = physmem_total (); > - > - /* Adjust for rlimits. */ > - min_expand = ggc_rlimit_bound (min_expand); > - > - /* The heuristic is a percentage equal to 30% + 70%*(RAM/1GB), yielding > - a lower bound of 30% and an upper bound of 100% (when RAM >= 1GB). */ > - min_expand /= 1024*1024*1024; > - min_expand *= 70; > - min_expand = MIN (min_expand, 70); > - min_expand += 30; > - > - return min_expand; > -} > - > -/* Heuristic to set a default for GGC_MIN_HEAPSIZE. */ > -static int > -ggc_min_heapsize_heuristic (void) > -{ > - double phys_kbytes = physmem_total (); > - double limit_kbytes = ggc_rlimit_bound (phys_kbytes * 2); > - > - phys_kbytes /= 1024; /* Convert to Kbytes. */ > - limit_kbytes /= 1024; > - > - /* The heuristic is RAM/8, with a lower bound of 4M and an upper > - bound of 128M (when RAM >= 1GB). */ > - phys_kbytes /= 8; > - > -#if defined(HAVE_GETRLIMIT) && defined (RLIMIT_RSS) > - /* Try not to overrun the RSS limit while doing garbage collection. > - The RSS limit is only advisory, so no margin is subtracted. */ > - { > - struct rlimit rlim; > - if (getrlimit (RLIMIT_RSS, &rlim) == 0 > - && rlim.rlim_cur != (rlim_t) RLIM_INFINITY) > - phys_kbytes = MIN (phys_kbytes, rlim.rlim_cur / 1024); > - } > -# endif > - > - /* Don't blindly run over our data limit; do GC at least when the > - *next* GC would be within 20Mb of the limit or within a quarter of > - the limit, whichever is larger. If GCC does hit the data limit, > - compilation will fail, so this tries to be conservative. */ > - limit_kbytes = MAX (0, limit_kbytes - MAX (limit_kbytes / 4, 20 * 1024)); > - limit_kbytes = (limit_kbytes * 100) / (110 + ggc_min_expand_heuristic ()); > - phys_kbytes = MIN (phys_kbytes, limit_kbytes); > - > - phys_kbytes = MAX (phys_kbytes, 4 * 1024); > - phys_kbytes = MIN (phys_kbytes, 128 * 1024); > - > - return phys_kbytes; > -} > -#endif > - > -void > -init_ggc_heuristics (void) > -{ > -#if !defined ENABLE_GC_CHECKING && !defined ENABLE_GC_ALWAYS_COLLECT > - param_ggc_min_expand = ggc_min_expand_heuristic (); > - param_ggc_min_heapsize = ggc_min_heapsize_heuristic (); > -#endif > -} > - > /* GGC memory usage. */ > class ggc_usage: public mem_usage > { > diff --git a/gcc/ggc.h b/gcc/ggc.h > index 6c64caaafb2..04431439c5e 100644 > --- a/gcc/ggc.h > +++ b/gcc/ggc.h > @@ -285,9 +285,6 @@ extern void ggc_print_statistics (void); > > extern void stringpool_statistics (void); > > -/* Heuristics. */ > -extern void init_ggc_heuristics (void); > - > /* Report current heap memory use to stderr. */ > extern void report_heap_memory_use (void); > > diff --git a/gcc/opts.c b/gcc/opts.c > index addebf15365..7e363e5c1d6 100644 > --- a/gcc/opts.c > +++ b/gcc/opts.c > @@ -275,6 +275,110 @@ init_opts_obstack (void) > gcc_obstack_init (&opts_obstack); > } > > +#if !defined ENABLE_GC_CHECKING && !defined ENABLE_GC_ALWAYS_COLLECT > + > +/* Modify the bound based on rlimits. */ > + > +static double > +ggc_rlimit_bound (double limit) > +{ > +#if defined(HAVE_GETRLIMIT) > + struct rlimit rlim; > +#if defined(RLIMIT_AS) > + /* RLIMIT_AS is what POSIX says is the limit on mmap. Presumably > + any OS which has RLIMIT_AS also has a working mmap that GCC will use. > */ > + if (getrlimit (RLIMIT_AS, &rlim) == 0 > + && rlim.rlim_cur != (rlim_t) RLIM_INFINITY && rlim.rlim_cur < limit) > + limit = rlim.rlim_cur; > +#elif defined(RLIMIT_DATA) > + /* ... but some older OSs bound mmap based on RLIMIT_DATA, or we > + might be on an OS that has a broken mmap. (Others don't bound > + mmap at all, apparently.) */ > + if (getrlimit (RLIMIT_DATA, &rlim) == 0 > + && rlim.rlim_cur != (rlim_t) RLIM_INFINITY > + && rlim.rlim_cur < limit > + /* Darwin has this horribly bogus default setting of > + RLIMIT_DATA, to 6144Kb. No-one notices because RLIMIT_DATA > + appears to be ignored. Ignore such silliness. If a limit > + this small was actually effective for mmap, GCC wouldn't even > + start up. */ > + && rlim.rlim_cur >= 8 * 1024 * 1024) > + limit = rlim.rlim_cur; > +#endif /* RLIMIT_AS or RLIMIT_DATA */ > +#endif /* HAVE_GETRLIMIT */ > + > + return limit; > +} > + > +/* Heuristic to set a default for GGC_MIN_EXPAND. */ > + > +static int > +ggc_min_expand_heuristic (void) > +{ > + double min_expand = physmem_total (); > + > + /* Adjust for rlimits. */ > + min_expand = ggc_rlimit_bound (min_expand); > + > + /* The heuristic is a percentage equal to 30% + 70%*(RAM/1GB), yielding > + a lower bound of 30% and an upper bound of 100% (when RAM >= 1GB). */ > + min_expand /= 1024 * 1024 * 1024; > + min_expand *= 70; > + min_expand = MIN (min_expand, 70); > + min_expand += 30; > + > + return min_expand; > +} > + > +/* Heuristic to set a default for GGC_MIN_HEAPSIZE. */ > +static int > +ggc_min_heapsize_heuristic (void) > +{ > + double phys_kbytes = physmem_total (); > + double limit_kbytes = ggc_rlimit_bound (phys_kbytes * 2); > + > + phys_kbytes /= 1024; /* Convert to Kbytes. */ > + limit_kbytes /= 1024; > + > + /* The heuristic is RAM/8, with a lower bound of 4M and an upper > + bound of 128M (when RAM >= 1GB). */ > + phys_kbytes /= 8; > + > +#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_RSS) > + /* Try not to overrun the RSS limit while doing garbage collection. > + The RSS limit is only advisory, so no margin is subtracted. */ > + { > + struct rlimit rlim; > + if (getrlimit (RLIMIT_RSS, &rlim) == 0 > + && rlim.rlim_cur != (rlim_t) RLIM_INFINITY) > + phys_kbytes = MIN (phys_kbytes, rlim.rlim_cur / 1024); > + } > +#endif > + > + /* Don't blindly run over our data limit; do GC at least when the > + *next* GC would be within 20Mb of the limit or within a quarter of > + the limit, whichever is larger. If GCC does hit the data limit, > + compilation will fail, so this tries to be conservative. */ > + limit_kbytes = MAX (0, limit_kbytes - MAX (limit_kbytes / 4, 20 * 1024)); > + limit_kbytes = (limit_kbytes * 100) / (110 + ggc_min_expand_heuristic ()); > + phys_kbytes = MIN (phys_kbytes, limit_kbytes); > + > + phys_kbytes = MAX (phys_kbytes, 4 * 1024); > + phys_kbytes = MIN (phys_kbytes, 128 * 1024); > + > + return phys_kbytes; > +} > +#endif > + > +static void > +init_ggc_heuristics (void) > +{ > +#if !defined ENABLE_GC_CHECKING && !defined ENABLE_GC_ALWAYS_COLLECT > + param_ggc_min_expand = ggc_min_expand_heuristic (); > + param_ggc_min_heapsize = ggc_min_heapsize_heuristic (); > +#endif > +} > + > /* Initialize OPTS and OPTS_SET before using them in parsing options. */ > > void > @@ -289,6 +393,8 @@ init_options_struct (struct gcc_options *opts, struct > gcc_options *opts_set) > if (opts_set) > memset (opts_set, 0, sizeof (*opts_set)); > > + init_ggc_heuristics (); > + > /* Initialize whether `char' is signed. */ > opts->x_flag_signed_char = DEFAULT_SIGNED_CHAR; > /* Set this to a special "uninitialized" value. The actual default > diff --git a/gcc/toplev.c b/gcc/toplev.c > index d4583bac66c..fa6d39355d0 100644 > --- a/gcc/toplev.c > +++ b/gcc/toplev.c > @@ -1240,10 +1240,6 @@ general_init (const char *argv0, bool init_signals) > /* Initialize register usage now so switches may override. */ > init_reg_sets (); > > - /* This must be done after global_init_params but before argument > - processing. */ > - init_ggc_heuristics (); > - > /* Create the singleton holder for global state. This creates the > dump manager. */ > g = new gcc::context (); >