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?

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 ();

Reply via email to