From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 46172 invoked by alias); 27 Jul 2018 12:05:14 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 46157 invoked by uid 89); 27 Jul 2018 12:05:14 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,SPF_PASS autolearn=ham version=3.3.2 spammy=004 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; Fri, 27 Jul 2018 12:05:12 +0000 Received: from relay1.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 5AE6DACC8; Fri, 27 Jul 2018 12:05:10 +0000 (UTC) Subject: Re: [PATCH] Add malloc predictor (PR middle-end/83023). To: gcc-patches@gcc.gnu.org, Marc Glisse Cc: Jan Hubicka , Nathan Sidwell References: From: =?UTF-8?Q?Martin_Li=c5=a1ka?= Message-ID: Date: Fri, 27 Jul 2018 12:05:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.9.1 MIME-Version: 1.0 In-Reply-To: Content-Type: multipart/mixed; boundary="------------3D34E53DBBBAE5D15C58170E" X-IsSubscribed: yes X-SW-Source: 2018-07/txt/msg01715.txt.bz2 This is a multi-part message in MIME format. --------------3D34E53DBBBAE5D15C58170E Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Content-length: 2010 On 07/26/2018 05:00 PM, Marc Glisse wrote: > On Thu, 26 Jul 2018, Martin Liška wrote: > >> Following patch implements new predictors that annotates malloc-like functions. >> These almost every time return a non-null value. > > Out of curiosity (the __builtin_expect there doesn't hurt and we don't need to remove it), does it make __builtin_expect unnecessary in the implementation of operator new (libstdc++-v3/libsupc++/new_op.cc)? It looks like > >   while (__builtin_expect ((p = malloc (sz)) == 0, false)) >     { >       new_handler handler = std::get_new_handler (); >       if (! handler) >         _GLIBCXX_THROW_OR_ABORT(bad_alloc()); >       handler (); >     } > > where being in a loop may trigger opposite heuristics. > Thanks Marc for the pointer, it actually showed one problem with newly added predictor. So first, current trunk does: Predictions for bb 5 first match heuristics: 10.00% combined heuristics: 10.00% __builtin_expect heuristics of edge 5->6: 10.00% call heuristics of edge 5->6 (ignored): 33.00% loop exit heuristics of edge 5->9 (ignored): 5.50% removal of the __builtin_expect wrongly selected a different first march predictor: Predictions for bb 5 first match heuristics: 94.50% combined heuristics: 94.50% pointer (on trees) heuristics of edge 5->6 (ignored): 30.00% malloc returned non-NULL heuristics of edge 5->6 (ignored): 0.04% call heuristics of edge 5->6 (ignored): 33.00% loop exit heuristics of edge 5->9: 5.50% I fixed that by moving PRED_MALLOC_NONNULL up in the list, now it's fine: 1 edges in bb 4 predicted to even probabilities Predictions for bb 5 first match heuristics: 0.04% combined heuristics: 0.04% pointer (on trees) heuristics of edge 5->6 (ignored): 30.00% malloc returned non-NULL heuristics of edge 5->6: 0.04% call heuristics of edge 5->6 (ignored): 33.00% loop exit heuristics of edge 5->9 (ignored): 5.50% So answer is yes, the builtin can be then removed. Martin --------------3D34E53DBBBAE5D15C58170E Content-Type: text/x-patch; name="0001-Add-malloc-predictor-PR-middle-end-83023.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="0001-Add-malloc-predictor-PR-middle-end-83023.patch" Content-length: 3098 >From ba2aa6cb7367f529ad96ece92e25cd0366a28735 Mon Sep 17 00:00:00 2001 From: marxin Date: Thu, 26 Jul 2018 15:25:00 +0200 Subject: [PATCH] Add malloc predictor (PR middle-end/83023). gcc/ChangeLog: 2018-07-26 Martin Liska PR middle-end/83023 * predict.c (expr_expected_value_1): Handle DECL_IS_MALLOC declarations. * predict.def (PRED_MALLOC_NONNULL): New predictor. gcc/testsuite/ChangeLog: 2018-07-26 Martin Liska PR middle-end/83023 * gcc.dg/predict-16.c: New test. --- gcc/predict.c | 8 ++++++++ gcc/predict.def | 5 ++++- gcc/testsuite/gcc.dg/predict-16.c | 31 +++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/predict-16.c diff --git a/gcc/predict.c b/gcc/predict.c index a6769eda1c7..a7b2223c697 100644 --- a/gcc/predict.c +++ b/gcc/predict.c @@ -2380,6 +2380,14 @@ expr_expected_value_1 (tree type, tree op0, enum tree_code code, } return NULL; } + + if (DECL_IS_MALLOC (decl)) + { + if (predictor) + *predictor = PRED_MALLOC_NONNULL; + return boolean_true_node; + } + if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL) switch (DECL_FUNCTION_CODE (decl)) { diff --git a/gcc/predict.def b/gcc/predict.def index 4ed97ed165c..426c17f26fd 100644 --- a/gcc/predict.def +++ b/gcc/predict.def @@ -88,6 +88,10 @@ DEF_PREDICTOR (PRED_NORETURN, "noreturn call", PROB_VERY_LIKELY, DEF_PREDICTOR (PRED_COLD_FUNCTION, "cold function call", PROB_VERY_LIKELY, PRED_FLAG_FIRST_MATCH) +/* Return value of malloc function is almost always non-null. */ +DEF_PREDICTOR (PRED_MALLOC_NONNULL, "malloc returned non-NULL", \ + PROB_VERY_LIKELY, PRED_FLAG_FIRST_MATCH) + /* Edge causing loop to terminate is probably not taken. */ DEF_PREDICTOR (PRED_LOOP_EXIT, "loop exit", HITRATE (89), PRED_FLAG_FIRST_MATCH) @@ -169,7 +173,6 @@ DEF_PREDICTOR (PRED_HOT_LABEL, "hot label", HITRATE (85), 0) DEF_PREDICTOR (PRED_COLD_LABEL, "cold label", PROB_VERY_LIKELY, PRED_FLAG_FIRST_MATCH) - /* The following predictors are used in Fortran. */ /* Branch leading to an integer overflow are extremely unlikely. */ diff --git a/gcc/testsuite/gcc.dg/predict-16.c b/gcc/testsuite/gcc.dg/predict-16.c new file mode 100644 index 00000000000..3a3e943bb79 --- /dev/null +++ b/gcc/testsuite/gcc.dg/predict-16.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-profile_estimate" } */ + +#include +#include + +void *r; +void *r2; +void *r3; +void *r4; + +void *m (size_t s, int c) +{ + r = malloc (s); + if (r) + memset (r, 0, s); + + r2 = calloc (s, 0); + if (r2) + memset (r2, 0, s); + + r3 = __builtin_malloc (s); + if (r3) + memset (r3, 0, s); + + r4 = __builtin_calloc (s, 0); + if (r4) + memset (r4, 0, s); +} + +/* { dg-final { scan-tree-dump-times "malloc returned non-NULL heuristics of edge\[^:\]*: 99.96%" 4 "profile_estimate"} } */ -- 2.18.0 --------------3D34E53DBBBAE5D15C58170E--