public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Fix code emission for FAIL_ALLOC predictor
@ 2016-06-13 13:57 Martin Liška
  2016-06-15 11:36 ` Martin Liška
  0 siblings, 1 reply; 3+ messages in thread
From: Martin Liška @ 2016-06-13 13:57 UTC (permalink / raw)
  Cc: GCC Patches, Jan Hubicka

Hello.

Following patch fixes Fortran FAIL_ALLOC predictor in a way that it introduces a new one (PRED_FORTRAN_REALLOC)
and it properly marks returned values as described in the following 2 examples:

A) allocate_allocatable

original annotation:

    if ((logical(kind=4)) __builtin_expect ((integer(kind=8)) (overflow.343 != 0), 0, 33)) // overflow
      {
        stat.341 = 5014;
      }
    else
      {
        if ((logical(kind=4)) __builtin_expect ((integer(kind=8)) (bx_ilow.data != 0B), 0, 34)) // fail alloc
          {
            stat.341 = 5014;
          }
        else
          {
            stat.341 = 0;
            bx_ilow.data = (void * restrict) __builtin_malloc (MAX_EXPR <size.342, 1>);
            if (bx_ilow.data == 0B)
              {
                stat.341 = 5014;
              }
          }
      }      
    if ((logical(kind=4)) __builtin_expect ((integer(kind=8)) (stat.341 == 0), 1, 34)) // fail alloc
      {
        bx_ilow.dtype = 539;
        bx_ilow.dim[0].lbound = (integer(kind=8)) xstart;
        bx_ilow.dim[0].ubound = 1;
        bx_ilow.dim[0].stride = 1;
        bx_ilow.dim[1].lbound = (integer(kind=8)) ystart;
        bx_ilow.dim[1].ubound = D.5342;
        bx_ilow.dim[1].stride = D.5341;
        bx_ilow.dim[2].lbound = (integer(kind=8)) zstart;
        bx_ilow.dim[2].ubound = D.5346;
        bx_ilow.dim[2].stride = D.5345;
        bx_ilow.offset = D.5352;
      }


I changed it to:

    if ((logical(kind=4)) __builtin_expect ((integer(kind=8)) (overflow.343 != 0), 0, 33)) // overflow
      {
        stat.341 = 5014;
      }
    else
      {
        if ((logical(kind=4)) __builtin_expect ((integer(kind=8)) (bx_ilow.data != 0B), 0, 35)) // repeated allocation/deallocation
          {
            stat.341 = 5014;
          }
        else
          {
            stat.341 = 0;
            bx_ilow.data = (void * restrict) __builtin_malloc (MAX_EXPR <size.342, 1>);
            if ((logical(kind=4)) __builtin_expect ((integer(kind=8)) (bx_ilow.data == 0B), 0, 34)) // fail alloc
              {
                stat.341 = 5014;
              }
          }
      }
    if (stat.341 == 0) // no expectation
      {
        bx_ilow.dtype = 539;
        bx_ilow.dim[0].lbound = (integer(kind=8)) xstart;
        bx_ilow.dim[0].ubound = 1;
        bx_ilow.dim[0].stride = 1;
        bx_ilow.dim[1].lbound = (integer(kind=8)) ystart;
        bx_ilow.dim[1].ubound = D.5342;
        bx_ilow.dim[1].stride = D.5341;
        bx_ilow.dim[2].lbound = (integer(kind=8)) zstart;
        bx_ilow.dim[2].ubound = D.5346;
        bx_ilow.dim[2].stride = D.5345;
        bx_ilow.offset = D.5352;
      }

B) array allocation

  <bb 9>:
  # size.1478_3210 = PHI <0(7), size.1478_3743(8)>
  _21 = _3740 != 0;
  _22 = (integer(kind=8)) _21;
  _23 = BUILTIN_EXPECT (_22, 0, 33); // overflow
  _24 = (logical(kind=4)) _23;
  if (_24 != 0)
    goto <bb 13>;
  else
    goto <bb 10>;

  <bb 10>:
  _25 = hrval.data;
  _26 = _25 != 0B;
  _27 = (integer(kind=8)) _26;
  _28 = BUILTIN_EXPECT (_27, 0, 34); // fail malloc
  _29 = (logical(kind=4)) _28;
  if (_29 != 0)
    goto <bb 13>;
  else
    goto <bb 11>;

  <bb 11>:
  _30 = MAX_EXPR <size.1478_3210, 1>;
  _31 = __builtin_malloc (_30);
  hrval.data = _31;
  if (_31 == 0B)
    goto <bb 12>;
  else
    goto <bb 13>;

  <bb 12>:

  <bb 13>:
  # stat.1477_3202 = PHI <5014(9), 5014(10), 0(11), 5014(12)>
  _33 = stat.1477_3202 == 0;
  _34 = (integer(kind=8)) _33;
  _35 = BUILTIN_EXPECT (_34, 1, 34); // fail malloc
  _36 = (logical(kind=4)) _35;
  if (_36 != 0)
    goto <bb 14>;
  else
    goto <bb 15>;

currently looks as follows:

  <bb 9>:
  # size.1478_3210 = PHI <0(7), size.1478_3743(8)>
  _21 = _3740 != 0;
  _22 = (integer(kind=8)) _21;
  _23 = BUILTIN_EXPECT (_22, 0, 33); // overflow
  _24 = (logical(kind=4)) _23;
  if (_24 != 0)
    goto <bb 13>;
  else
    goto <bb 10>;

  <bb 10>:
  _25 = hrval.data;
  _26 = _25 != 0B;
  _27 = (integer(kind=8)) _26;
  _28 = BUILTIN_EXPECT (_27, 0, 35); // repeated allocation/deallocation
  _29 = (logical(kind=4)) _28;
  if (_29 != 0)
    goto <bb 13>;
  else
    goto <bb 11>;

  <bb 11>:
  _30 = MAX_EXPR <size.1478_3210, 1>;
  _31 = __builtin_malloc (_30);
  hrval.data = _31;
  _33 = _31 == 0B;
  _34 = (integer(kind=8)) _33;
  _35 = BUILTIN_EXPECT (_34, 0, 34); // fail alloc
  _36 = (logical(kind=4)) _35;
  if (_36 != 0)
    goto <bb 12>;
  else
    goto <bb 13>;

  <bb 12>:

  <bb 13>:
  # stat.1477_3202 = PHI <5014(9), 5014(10), 0(11), 5014(12)>
  if (stat.1477_3202 == 0) // no prediction
    goto <bb 14>;
  else
    goto <bb 15>;

I get following numbers with the patch applied:

1) polyhedron benchmark (aermod.f90.061i.profile):
HEURISTICS                           BRANCHES  (REL)  HITRATE                COVERAGE COVERAGE  (REL)
repeated allocation/deallocation          194   4.1% 100.00% / 100.00%            194   194.00   0.0%
fail alloc                                377   7.9% 100.00% / 100.00%            377   377.00   0.0%

b) 459.GemsFDTD SPEC2006 benchmark:
HEURISTICS                           BRANCHES  (REL)  HITRATE                COVERAGE COVERAGE  (REL)
repeated allocation/deallocation          203   4.3% 100.00% / 100.00%            203   203.00   0.0%
fail alloc                                378   8.0% 100.00% / 100.00%            378   378.00   0.0%

Even though all numbers are 100%, I would suggest to set FAIL_ALLOC to PROB_VERY_LIKELY and
PRED_FORTRAN_REALLOC to PROB_LIKELY.

Ready to install the patch if it survives regression tests?

Thanks,
Martin

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] Fix code emission for FAIL_ALLOC predictor
  2016-06-13 13:57 [PATCH] Fix code emission for FAIL_ALLOC predictor Martin Liška
@ 2016-06-15 11:36 ` Martin Liška
  2016-06-15 11:52   ` Jan Hubicka
  0 siblings, 1 reply; 3+ messages in thread
From: Martin Liška @ 2016-06-15 11:36 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jan Hubicka

[-- Attachment #1: Type: text/plain, Size: 30 bytes --]

Adding missing patch.

Martin

[-- Attachment #2: 0001-Fix-code-emission-for-FAIL_ALLOC-predictor.patch --]
[-- Type: text/x-patch, Size: 4680 bytes --]

From 35ba97e0139d955c04e67ca157f8899bbb468bf1 Mon Sep 17 00:00:00 2001
From: marxin <mliska@suse.cz>
Date: Thu, 9 Jun 2016 17:51:38 +0200
Subject: [PATCH] Fix code emission for FAIL_ALLOC predictor

gcc/ChangeLog:

2016-06-13  Martin Liska  <mliska@suse.cz>

	* predict.def: Define a new predictor.

gcc/fortran/ChangeLog:

2016-06-13  Martin Liska  <mliska@suse.cz>

	* trans-array.c (gfc_array_allocate): Do not generate expect
	stmt.
	* trans.c (gfc_allocate_using_malloc): Properly set FAIL_ALLOC
	predictor for malloc return value.
	(gfc_allocate_allocatable): Use REALLOC predictor instead of
	FAIL_ALLOC.
	(gfc_deallocate_with_status): Likewise.
---
 gcc/fortran/trans-array.c |  2 +-
 gcc/fortran/trans.c       | 10 ++++------
 gcc/predict.def           | 15 +++++++++------
 3 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c
index 403ce3a..e95c8dd 100644
--- a/gcc/fortran/trans-array.c
+++ b/gcc/fortran/trans-array.c
@@ -5553,7 +5553,7 @@ gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree status, tree errmsg,
 			  build_int_cst (TREE_TYPE (status), 0));
       gfc_add_expr_to_block (&se->pre,
 		 fold_build3_loc (input_location, COND_EXPR, void_type_node,
-				  gfc_likely (cond, PRED_FORTRAN_FAIL_ALLOC),
+				  cond,
 				  set_descriptor,
 				  build_empty_stmt (input_location)));
     }
diff --git a/gcc/fortran/trans.c b/gcc/fortran/trans.c
index c6688d3..d6b4a56 100644
--- a/gcc/fortran/trans.c
+++ b/gcc/fortran/trans.c
@@ -672,9 +672,6 @@ gfc_allocate_using_malloc (stmtblock_t * block, tree pointer,
   gfc_start_block (&on_error);
   if (status != NULL_TREE)
     {
-      gfc_add_expr_to_block (&on_error,
-			     build_predict_expr (PRED_FORTRAN_FAIL_ALLOC,
-						 NOT_TAKEN));
       tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type, status,
 			     build_int_cst (status_type, LIBERROR_ALLOCATION));
       gfc_add_expr_to_block (&on_error, tmp);
@@ -693,7 +690,8 @@ gfc_allocate_using_malloc (stmtblock_t * block, tree pointer,
 				boolean_type_node, pointer,
 				build_int_cst (prvoid_type_node, 0));
   tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
-			 error_cond, gfc_finish_block (&on_error),
+			 gfc_unlikely (error_cond, PRED_FORTRAN_FAIL_ALLOC),
+			 gfc_finish_block (&on_error),
 			 build_empty_stmt (input_location));
 
   gfc_add_expr_to_block (block, tmp);
@@ -796,7 +794,7 @@ gfc_allocate_allocatable (stmtblock_t * block, tree mem, tree size, tree token,
   null_mem = gfc_unlikely (fold_build2_loc (input_location, NE_EXPR,
 					    boolean_type_node, mem,
 					    build_int_cst (type, 0)),
-			   PRED_FORTRAN_FAIL_ALLOC);
+			   PRED_FORTRAN_REALLOC);
 
   /* If mem is NULL, we call gfc_allocate_using_malloc or
      gfc_allocate_using_lib.  */
@@ -1385,7 +1383,7 @@ gfc_deallocate_with_status (tree pointer, tree status, tree errmsg,
 	  cond2 = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
 				   stat, build_zero_cst (TREE_TYPE (stat)));
 	  tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
-				 gfc_unlikely (cond2, PRED_FORTRAN_FAIL_ALLOC),
+				 gfc_unlikely (cond2, PRED_FORTRAN_REALLOC),
 				 tmp, build_empty_stmt (input_location));
 	  gfc_add_expr_to_block (&non_null, tmp);
 	}
diff --git a/gcc/predict.def b/gcc/predict.def
index c0a3f36..da4f9ab 100644
--- a/gcc/predict.def
+++ b/gcc/predict.def
@@ -163,12 +163,15 @@ DEF_PREDICTOR (PRED_FORTRAN_OVERFLOW, "overflow", PROB_ALWAYS,
 	       PRED_FLAG_FIRST_MATCH)
 
 /* Branch leading to a failure status are unlikely.  This can occur for out
-   of memory or when trying to allocate an already allocated allocated or
-   deallocating an already deallocated allocatable.  This predictor only
-   occurs when the user explicitly asked for a return status.  By default,
-   the code aborts, which is handled via PRED_NORETURN.
-   FIXME: the hitrate really ought to be close to 100%.  */
-DEF_PREDICTOR (PRED_FORTRAN_FAIL_ALLOC, "fail alloc", HITRATE (62), 0)
+   of memory.  This predictor only occurs when the user explicitly asked
+   for a return status.  By default, the code aborts,
+   which is handled via PRED_NORETURN.  */
+DEF_PREDICTOR (PRED_FORTRAN_FAIL_ALLOC, "fail alloc", PROB_VERY_LIKELY, 0)
+
+/* Predictor is used for an allocation of an already allocated memory or
+   deallocating an already deallocated allocatable.  */
+DEF_PREDICTOR (PRED_FORTRAN_REALLOC, "repeated allocation/deallocation", \
+	       PROB_LIKELY, 0)
 
 /* Branch leading to an I/O failure status are unlikely.  This predictor is
    used for I/O failures such as for invalid unit numbers.  This predictor
-- 
2.8.3


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] Fix code emission for FAIL_ALLOC predictor
  2016-06-15 11:36 ` Martin Liška
