This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Add malloc predictor (PR middle-end/83023).
On 08/07/2018 01:51 PM, Jan Hubicka wrote:
>>
>> 2018-07-26 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.
>
> 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 <mliska@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
>>
>