[tree-profiling] More return predictors fixes

Jan Hubicka jh@suse.cz
Sun Aug 15 23:05:00 GMT 2004


Hi,
this patch fix the const return predictor so it no longer works the
ohter way around.  It quite surprise me that the returns passing positive
constants are usually taken but in addition to the SPECs I tested it on
GCC and gimp and it ineed appears to be the case.  I wonder what makes
the current implementaiton so different from RTL (it does differ - it is
more smart on looking up the constants and it give up in the case all
return values are actually positive constnts) to explain the oposite
outcome, but I double checked the code and it really appears to do what
it is supposed to...

Bootstrapped/regtested on i686-pc-gnu-linux, commited.

Honza

2004-08-16  Jan Hubicka  <jh@suse.cz>
	* predict.c (estimate_probability): Run BB level predictors just once per block.
	(return_prediction): Return the expected outcome.
	(apply_return_prediction): Use the expected outcome.
	* predict.def (PRED_CONST_RETURN, PRED_NEGATIVE_RETURN,
	PRED_NULL_RETURN): Fill in values matching the new implementation.
Index: predict.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/predict.c,v
retrieving revision 1.71.2.18.2.14
diff -c -3 -p -r1.71.2.18.2.14 predict.c
*** predict.c	13 Aug 2004 23:50:32 -0000	1.71.2.18.2.14
--- predict.c	15 Aug 2004 18:17:07 -0000
*************** estimate_probability (struct loops *loop
*** 836,844 ****
  		    break;
  		  }
  	    }
- 	  bb_estimate_probability_locally (bb);
  	}
! 
      }
  
    /* Attach the combined probability to each conditional jump.  */
--- 836,843 ----
  		    break;
  		  }
  	    }
  	}
!       bb_estimate_probability_locally (bb);
      }
  
    /* Attach the combined probability to each conditional jump.  */
*************** tree_predict_by_opcode (basic_block bb)
*** 1113,1119 ****
  
  /* Try to guess whether the value of return means error code.  */
  static enum br_predictor
! return_prediction (tree val)
  {
    /* VOID.  */
    if (!val)
--- 1112,1118 ----
  
  /* Try to guess whether the value of return means error code.  */
  static enum br_predictor
! return_prediction (tree val, enum prediction *prediction)
  {
    /* VOID.  */
    if (!val)
*************** return_prediction (tree val)
*** 1123,1129 ****
      {
        /* NULL is usually not returned.  */
        if (integer_zerop (val))
! 	return PRED_NULL_RETURN;
      }
    else if (INTEGRAL_TYPE_P (TREE_TYPE (val)))
      {
--- 1122,1131 ----
      {
        /* NULL is usually not returned.  */
        if (integer_zerop (val))
! 	{
! 	  *prediction = NOT_TAKEN;
! 	  return PRED_NULL_RETURN;
! 	}
      }
    else if (INTEGRAL_TYPE_P (TREE_TYPE (val)))
      {
*************** return_prediction (tree val)
*** 1131,1143 ****
           errors.  */
        if (TREE_CODE (val) == INTEGER_CST
  	  && tree_int_cst_sgn (val) < 0)
! 	return PRED_NEGATIVE_RETURN;
!       /* Constant return values are also usually erors,
!          zero/one often mean booleans so exclude them from the
  	 heuristics.  */
        if (TREE_CONSTANT (val)
  	  && (!integer_zerop (val) && !integer_onep (val)))
! 	return PRED_CONST_RETURN;
      }
    return PRED_NO_PREDICTION;
  }
--- 1133,1151 ----
           errors.  */
        if (TREE_CODE (val) == INTEGER_CST
  	  && tree_int_cst_sgn (val) < 0)
! 	{
! 	  *prediction = NOT_TAKEN;
! 	  return PRED_NEGATIVE_RETURN;
! 	}
!       /* Constant return values seems to be commonly taken.
!          Zero/one often represent booleans so exclude them from the
  	 heuristics.  */
        if (TREE_CONSTANT (val)
  	  && (!integer_zerop (val) && !integer_onep (val)))
! 	{
! 	  *prediction = TAKEN;
! 	  return PRED_NEGATIVE_RETURN;
! 	}
      }
    return PRED_NO_PREDICTION;
  }
