From patchwork Mon Nov 18 12:24:27 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Martin_Li=C5=A1ka?= X-Patchwork-Id: 1196739 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-513900-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=suse.cz Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="easRuFoi"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47Gp703lRKz9sPj for ; Mon, 18 Nov 2019 23:24:42 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :subject:to:cc:message-id:date:mime-version:content-type; q=dns; s=default; b=xB4MKtplKUFtJaLx0wEYJd5Zm2WWvJ0cROR4b6gC5qmUQXW5R7 RfNI4hm0YkViXaCT1bo+HUOqFKMn+Kuv72MIwu3+KGZa1ivKEy/jAr9Ot08Ld/10 NlLXTz41OhhsDgcCH3HlOUdqMMW5RvZRBVnfN7Lr+n7Kyd/xxc/erqyHk= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :subject:to:cc:message-id:date:mime-version:content-type; s= default; bh=xCGND97n3eGH6de0PkifkF0k4vM=; b=easRuFoi8PvfYOuyJL7k W9R06UxVaHZ8dYnFE+IXTn9k7nm+hpTRp90KviSIW7i7cs/rK/er4zV0lI43rOoJ KZIP2LrKIejLqRu1zqG3HTQ7l3ePmGqMW06bDJKLw6AipeT6EHnC3NSzha5N78xe lFzKgrfodRMylahHGBHgP2o= Received: (qmail 74725 invoked by alias); 18 Nov 2019 12:24:34 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 74697 invoked by uid 89); 18 Nov 2019 12:24:34 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-18.5 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, SPF_PASS autolearn=ham version=3.3.1 spammy=holder, sk:global_, 7156, notices X-HELO: mx1.suse.de Received: from mx2.suse.de (HELO mx1.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 18 Nov 2019 12:24:30 +0000 Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 977C7AD49; Mon, 18 Nov 2019 12:24:28 +0000 (UTC) From: =?utf-8?q?Martin_Li=C5=A1ka?= Subject: [PATCH] Restore init_ggc_heuristics. To: gcc-patches@gcc.gnu.org Cc: Jan Hubicka Message-ID: <3c91e664-8624-aa73-1ebc-9fcaef1feb00@suse.cz> Date: Mon, 18 Nov 2019 13:24:27 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.2.1 MIME-Version: 1.0 X-IsSubscribed: yes 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 * 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 ();