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]

[cfg-branch]


Hi,
I've installed the attached patch that hopes to improve the opcode heuristics.

Honza

Hi,
this is updated patch to refine opcode heuristic.  I believe that the low
overall coverage of opcode heuristic is caused by fact, that we mix
too many different things together. For instance test whether FP values
are unordered should be much better predictable than test whether integer
is 0, as such test is often used in boolean expression.

For this putpose I split OPCODE heurostic to OPCODE_POSITIVE - declaring that
values should be positive (this is usually strong one), OPCODE_NONZERO -
declaring that values usually does not equal zero (very weak one - perhaps we
may want to drop it, but I would like to see overall results first),
OPCODE_NONEQUAL - declaring that two values are usually not equal in case
neighter of them is 0 (it is unlikely value to be 42, while more likely to be
0).  In the past I was also experimenting with OPCODE_NONONE doing the
same as NONZERO, but given the usual C coding style, boolean expressions
are not test agains 1.

The patch also refines the pointer heuristic to match even when only one of
operands is known to be pointer - this is important in case the pointer
is compared to constant, that is load to temporary register, as that register
don't have pointer flag anymore.

As a next step I would like to move opcode and pointer heuristics after first
CSE pass, as the insn chain is more similar to what programmer really wanted.

Sat Aug 25 14:55:23 CEST 2001  Jan Hubicka  <jh@suse.cz>
	* predict.c (estimate_probability): Refine pointer heuristic;
	split opcode into multiple heuristics.
	* predict.def (PRED_OPCODE_POSITIVE, PRED_OPCODE_NONZERO,
	PRED_OPCODE_NONEQUAL, PRED_FPOPCODE): New.

Index: predict.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/predict.c,v
retrieving revision 1.38
diff -c -3 -p -r1.38 predict.c
*** predict.c	2001/08/22 14:35:31	1.38
--- predict.c	2001/08/25 12:38:32
*************** 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.  */
--- 435,507 ----
        /* 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:
! 	    if (FLOAT_MODE_P (GET_MODE (XEXP (cond, 0))))
! 	      predict_insn_def (last_insn, PRED_FPOPCODE, NOT_TAKEN);
! 	    else if (XEXP (cond, 1) == const0_rtx || XEXP (cond, 0) == const0_rtx)
! 	      predict_insn_def (last_insn, PRED_OPCODE_NONZERO, NOT_TAKEN);
! 	    else
! 	      predict_insn_def (last_insn, PRED_OPCODE_NONEQUAL, NOT_TAKEN);
! 	    break;
! 	  case NE:
! 	  case LTGT:
! 	    if (FLOAT_MODE_P (GET_MODE (XEXP (cond, 0))))
! 	      predict_insn_def (last_insn, PRED_FPOPCODE, TAKEN);
! 	    else if (XEXP (cond, 1) == const0_rtx || XEXP (cond, 0) == const0_rtx)
! 	      predict_insn_def (last_insn, PRED_OPCODE_NONZERO, TAKEN);
! 	    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.11
diff -c -3 -p -r1.11 predict.def
*** predict.def	2001/08/22 14:35:31	1.11
--- predict.def	2001/08/25 12:38:32
*************** 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,98 ----
  DEF_PREDICTOR (PRED_POINTER, "pointer", HITRATE (83), 0)
  
  /* NE is probable, EQ not etc...  */
! DEF_PREDICTOR (PRED_OPCODE_POSITIVE, "opcode values positive", HITRATE (71), 0)
! DEF_PREDICTOR (PRED_OPCODE_NONZERO, "opcode values nonzero", HITRATE (52), 0)
! DEF_PREDICTOR (PRED_OPCODE_NONEQUAL, "opcode values nonequal", HITRATE (62), 0)
! DEF_PREDICTOR (PRED_FPOPCODE, "fp_opcode", HITRATE (90), 0)
  
  /* Branch guarding call is probably taken.  */
  DEF_PREDICTOR (PRED_CALL, "call", HITRATE (70), 0)


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