Add malloc predictor (PR middle-end/83023).
authorMartin Liska <mliska@suse.cz>
Tue, 7 Aug 2018 11:59:13 +0000 (13:59 +0200)
committerMartin Liska <marxin@gcc.gnu.org>
Tue, 7 Aug 2018 11:59:13 +0000 (11:59 +0000)
2018-08-07  Martin Liska  <mliska@suse.cz>

        PR middle-end/83023
* predict.c (expr_expected_value_1): Handle DECL_IS_MALLOC,
        BUILT_IN_REALLOC and DECL_IS_OPERATOR_NEW.
* predict.def (PRED_MALLOC_NONNULL): New predictor.
* doc/extend.texi: Document that malloc attribute adds
        hit to compiler.
2018-08-07  Martin Liska  <mliska@suse.cz>

        PR middle-end/83023
* gcc.dg/predict-16.c: New test.
* g++.dg/predict-1.C: New test.

From-SVN: r263355

gcc/ChangeLog
gcc/doc/extend.texi
gcc/predict.c
gcc/predict.def
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/predict-1.C [new file with mode: 0644]
gcc/testsuite/gcc.dg/predict-16.c [new file with mode: 0644]

index 5121968cda26d08e1e284b9772101321e9d5496e..8bbcceacdd969e2029d47a673ebc8e69eb32c6d8 100644 (file)
@@ -1,3 +1,12 @@
+2018-08-07  Martin Liska  <mliska@suse.cz>
+
+        PR middle-end/83023
+       * predict.c (expr_expected_value_1): Handle DECL_IS_MALLOC,
+        BUILT_IN_REALLOC and DECL_IS_OPERATOR_NEW.
+       * predict.def (PRED_MALLOC_NONNULL): New predictor.
+       * doc/extend.texi: Document that malloc attribute adds
+        hit to compiler.
+
 2018-08-06  John David Anglin  <danglin@gcc.gnu.org>
 
        PR target/86807
index bf465d7b93cda579ccc2119cc3b3a62e9eaa353f..183ff1c6348dc6347c98f7a3906b64893a02e502 100644 (file)
@@ -2941,7 +2941,9 @@ that the pointer @var{P} returned by the function cannot alias any
 other pointer valid when the function returns, and moreover no
 pointers to valid objects occur in any storage addressed by @var{P}.
 
-Using this attribute can improve optimization.  Functions like
+Using this attribute can improve optimization.  Compiler predicts
+that a function with the attribute returns non-null in most cases.
+Functions like
 @code{malloc} and @code{calloc} have this property because they return
 a pointer to uninitialized or zeroed-out storage.  However, functions
 like @code{realloc} do not have this property, as they can return a
index a6769eda1c776dcdfbc9b879ca3552d90b185968..96ae10f1319a6593dd0856a599adfca7c5b97190 100644 (file)
@@ -2380,6 +2380,14 @@ expr_expected_value_1 (tree type, tree op0, enum tree_code code,
                }
              return NULL;
            }
+
+         if (DECL_IS_MALLOC (decl) || DECL_IS_OPERATOR_NEW (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;
            }
index 4ed97ed165c4d386aee2fd8c287de36ea4eed1f7..76e6590cc961c3c8541a1fdaef333a36549ddd4b 100644 (file)
@@ -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.  */
index c556cb1b5c93caa21458c8dd32f5e348f42b6028..868f4215ef0c10f0b0af11a9a1d133240084dd03 100644 (file)
@@ -1,3 +1,9 @@
+2018-08-07  Martin Liska  <mliska@suse.cz>
+
+        PR middle-end/83023
+       * gcc.dg/predict-16.c: New test.
+       * g++.dg/predict-1.C: New test.
+
 2018-08-07  Steve Ellcey  <sellcey@cavium.com>
            Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
 
diff --git a/gcc/testsuite/g++.dg/predict-1.C b/gcc/testsuite/g++.dg/predict-1.C
new file mode 100644 (file)
index 0000000..8e2032f
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-profile_estimate" } */
+
+#include <new>
+
+int *r;
+
+void test()
+{
+  r = new(std::nothrow) int;
+  if (r)
+    __builtin_memset (r, 0, sizeof(int));
+}
+
+/* { dg-final { scan-tree-dump "malloc returned non-NULL heuristics of edge\[^:\]*: 99.96%" "profile_estimate"} } */
diff --git a/gcc/testsuite/gcc.dg/predict-16.c b/gcc/testsuite/gcc.dg/predict-16.c
new file mode 100644 (file)
index 0000000..e1f331b
--- /dev/null
@@ -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%" 5 "profile_estimate"} } */