This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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
>>
> 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]