@ 2016-06-15 11:52   ` Jan Hubicka
  0 siblings, 0 replies; 3+ messages in thread
From: Jan Hubicka @ 2016-06-15 11:52 UTC (permalink / raw)
  To: Martin Liška; +Cc: gcc-patches, Jan Hubicka

> Adding missing patch.
> 
> Martin

> >From 35ba97e0139d955c04e67ca157f8899bbb468bf1 Mon Sep 17 00:00:00 2001
> From: marxin <mliska@suse.cz>
> Date: Thu, 9 Jun 2016 17:51:38 +0200
> Subject: [PATCH] Fix code emission for FAIL_ALLOC predictor
> 
> gcc/ChangeLog:
> 
> 2016-06-13  Martin Liska  <mliska@suse.cz>
> 
> 	* predict.def: Define a new predictor.
> 
> gcc/fortran/ChangeLog:
> 
> 2016-06-13  Martin Liska  <mliska@suse.cz>
> 
> 	* trans-array.c (gfc_array_allocate): Do not generate expect
> 	stmt.
> 	* trans.c (gfc_allocate_using_malloc): Properly set FAIL_ALLOC
> 	predictor for malloc return value.
> 	(gfc_allocate_allocatable): Use REALLOC predictor instead of
> 	FAIL_ALLOC.
> 	(gfc_deallocate_with_status): Likewise.

OK, thanks!

Honza

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2016-06-15 11:52 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-13 13:57 [PATCH] Fix code emission for FAIL_ALLOC predictor Martin Liška
2016-06-15 11:36 ` Martin Liška
2016-06-15 11:52   ` Jan Hubicka

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).