*************** apply_return_prediction (int *heads)
*** 1153,1158 ****
--- 1161,1167 ----
    tree phi;
    int phi_num_args, i;
    enum br_predictor pred;
+   enum prediction direction;
  
    for (e = EXIT_BLOCK_PTR->pred; e ; e = e->pred_next)
      {
*************** apply_return_prediction (int *heads)
*** 1182,1202 ****
    if (!phi)
      return;
    phi_num_args = PHI_NUM_ARGS (phi);
!   pred = return_prediction (PHI_ARG_DEF (phi, 0));
  
    /* Avoid the degenerate case where all return values form the function
       belongs to same category (ie they are all positive constants)
       so we can hardly say something about them.  */
    for (i = 1; i < phi_num_args; i++)
!     if (pred != return_prediction (PHI_ARG_DEF (phi, i)))
        break;
    if (i != phi_num_args)
      for (i = 0; i < phi_num_args; i++)
        {
! 	pred = return_prediction (PHI_ARG_DEF (phi, i));
  	if (pred != PRED_NO_PREDICTION)
  	  predict_paths_leading_to (PHI_ARG_EDGE (phi, i)->src, heads, pred,
! 				    NOT_TAKEN);
        }
  }
  
--- 1191,1211 ----
    if (!phi)
      return;
    phi_num_args = PHI_NUM_ARGS (phi);
!   pred = return_prediction (PHI_ARG_DEF (phi, 0), &direction);
  
    /* Avoid the degenerate case where all return values form the function
       belongs to same category (ie they are all positive constants)
       so we can hardly say something about them.  */
    for (i = 1; i < phi_num_args; i++)
!     if (pred != return_prediction (PHI_ARG_DEF (phi, i), &direction))
        break;
    if (i != phi_num_args)
      for (i = 0; i < phi_num_args; i++)
        {
! 	pred = return_prediction (PHI_ARG_DEF (phi, i), &direction);
  	if (pred != PRED_NO_PREDICTION)
  	  predict_paths_leading_to (PHI_ARG_EDGE (phi, i)->src, heads, pred,
! 				    direction);
        }
  }
  
Index: predict.def
===================================================================
RCS file: /cvs/gcc/gcc/gcc/predict.def,v
retrieving revision 1.15.2.3.2.3
diff -c -3 -p -r1.15.2.3.2.3 predict.def
*** predict.def	2 Aug 2004 23:11:53 -0000	1.15.2.3.2.3
--- predict.def	15 Aug 2004 18:17:07 -0000
*************** DEF_PREDICTOR (PRED_TREE_EARLY_RETURN, "
*** 110,122 ****
  DEF_PREDICTOR (PRED_GOTO, "goto", HITRATE (70), 0)
  
  /* Branch ending with return constant is probably not taken.  */
! DEF_PREDICTOR (PRED_CONST_RETURN, "const return", HITRATE (95), 0)
  
  /* Branch ending with return negative constant is probably not taken.  */
! DEF_PREDICTOR (PRED_NEGATIVE_RETURN, "negative return", HITRATE (96), 0)
  
  /* Branch ending with return; is probably not taken */
! DEF_PREDICTOR (PRED_NULL_RETURN, "null return", HITRATE (90), 0)
  
  /* Branches to a mudflap bounds check are extremely unlikely.  */
  DEF_PREDICTOR (PRED_MUDFLAP, "mudflap check", HITRATE (99), 0)
--- 110,122 ----
  DEF_PREDICTOR (PRED_GOTO, "goto", HITRATE (70), 0)
  
  /* Branch ending with return constant is probably not taken.  */
! DEF_PREDICTOR (PRED_CONST_RETURN, "const return", HITRATE (69), 0)
  
  /* Branch ending with return negative constant is probably not taken.  */
! DEF_PREDICTOR (PRED_NEGATIVE_RETURN, "negative return", HITRATE (97), 0)
  
  /* Branch ending with return; is probably not taken */
! DEF_PREDICTOR (PRED_NULL_RETURN, "null return", HITRATE (93), 0)
  
  /* Branches to a mudflap bounds check are extremely unlikely.  */
  DEF_PREDICTOR (PRED_MUDFLAP, "mudflap check", HITRATE (99), 0)



More information about the Gcc-patches mailing list