opcode heuristic tweek

Jan Hubicka jh@suse.cz
Wed Dec 12 05:05:00 GMT 2001


Hi,
this patch improves considerably the hitrate of our heuristics by fixing
opcode heuristics.  Currently the opcode heuristics predicts the comparison
with 0 and floating point comparisons, that behave very differently from
the rest of covered cases. 0 because it is used for booleans and floats
probably because equality test is used just in very special cases.

This patch removes thsese cases increasing the opcode heuristic hitrate
from 55% to 70 and 78%.

Honza

Wed Dec 12 14:02:02 CET 2001  Jan Hubicka  <jh@suse.cz>
	* predict.c (estimate_probability): Reorganize opcode heuristics.
	* predict.def (PRED_OPCODE_POSITIVE, PRED_OPCODE_NONEQUAL,
	PRED_FPOPCODE): New.

*** predict.c	Fri Nov 23 03:05:18 2001
--- /home/hubicka/egcs/gcc/predict.c	Wed Dec 12 13:58:08 2001
*************** estimate_probability (loops_info)
*** 435,508 ****
        /* Try "pointer heuristic."
  	 A comparison ptr == 0 is predicted as false.
  	 Similarly, a comparison ptr1 == ptr2 is predicted as false.  */
!       switch (GET_CODE (cond))
! 	{
! 	case EQ:
! 	  if (GET_CODE (XEXP (cond, 0)) == REG
! 	      && REG_POINTER (XEXP (cond, 0))
! 	      && (XEXP (cond, 1) == const0_rtx
! 		  || (GET_CODE (XEXP (cond, 1)) == REG
! 		      && REG_POINTER (XEXP (cond, 1)))))
! 
  	    predict_insn_def (last_insn, PRED_POINTER, NOT_TAKEN);
! 	  break;
! 	case NE:
! 	  if (GET_CODE (XEXP (cond, 0)) == REG
! 	      && REG_POINTER (XEXP (cond, 0))
! 	      && (XEXP (cond, 1) == const0_rtx
! 		  || (GET_CODE (XEXP (cond, 1)) == REG
! 		      && REG_POINTER (XEXP (cond, 1)))))
  	    predict_insn_def (last_insn, PRED_POINTER, TAKEN);
! 	  break;
! 
! 	default:
! 	  break;
! 	}
! 
        /* Try "opcode heuristic."
  	 EQ tests are usually false and NE tests are usually true. Also,
  	 most quantities are positive, so we can make the appropriate guesses
  	 about signed comparisons against zero.  */
!       switch (GET_CODE (cond))
! 	{
! 	case CONST_INT:
! 	  /* Unconditional branch.  */
! 	  predict_insn_def (last_insn, PRED_UNCONDITIONAL,
! 			    cond == const0_rtx ? NOT_TAKEN : TAKEN);
! 	  break;
! 
! 	case EQ:
! 	case UNEQ:
! 	  predict_insn_def (last_insn, PRED_OPCODE, NOT_TAKEN);
! 	  break;
! 	case NE:
! 	case LTGT:
! 	  predict_insn_def (last_insn, PRED_OPCODE, TAKEN);
! 	  break;
! 	case ORDERED:
! 	  predict_insn_def (last_insn, PRED_OPCODE, TAKEN);
! 	  break;
! 	case UNORDERED:
! 	  predict_insn_def (last_insn, PRED_OPCODE, NOT_TAKEN);
! 	  break;
! 	case LE:
! 	case LT:
! 	  if (XEXP (cond, 1) == const0_rtx
! 	      || (GET_CODE (XEXP (cond, 1)) == CONST_INT
! 		  && INTVAL (XEXP (cond, 1)) == -1))
! 	    predict_insn_def (last_insn, PRED_OPCODE, NOT_TAKEN);
! 	  break;
! 	case GE:
! 	case GT:
! 	  if (XEXP (cond, 1) == const0_rtx
! 	      || (GET_CODE (XEXP (cond, 1)) == CONST_INT
! 		  && INTVAL (XEXP (cond, 1)) == -1))
! 	    predict_insn_def (last_insn, PRED_OPCODE, TAKEN);
! 	  break;
! 
! 	default:
! 	  break;
! 	}
      }
  
    /* Attach the combined probability to each conditional jump.  */
--- 453,535 ----
        /* Try "pointer heuristic."
  	 A comparison ptr == 0 is predicted as false.
  	 Similarly, a comparison ptr1 == ptr2 is predicted as false.  */
