branch probabilities for calls

Richard Henderson rth@cygnus.com
Mon May 8 23:15:00 GMT 2000


IA-64 has branch predicion bits for call instructions.  These
are of course only useful when the call is predicated.  Here
I propagate the branch probability tag from the jump we removed
onto any waiting call insns.

Bootstrapped ia64-linux.


r~

        * ifcvt.c (cond_exec_process_insns): New argument prob_val.
        Attach it to call insns.
        (cond_exec_process_if_block): Track probability for true and
        false branches.
        (dead_or_predicable): Likewise.

Index: ifcvt.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/ifcvt.c,v
retrieving revision 1.12
diff -c -p -d -r1.12 ifcvt.c
*** ifcvt.c	2000/05/06 21:50:03	1.12
--- ifcvt.c	2000/05/09 05:53:45
*************** static int count_bb_insns		PARAMS ((basi
*** 74,80 ****
  static rtx first_active_insn		PARAMS ((basic_block));
  static int last_active_insn_p		PARAMS ((basic_block, rtx));
  
! static int cond_exec_process_insns	PARAMS ((rtx, rtx, rtx, int));
  static rtx cond_exec_get_condition	PARAMS ((rtx));
  static int cond_exec_process_if_block	PARAMS ((basic_block, basic_block,
  						 basic_block, basic_block));
--- 74,80 ----
  static rtx first_active_insn		PARAMS ((basic_block));
  static int last_active_insn_p		PARAMS ((basic_block, rtx));
  
! static int cond_exec_process_insns	PARAMS ((rtx, rtx, rtx, rtx, int));
  static rtx cond_exec_get_condition	PARAMS ((rtx));
  static int cond_exec_process_if_block	PARAMS ((basic_block, basic_block,
  						 basic_block, basic_block));
*************** last_active_insn_p (bb, insn)
*** 179,188 ****
     insns were processed.  */
  
  static int
! cond_exec_process_insns (start, end, test, mod_ok)
       rtx start;			/* first insn to look at */
       rtx end;			/* last insn to look at */
       rtx test;			/* conditional execution test */
       int mod_ok;		/* true if modifications ok last insn.  */
  {
    int must_be_last = FALSE;
--- 179,189 ----
     insns were processed.  */
  
  static int
! cond_exec_process_insns (start, end, test, prob_val, mod_ok)
       rtx start;			/* first insn to look at */
       rtx end;			/* last insn to look at */
       rtx test;			/* conditional execution test */
+      rtx prob_val;		/* probability of branch taken.  */
       int mod_ok;		/* true if modifications ok last insn.  */
  {
    int must_be_last = FALSE;
*************** cond_exec_process_insns (start, end, tes
*** 212,217 ****
--- 213,223 ----
  		       gen_rtx_COND_EXEC (VOIDmode, copy_rtx (test),
  					  PATTERN (insn)), 1);
  
+       if (GET_CODE (insn) == CALL_INSN && prob_val)
+ 	validate_change (insn, &REG_NOTES (insn),
+ 			 alloc_EXPR_LIST (REG_BR_PROB, prob_val,
+ 					  REG_NOTES (insn)), 1);
+ 
      insn_done:
        if (insn == end)
  	break;
*************** cond_exec_process_if_block (test_bb, the
*** 267,272 ****
--- 273,280 ----
    int then_mod_ok;		/* whether conditional mods are ok in THEN */
    rtx true_expr;		/* test for else block insns */
    rtx false_expr;		/* test for then block insns */
+   rtx true_prob_val;		/* probability of else block */
+   rtx false_prob_val;		/* probability of then block */
    int n_insns;
  
    /* Find the conditional jump to the ELSE or JOIN part, and isolate
*************** cond_exec_process_if_block (test_bb, the
*** 324,329 ****
--- 332,346 ----
  			       GET_MODE (true_expr), XEXP (true_expr, 0),
  			       XEXP (true_expr, 1));
  
+   true_prob_val = find_reg_note (test_bb->end, REG_BR_PROB, NULL_RTX);
+   if (true_prob_val)
+     {
+       true_prob_val = XEXP (true_prob_val, 0);
+       false_prob_val = GEN_INT (REG_BR_PROB_BASE - INTVAL (true_prob_val));
+     }
+   else
+     false_prob_val = NULL_RTX;
+ 
    /* For IF-THEN-ELSE blocks, we don't allow modifications of the test
       on then THEN block.  */
    then_mod_ok = (else_bb == NULL_BLOCK);
*************** cond_exec_process_if_block (test_bb, the
*** 333,344 ****
  
    if (then_end
        && ! cond_exec_process_insns (then_start, then_end,
! 				    false_expr, then_mod_ok))
      goto fail;
  
    if (else_bb
        && ! cond_exec_process_insns (else_start, else_end,
! 				    true_expr, TRUE))
      goto fail;
  
    if (! apply_change_group ())
--- 350,361 ----
  
    if (then_end
        && ! cond_exec_process_insns (then_start, then_end,
! 				    false_expr, false_prob_val, then_mod_ok))
      goto fail;
  
    if (else_bb
        && ! cond_exec_process_insns (else_start, else_end,
! 				    true_expr, true_prob_val, TRUE))
      goto fail;
  
    if (! apply_change_group ())
*************** dead_or_predicable (test_bb, merge_bb, o
*** 1792,1806 ****
  	 All that's left is making sure the insns involved can actually
  	 be predicated.  */
  
!       rtx cond;
  
        cond = cond_exec_get_condition (jump);
        if (reversep)
! 	cond = gen_rtx_fmt_ee (reverse_condition (GET_CODE (cond)),
! 			       GET_MODE (cond), XEXP (cond, 0),
! 			       XEXP (cond, 1));
  
!       if (! cond_exec_process_insns (head, end, cond, 0))
  	goto cancel;
  
        earliest = jump;
--- 1809,1832 ----
  	 All that's left is making sure the insns involved can actually
  	 be predicated.  */
  
!       rtx cond, prob_val;
  
        cond = cond_exec_get_condition (jump);
+ 
+       prob_val = find_reg_note (jump, REG_BR_PROB, NULL_RTX);
+       if (prob_val)
+ 	prob_val = XEXP (prob_val, 0);
+ 
        if (reversep)
! 	{
! 	  cond = gen_rtx_fmt_ee (reverse_condition (GET_CODE (cond)),
! 			         GET_MODE (cond), XEXP (cond, 0),
! 			         XEXP (cond, 1));
! 	  if (prob_val)
! 	    prob_val = GEN_INT (REG_BR_PROB_BASE - INTVAL (prob_val));
! 	}
  
!       if (! cond_exec_process_insns (head, end, cond, prob_val, 0))
  	goto cancel;
  
        earliest = jump;


More information about the Gcc-patches mailing list