On 07/31/2018 11:25 AM, Jan Hubicka wrote:
>> Hi.
>>
>> Following patch implements new predictors that annotates malloc-like 
>> functions.
>> These almost every time return a non-null value.
>>
>> Patch can bootstrap on ppc64le-redhat-linux and survives regression tests.
>>
>> Ready to be installed?
>> Martin
>>
>> gcc/ChangeLog:
>>
>> 2018-07-26  Martin Liska  <mli...@suse.cz>
>>
>>         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  <mli...@suse.cz>
>>
>>         PR middle-end/83023
>>      * gcc.dg/predict-16.c: New test.
> 
> These are two conceptually different things - wether you return new memory
> and whether the return value is commonly non-null. While it goes together
> for majority of malloc function I wonder if this is safe WRT the auto-detected
> malloc attributes.  I do not know how common is code that returns new memory
> only under some conditions?  

You are right that malloc attribute does not guarantee that non-null is returned
in most cases. But I would say in most cases it's the case.

I'm sending updated version of the patch where I added BUILT_IN_REALLOC, which
doesn't have malloc attribute, but return non-null in most cases.

May I install that?
Martin

> 
> Honza
> 

>From 8ead58710e5676032183627bffc139382b34c609 Mon Sep 17 00:00:00 2001
From: marxin <mli...@suse.cz>
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  <mli...@suse.cz>

        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  <mli...@suse.cz>

        PR middle-end/83023
	* gcc.dg/predict-16.c: New test.
---
 gcc/predict.c                     | 12 +++++++++++
 gcc/predict.def                   |  5 ++++-
 gcc/testsuite/gcc.dg/predict-16.c | 36 +++++++++++++++++++++++++++++++
 3 files changed, 52 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..69909d2dee1 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))
 	      {
@@ -2414,6 +2422,10 @@ expr_expected_value_1 (tree type, tree op0, enum tree_code code,
 		if (predictor)
 		  *predictor = PRED_COMPARE_AND_SWAP;
 		return boolean_true_node;
+	      case BUILT_IN_REALLOC:
+		if (predictor)
+		  *predictor = PRED_MALLOC_NONNULL;
+		return boolean_true_node;
 	      default:
 		break;
 	    }
diff --git a/gcc/predict.def b/gcc/predict.def
index 4ed97ed165c..76e6590cc96 100644
--- a/gcc/predict.def
+++ b/gcc/predict.def
@@ -51,6 +51,10 @@ DEF_PREDICTOR (PRED_NO_PREDICTION, "no prediction", PROB_ALWAYS, 0)
 DEF_PREDICTOR (PRED_UNCONDITIONAL, "unconditional jump", PROB_ALWAYS,
 	       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)
+
 /* Use number of loop iterations determined by # of iterations
    analysis to set probability.  We don't want to use Dempster-Shaffer
    theory here, as the predictions is exact.  */
@@ -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..b71ad6c706d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/predict-16.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-profile_estimate" } */
+
+#include <stdlib.h>
+#include <string.h>
+
+void *r;
+void *r2;
+void *r3;
+void *r4;
+void *r5;
+
+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);
+
+  r5 = __builtin_realloc (r4, s);
+  if (r5)
+    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

Reply via email to