branch prediction tweek

Jan Hubicka jh@suse.cz
Mon Aug 12 09:33:00 GMT 2002


Hi,
the attached patch cleans up how the call based branch prediction heuristics
work.  Now the highlevel branch prediction stuff is used instead of determining
the sequences from RTL.  This has an advnatages - I can now discover recusive
functions (that have the property of having hot path not going trought the call
site) and do better work on CALL heruistics that predicts calls as improbable
since they are commonly error handling.  I've restricted this to functions
returning void that improves the hitrates consistently.

The patch results in slightly, but measurably faster compiler and about 1-2 points
improvement in SPEC score.

Honza

Mon Aug 12 18:30:09 CEST 2002  Jan Hubicka  <jh@suse.cz>

	* calls.c: Include predict.h
	(expand_call): Handle recursion, noreturn and call heuristics.
	* predict.c (estimate_probability): Kill call heuristics.
	(process_note_heuristics): Kill noreturn heuristics.

*** calls.c.old	Sun Aug 11 18:02:29 2002
--- calls.c	Sun Aug 11 19:57:25 2002
*************** Software Foundation, 59 Temple Place - S
*** 34,39 ****
--- 34,40 ----
  #include "timevar.h"
  #include "sbitmap.h"
  #include "langhooks.h"
+ #include "predict.h"
  
  #if !defined FUNCTION_OK_FOR_SIBCALL
  #define FUNCTION_OK_FOR_SIBCALL(DECL) 1
*************** expand_call (exp, target, ignore)
*** 2607,2612 ****
--- 2608,2637 ----
  
    function_call_count++;
  
+   /* In case we are seeing tail recursion, drop the note.  */
+   if (TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
+       && TREE_OPERAND (TREE_OPERAND (exp, 0), 0) == current_function_decl)
+     {
+       rtx note;
+       note = emit_note (NULL, NOTE_INSN_PREDICTION);
+       NOTE_PREDICTION (note) = NOTE_PREDICT (PRED_RECURSION, NOT_TAKEN);
+     }
+   /* Functions never returning and longjumps are usually not taken.  */
+   else if (flags & (ECF_NORETURN | ECF_LONGJMP))
+     {
+       rtx note;
+       note = emit_note (NULL, NOTE_INSN_PREDICTION);
+       NOTE_PREDICTION (note) = NOTE_PREDICT (PRED_NORETURN, NOT_TAKEN);
+     }
+   /* Predict functions returning VOID as improbable.  They are commonly used to
+      signalize error states.  */
+   else if (TYPE_MODE (TREE_TYPE (exp)) == VOIDmode)
+     {
+       rtx note;
+       note = emit_note (NULL, NOTE_INSN_PREDICTION);
+       NOTE_PREDICTION (note) = NOTE_PREDICT (PRED_CALL, NOT_TAKEN);
+     }
+ 
    /* We want to make two insn chains; one for a sibling call, the other
       for a normal call.  We will select one of the two chains after
       initial RTL generation is complete.  */
*** predict.def.old	Sun Aug 11 18:02:19 2002
--- predict.def	Sun Aug 11 18:02:23 2002
*************** DEF_PREDICTOR (PRED_NEGATIVE_RETURN, "ne
*** 113,115 ****
--- 113,118 ----
  
  /* Branch ending with return; is probably not taken */
  DEF_PREDICTOR (PRED_NULL_RETURN, "null return", HITRATE (90), 0)
+ 
+ /* Recursive calls usually does not happen */
+ DEF_PREDICTOR (PRED_RECURSION, "recursion", HITRATE (80), 0)
*** predict.c.old	Sun Aug 11 21:01:25 2002
--- predict.c	Sun Aug 11 20:45:02 2002
*************** estimate_probability (loops_info)
*** 490,519 ****
  	       && !predicted_by_p (bb, PRED_NEGATIVE_RETURN)
  	       && !last_basic_block_p (e->dest))
  	    predict_edge_def (e, PRED_EARLY_RETURN, TAKEN);
- 
- 	  /* Look for block we are guarding (ie we dominate it,
- 	     but it doesn't postdominate us).  */
- 	  if (e->dest != EXIT_BLOCK_PTR && e->dest != bb
- 	      && dominated_by_p (dominators, e->dest, e->src)
- 	      && !dominated_by_p (post_dominators, e->src, e->dest))
- 	    {
- 	      rtx insn;
- 
- 	      /* The call heuristic claims that a guarded function call
- 		 is improbable.  This is because such calls are often used
- 		 to signal exceptional situations such as printing error
- 		 messages.  */
- 	      for (insn = e->dest->head; insn != NEXT_INSN (e->dest->end);
- 		   insn = NEXT_INSN (insn))
- 		if (GET_CODE (insn) == CALL_INSN
- 		    /* Constant and pure calls are hardly used to signalize
- 		       something exceptional.  */
- 		    && ! CONST_OR_PURE_CALL_P (insn))
- 		  {
- 		    predict_edge_def (e, PRED_CALL, NOT_TAKEN);
- 		    break;
- 		  }
- 	    }
  	}
  
        cond = get_condition (last_insn, &earliest);
--- 490,495 ----
*************** process_note_predictions (bb, heads, dom
*** 783,812 ****
       dominance_info post_dominators;
  {
    rtx insn;
-   edge e;
- 
-   /* Additionaly, we check here for blocks with no successors.  */
-   int contained_noreturn_call = 0;
    int was_bb_head = 0;
-   int noreturn_block = 1;
  
    for (insn = bb->end; insn;
         was_bb_head |= (insn == bb->head), insn = PREV_INSN (insn))
      {
!       if (GET_CODE (insn) != NOTE)
! 	{
! 	  if (was_bb_head)
! 	    break;
! 	  else
! 	    {
! 	      /* Noreturn calls cause program to exit, therefore they are
! 	         always predicted as not taken.  */
! 	      if (GET_CODE (insn) == CALL_INSN
! 		  && find_reg_note (insn, REG_NORETURN, NULL))
! 		contained_noreturn_call = 1;
! 	      continue;
! 	    }
! 	}
        if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_PREDICTION)
  	{
  	  int alg = (int) NOTE_PREDICTION_ALG (insn);
--- 759,771 ----
       dominance_info post_dominators;
  {
    rtx insn;
    int was_bb_head = 0;
  
    for (insn = bb->end; insn;
         was_bb_head |= (insn == bb->head), insn = PREV_INSN (insn))
      {
!       if (GET_CODE (insn) != NOTE && was_bb_head)
! 	break;
        if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_PREDICTION)
  	{
  	  int alg = (int) NOTE_PREDICTION_ALG (insn);
*************** process_note_predictions (bb, heads, dom
*** 819,837 ****
  	  delete_insn (insn);
  	}
      }
-   for (e = bb->succ; e; e = e->succ_next)
-     if (!(e->flags & EDGE_FAKE))
-       noreturn_block = 0;
-   if (contained_noreturn_call)
-     {
-       /* This block ended from other reasons than because of return.
-          If it is because of noreturn call, this should certainly not
-          be taken.  Otherwise it is probably some error recovery.  */
-       process_note_prediction (bb,
- 			       heads,
- 			       dominators,
- 			       post_dominators, PRED_NORETURN, NOT_TAKEN);
-     }
  }
  
  /* Gathers NOTE_INSN_PREDICTIONs and turns them into
--- 778,783 ----



More information about the Gcc-patches mailing list