[PATCH] Restore init_ggc_heuristics.
Jan Hubicka
hubicka@ucw.cz
Mon Nov 18 13:09:00 GMT 2019
> 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 <mliska@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 ();
>
More information about the Gcc-patches
mailing list