!       if (GET_RTX_CLASS (GET_CODE (cond)) == '<'
! 	  && ((REG_P (XEXP (cond, 0)) && REG_POINTER (XEXP (cond, 0)))
! 	      || (REG_P (XEXP (cond, 1)) && REG_POINTER (XEXP (cond, 1)))))
! 	switch (GET_CODE (cond))
! 	  {
! 	  case EQ:
  	    predict_insn_def (last_insn, PRED_POINTER, NOT_TAKEN);
! 	    break;
! 	  case NE:
  	    predict_insn_def (last_insn, PRED_POINTER, TAKEN);
! 	    break;
! 	  default:
! 	    break;
! 	  }
!       else
        /* Try "opcode heuristic."
  	 EQ tests are usually false and NE tests are usually true. Also,
  	 most quantities are positive, so we can make the appropriate guesses
  	 about signed comparisons against zero.  */
! 	switch (GET_CODE (cond))
! 	  {
! 	  case CONST_INT:
! 	    /* Unconditional branch.  */
! 	    predict_insn_def (last_insn, PRED_UNCONDITIONAL,
! 			      cond == const0_rtx ? NOT_TAKEN : TAKEN);
! 	    break;
! 
! 	  case EQ:
! 	  case UNEQ:
! 	    /* Floating point comparisons appears to behave in a very
! 	       inpredictable way because of special role of = tests in
! 	       FP code.  */
! 	    if (FLOAT_MODE_P (GET_MODE (XEXP (cond, 0))))
! 	      ;
! 	    /* Comparisons with 0 are often used for booleans and there is
! 	       nothing usefull to predict about them.  */
! 	    else if (XEXP (cond, 1) == const0_rtx || XEXP (cond, 0) == const0_rtx)
! 	      ;
! 	    else
! 	      predict_insn_def (last_insn, PRED_OPCODE_NONEQUAL, NOT_TAKEN);
! 	    break;
! 	  case NE:
! 	  case LTGT:
! 	    /* Floating point comparisons appears to behave in a very
! 	       inpredictable way because of special role of = tests in
! 	       FP code.  */
! 	    if (FLOAT_MODE_P (GET_MODE (XEXP (cond, 0))))
! 	      ;
! 	    /* Comparisons with 0 are often used for booleans and there is
! 	       nothing usefull to predict about them.  */
! 	    else if (XEXP (cond, 1) == const0_rtx || XEXP (cond, 0) == const0_rtx)
! 	      ;
! 	    else
! 	      predict_insn_def (last_insn, PRED_OPCODE_NONEQUAL, TAKEN);
! 	    break;
! 	  case ORDERED:
! 	    predict_insn_def (last_insn, PRED_FPOPCODE, TAKEN);
! 	    break;
! 	  case UNORDERED:
! 	    predict_insn_def (last_insn, PRED_FPOPCODE, NOT_TAKEN);
! 	    break;
! 	  case LE:
! 	  case LT:
! 	    if (XEXP (cond, 1) == const0_rtx || XEXP (cond, 1) == const1_rtx
! 		|| XEXP (cond, 1) == constm1_rtx)
! 	      predict_insn_def (last_insn, PRED_OPCODE_POSITIVE, NOT_TAKEN);
! 	    break;
! 	  case GE:
! 	  case GT:
! 	    if (XEXP (cond, 1) == const0_rtx || XEXP (cond, 1) == const1_rtx
! 		|| XEXP (cond, 1) == constm1_rtx)
! 	      predict_insn_def (last_insn, PRED_OPCODE_POSITIVE, TAKEN);
! 	    break;
! 
! 	  default:
! 	    break;
! 	  }
      }
  
    /* Attach the combined probability to each conditional jump.  */
Index: predict.def
===================================================================
RCS file: /cvs/gcc/egcs/gcc/predict.def,v
retrieving revision 1.12
diff -c -3 -p -r1.12 predict.def
*** predict.def	2001/10/28 20:09:15	1.12
--- predict.def	2001/12/12 13:01:43
*************** DEF_PREDICTOR (PRED_LOOP_HEADER, "loop h
*** 89,95 ****
  DEF_PREDICTOR (PRED_POINTER, "pointer", HITRATE (83), 0)
  
  /* NE is probable, EQ not etc...  */
! DEF_PREDICTOR (PRED_OPCODE, "opcode", HITRATE (55), 0)
  
  /* Branch guarding call is probably taken.  */
  DEF_PREDICTOR (PRED_CALL, "call", HITRATE (70), 0)
--- 89,97 ----
  DEF_PREDICTOR (PRED_POINTER, "pointer", HITRATE (83), 0)
  
  /* NE is probable, EQ not etc...  */
! DEF_PREDICTOR (PRED_OPCODE_POSITIVE, "opcode values positive", HITRATE (78), 0)
! DEF_PREDICTOR (PRED_OPCODE_NONEQUAL, "opcode values nonequal", HITRATE (70), 0)
! DEF_PREDICTOR (PRED_FPOPCODE, "fp_opcode", HITRATE (90), 0)
  
  /* Branch guarding call is probably taken.  */
  DEF_PREDICTOR (PRED_CALL, "call", HITRATE (70), 0)



More information about the Gcc-patches mailing list