On 08/07/2018 01:51 PM, Jan Hubicka wrote: >> >> 2018-07-26 Martin Liska <mli...@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. > > Patch is OK. I am still somewhat worried that we will run into functions that > do return NULL in most times and otherwise they return newly mallocated block.
Thanks. > > For this reason please simply document the behaviour in extend.texi. > For auto-detected malloc attribute I guess we may invent extra flag about > probability of NULL return value later if we run into interesting testcases. I documented that and installed patch as r263355. Martin > > I think it is a mistake that we don't detect malloc attribute early. It has > good chance of making the simplifications in early opts to cascade. I will > look into this. > > Honza >> >> gcc/testsuite/ChangeLog: >> >> 2018-07-26 Martin Liska <mli...@suse.cz> >> >> PR middle-end/83023 >> * gcc.dg/predict-16.c: New test. >> * g++.dg/predict-1.C: New test. >> --- >> gcc/predict.c | 12 +++++++++++ >> gcc/predict.def | 5 ++++- >> gcc/testsuite/g++.dg/predict-1.C | 15 +++++++++++++ >> gcc/testsuite/gcc.dg/predict-16.c | 36 +++++++++++++++++++++++++++++++ >> 4 files changed, 67 insertions(+), 1 deletion(-) >> create mode 100644 gcc/testsuite/g++.dg/predict-1.C >> create mode 100644 gcc/testsuite/gcc.dg/predict-16.c >> >> diff --git a/gcc/predict.c b/gcc/predict.c >> index 2ee8274fe61..ef6794edda5 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) || 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)) >> { >> @@ -2420,6 +2428,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 03900bf89b3..bf659704bfc 100644 >> --- a/gcc/predict.def >> +++ b/gcc/predict.def >> @@ -55,6 +55,10 @@ DEF_PREDICTOR (PRED_UNCONDITIONAL, "unconditional jump", >> PROB_ALWAYS, >> DEF_PREDICTOR (PRED_BUILTIN_UNPREDICTABLE, "__builtin_unpredictable", >> PROB_EVEN, >> 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. */ >> @@ -173,7 +177,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/g++.dg/predict-1.C >> b/gcc/testsuite/g++.dg/predict-1.C >> new file mode 100644 >> index 00000000000..8e2032f33a4 >> --- /dev/null >> +++ b/gcc/testsuite/g++.dg/predict-1.C >> @@ -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 >> index 00000000000..e1f331b909a >> --- /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%" 5 "profile_estimate"} } */ >> -- >> 2.18.0 >> >