estimate_probabilities patch
Richard Henderson
rth@cygnus.com
Sat Apr 22 12:19:00 GMT 2000
Expands on Zack's recent patch so that we test both sides of
a branch. Currently we'd mispredict
int f(int p)
{
int x;
if (!p)
x = bar();
else
abort ();
return x;
}
Also, use 90% instead of 50% for "predict taken".
r~
* predict.c (estimate_probability): Examine both sides of
a branch for no exits. Use 90% not 50% for predict taken.
Reorg for one copy of note generation code.
Index: predict.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/predict.c,v
retrieving revision 1.7
diff -c -p -d -r1.7 predict.c
*** predict.c 2000/04/22 18:34:59 1.7
--- predict.c 2000/04/22 19:03:47
*************** estimate_probability (loops_info)
*** 103,136 ****
{
rtx last_insn = BLOCK_END (i);
rtx cond, earliest;
! int prob = 0;
edge e;
if (GET_CODE (last_insn) != JUMP_INSN
|| ! condjump_p (last_insn) || simplejump_p (last_insn))
continue;
if (find_reg_note (last_insn, REG_BR_PROB, 0))
continue;
cond = get_condition (last_insn, &earliest);
if (! cond)
continue;
! /* If the jump branches around a block with no successors,
! predict it to be taken. */
! prob = 0;
for (e = BASIC_BLOCK (i)->succ; e; e = e->succ_next)
! if ((e->flags & EDGE_FALLTHRU) && e->dest->succ == NULL)
{
! prob = REG_BR_PROB_BASE;
! break;
}
- if (prob)
- {
- REG_NOTES (last_insn)
- = gen_rtx_EXPR_LIST (REG_BR_PROB, GEN_INT (prob),
- REG_NOTES (last_insn));
- continue;
- }
/* Try "pointer heuristic."
A comparison ptr == 0 is predicted as false.
--- 103,134 ----
{
rtx last_insn = BLOCK_END (i);
rtx cond, earliest;
! int prob;
edge e;
if (GET_CODE (last_insn) != JUMP_INSN
|| ! condjump_p (last_insn) || simplejump_p (last_insn))
continue;
+
if (find_reg_note (last_insn, REG_BR_PROB, 0))
continue;
+
cond = get_condition (last_insn, &earliest);
if (! cond)
continue;
! /* If one of the successor blocks has no successors, predict
! that side not taken. */
! /* ??? Ought to do the same for any subgraph with no exit. */
for (e = BASIC_BLOCK (i)->succ; e; e = e->succ_next)
! if (e->dest->succ == NULL)
{
! if (e->flags & EDGE_FALLTHRU)
! prob = REG_BR_PROB_BASE;
! else
! prob = 0;
! goto emitnote;
}
/* Try "pointer heuristic."
A comparison ptr == 0 is predicted as false.
*************** estimate_probability (loops_info)
*** 143,149 ****
&& (XEXP (cond, 1) == const0_rtx
|| (GET_CODE (XEXP (cond, 1)) == REG
&& REGNO_POINTER_FLAG (REGNO (XEXP (cond, 1))))))
! prob = REG_BR_PROB_BASE / 10;
break;
case NE:
if (GET_CODE (XEXP (cond, 0)) == REG
--- 141,150 ----
&& (XEXP (cond, 1) == const0_rtx
|| (GET_CODE (XEXP (cond, 1)) == REG
&& REGNO_POINTER_FLAG (REGNO (XEXP (cond, 1))))))
! {
! prob = REG_BR_PROB_BASE / 10;
! goto emitnote;
! }
break;
case NE:
if (GET_CODE (XEXP (cond, 0)) == REG
*************** estimate_probability (loops_info)
*** 151,167 ****
&& (XEXP (cond, 1) == const0_rtx
|| (GET_CODE (XEXP (cond, 1)) == REG
&& REGNO_POINTER_FLAG (REGNO (XEXP (cond, 1))))))
! prob = REG_BR_PROB_BASE / 2;
break;
default:
! prob = 0;
! }
! if (prob)
! {
! REG_NOTES (last_insn)
! = gen_rtx_EXPR_LIST (REG_BR_PROB, GEN_INT (prob),
! REG_NOTES (last_insn));
! continue;
}
/* Try "opcode heuristic."
--- 152,165 ----
&& (XEXP (cond, 1) == const0_rtx
|| (GET_CODE (XEXP (cond, 1)) == REG
&& REGNO_POINTER_FLAG (REGNO (XEXP (cond, 1))))))
! {
! prob = REG_BR_PROB_BASE - (REG_BR_PROB_BASE / 10);
! goto emitnote;
! }
break;
+
default:
! break;
}
/* Try "opcode heuristic."
*************** estimate_probability (loops_info)
*** 172,201 ****
{
case CONST_INT:
/* Unconditional branch. */
! prob = REG_BR_PROB_BASE / 2;
! break;
case EQ:
prob = REG_BR_PROB_BASE / 10;
! break;
case NE:
! prob = REG_BR_PROB_BASE / 2;
! break;
case LE:
case LT:
if (XEXP (cond, 1) == const0_rtx)
! prob = REG_BR_PROB_BASE / 10;
break;
case GE:
case GT:
if (XEXP (cond, 1) == const0_rtx
|| (GET_CODE (XEXP (cond, 1)) == CONST_INT
&& INTVAL (XEXP (cond, 1)) == -1))
! prob = REG_BR_PROB_BASE / 2;
break;
default:
! prob = 0;
}
REG_NOTES (last_insn)
= gen_rtx_EXPR_LIST (REG_BR_PROB, GEN_INT (prob),
REG_NOTES (last_insn));
--- 170,211 ----
{
case CONST_INT:
/* Unconditional branch. */
! prob = (cond == const0_rtx ? 0 : REG_BR_PROB_BASE);
! goto emitnote;
!
case EQ:
prob = REG_BR_PROB_BASE / 10;
! goto emitnote;
case NE:
! prob = REG_BR_PROB_BASE - (REG_BR_PROB_BASE / 10);
! goto emitnote;
case LE:
case LT:
if (XEXP (cond, 1) == const0_rtx)
! {
! prob = REG_BR_PROB_BASE / 10;
! goto emitnote;
! }
break;
case GE:
case GT:
if (XEXP (cond, 1) == const0_rtx
|| (GET_CODE (XEXP (cond, 1)) == CONST_INT
&& INTVAL (XEXP (cond, 1)) == -1))
! {
! prob = REG_BR_PROB_BASE - (REG_BR_PROB_BASE / 10);
! goto emitnote;
! }
break;
default:
! break;
}
+
+ /* If we havn't chosen something by now, predict 50-50. */
+ prob = REG_BR_PROB_BASE / 2;
+
+ emitnote:
REG_NOTES (last_insn)
= gen_rtx_EXPR_LIST (REG_BR_PROB, GEN_INT (prob),
REG_NOTES (last_insn));
More information about the Gcc-patches
mailing list