Commit ee92cb46 by Jan Hubicka Committed by Jan Hubicka

predict.c (predict_insn, [...]): New static functions.

	* predict.c (predict_insn, predict_edge): New static functions.
	(estimate_probability): Revamp to use new functions;
	fix loop header heruistics; add loop exist heruistics

From-SVN: r43109
parent 9dd7e9cf
Sat Jun 9 23:29:41 CEST 2001 Jan Hubicka <jh@suse.cz>
* predict.c (predict_insn, predict_edge): New static functions.
(estimate_probability): Revamp to use new functions;
fix loop header heruistics; add loop exist heruistics
2001-06-09 Alexandre Oliva <aoliva@redhat.com> 2001-06-09 Alexandre Oliva <aoliva@redhat.com>
* config.gcc: Re-enable bi-arch sparc on Solaris 7 and above. * config.gcc: Re-enable bi-arch sparc on Solaris 7 and above.
......
...@@ -57,6 +57,50 @@ ...@@ -57,6 +57,50 @@
#define PROB_VERY_LIKELY (REG_BR_PROB_BASE - PROB_VERY_UNLIKELY) #define PROB_VERY_LIKELY (REG_BR_PROB_BASE - PROB_VERY_UNLIKELY)
#define PROB_ALWAYS (REG_BR_PROB_BASE) #define PROB_ALWAYS (REG_BR_PROB_BASE)
static void predict_insn PARAMS ((rtx, int));
static void predict_edge PARAMS ((edge, int));
static void
predict_insn (insn, probability)
rtx insn;
int probability;
{
rtx note = find_reg_note (insn, REG_BR_PROB, 0);
/* Implement "first match" heruistics. In case we already predicted
insn somehow, keep it predicted that way. In future we would like
to rather store all predictions and then combine them. */
if (note)
return;
if (!any_condjump_p (insn))
abort ();
REG_NOTES (insn)
= gen_rtx_EXPR_LIST (REG_BR_PROB,
GEN_INT (probability), REG_NOTES (insn));
}
/* Predict edge E with given probability if possible. */
static void
predict_edge (e, probability)
edge e;
int probability;
{
rtx last_insn;
last_insn = e->src->end;
/* We can store the branch prediction information only about
conditional jumps. */
if (!any_condjump_p (last_insn))
return;
/* We always store probability of branching. */
if (e->flags & EDGE_FALLTHRU)
probability = REG_BR_PROB_BASE - probability;
predict_insn (last_insn, probability);
}
/* Statically estimate the probability that a branch will be taken. /* Statically estimate the probability that a branch will be taken.
??? In the next revision there will be a number of other predictors added ??? In the next revision there will be a number of other predictors added
from the above references. Further, each heuristic will be factored out from the above references. Further, each heuristic will be factored out
...@@ -79,26 +123,26 @@ estimate_probability (loops_info) ...@@ -79,26 +123,26 @@ estimate_probability (loops_info)
j <= loops_info->array[i].last->index; j <= loops_info->array[i].last->index;
++j) ++j)
{ {
if (TEST_BIT (loops_info->array[i].nodes, j))
{
int header_found = 0;
edge e; edge e;
if (! TEST_BIT (loops_info->array[i].nodes, j)) /* Loop branch heruistics - predict as taken an edge back to
for (e = BASIC_BLOCK(j)->pred; e; e = e->pred_next) a loop's head. */
if (TEST_BIT (loops_info->array[i].nodes, e->src->index)) for (e = BASIC_BLOCK(j)->succ; e; e = e->succ_next)
if (e->dest == loops_info->array[i].header)
{ {
rtx last_insn = BLOCK_END (e->src->index); header_found = 1;
rtx cond, earliest; predict_edge (e, PROB_VERY_LIKELY);
}
if (GET_CODE (last_insn) != JUMP_INSN /* Loop exit heruistics - predict as not taken an edge exiting
|| ! condjump_p (last_insn) || simplejump_p (last_insn)) the loop if the conditinal has no loop header successors */
continue; if (!header_found)
cond = get_condition (last_insn, &earliest); for (e = BASIC_BLOCK(j)->succ; e; e = e->succ_next)
if (! cond) if (e->dest->index <= 0
continue; || !TEST_BIT (loops_info->array[i].nodes, e->dest->index))
if (! find_reg_note (last_insn, REG_BR_PROB, 0)) predict_edge (e, PROB_UNLIKELY);
REG_NOTES (last_insn)
= gen_rtx_EXPR_LIST (REG_BR_PROB,
GEN_INT (PROB_VERY_LIKELY),
REG_NOTES (last_insn));
} }
} }
} }
...@@ -111,32 +155,25 @@ estimate_probability (loops_info) ...@@ -111,32 +155,25 @@ estimate_probability (loops_info)
{ {
rtx last_insn = BLOCK_END (i); rtx last_insn = BLOCK_END (i);
rtx cond, earliest; rtx cond, earliest;
int prob;
edge e; edge e;
if (GET_CODE (last_insn) != JUMP_INSN if (GET_CODE (last_insn) != JUMP_INSN
|| ! condjump_p (last_insn) || simplejump_p (last_insn)) || ! any_condjump_p (last_insn))
continue; continue;
if (find_reg_note (last_insn, REG_BR_PROB, 0)) if (find_reg_note (last_insn, REG_BR_PROB, 0))
continue; continue;
cond = get_condition (last_insn, &earliest);
if (! cond)
continue;
/* If one of the successor blocks has no successors, predict /* If one of the successor blocks has no successors, predict
that side not taken. */ that side not taken. */
/* ??? Ought to do the same for any subgraph with no exit. */ /* ??? Ought to do the same for any subgraph with no exit. */
for (e = BASIC_BLOCK (i)->succ; e; e = e->succ_next) for (e = BASIC_BLOCK (i)->succ; e; e = e->succ_next)
if (e->dest->succ == NULL) if (e->dest->succ == NULL)
{ predict_edge (e, PROB_NEVER);
if (e->flags & EDGE_FALLTHRU)
prob = PROB_ALWAYS; cond = get_condition (last_insn, &earliest);
else if (! cond)
prob = PROB_NEVER; continue;
goto emitnote;
}
/* Try "pointer heuristic." /* Try "pointer heuristic."
A comparison ptr == 0 is predicted as false. A comparison ptr == 0 is predicted as false.
...@@ -149,10 +186,8 @@ estimate_probability (loops_info) ...@@ -149,10 +186,8 @@ estimate_probability (loops_info)
&& (XEXP (cond, 1) == const0_rtx && (XEXP (cond, 1) == const0_rtx
|| (GET_CODE (XEXP (cond, 1)) == REG || (GET_CODE (XEXP (cond, 1)) == REG
&& REG_POINTER (XEXP (cond, 1))))) && REG_POINTER (XEXP (cond, 1)))))
{
prob = PROB_UNLIKELY; predict_insn (last_insn, PROB_UNLIKELY);
goto emitnote;
}
break; break;
case NE: case NE:
if (GET_CODE (XEXP (cond, 0)) == REG if (GET_CODE (XEXP (cond, 0)) == REG
...@@ -160,10 +195,7 @@ estimate_probability (loops_info) ...@@ -160,10 +195,7 @@ estimate_probability (loops_info)
&& (XEXP (cond, 1) == const0_rtx && (XEXP (cond, 1) == const0_rtx
|| (GET_CODE (XEXP (cond, 1)) == REG || (GET_CODE (XEXP (cond, 1)) == REG
&& REG_POINTER (XEXP (cond, 1))))) && REG_POINTER (XEXP (cond, 1)))))
{ predict_insn (last_insn, PROB_LIKELY);
prob = PROB_LIKELY;
goto emitnote;
}
break; break;
default: default:
...@@ -178,53 +210,40 @@ estimate_probability (loops_info) ...@@ -178,53 +210,40 @@ estimate_probability (loops_info)
{ {
case CONST_INT: case CONST_INT:
/* Unconditional branch. */ /* Unconditional branch. */
prob = (cond == const0_rtx ? PROB_NEVER : PROB_ALWAYS); predict_insn (last_insn,
goto emitnote; cond == const0_rtx ? PROB_NEVER : PROB_ALWAYS);
break;
case EQ: case EQ:
case UNEQ: case UNEQ:
prob = PROB_UNLIKELY; predict_insn (last_insn, PROB_UNLIKELY);
goto emitnote; break;
case NE: case NE:
case LTGT: case LTGT:
prob = PROB_LIKELY; predict_insn (last_insn, PROB_LIKELY);
goto emitnote; break;
case ORDERED: case ORDERED:
prob = PROB_LIKELY; predict_insn (last_insn, PROB_LIKELY);
goto emitnote; break;
case UNORDERED: case UNORDERED:
prob = PROB_UNLIKELY; predict_insn (last_insn, PROB_UNLIKELY);
goto emitnote; break;
case LE: case LE:
case LT: case LT:
if (XEXP (cond, 1) == const0_rtx) if (XEXP (cond, 1) == const0_rtx)
{ predict_insn (last_insn, PROB_UNLIKELY);
prob = PROB_UNLIKELY;
goto emitnote;
}
break; break;
case GE: case GE:
case GT: case GT:
if (XEXP (cond, 1) == const0_rtx if (XEXP (cond, 1) == const0_rtx
|| (GET_CODE (XEXP (cond, 1)) == CONST_INT || (GET_CODE (XEXP (cond, 1)) == CONST_INT
&& INTVAL (XEXP (cond, 1)) == -1)) && INTVAL (XEXP (cond, 1)) == -1))
{ predict_insn (last_insn, PROB_LIKELY);
prob = PROB_LIKELY;
goto emitnote;
}
break; break;
default: default:
break; break;
} }
/* If we havn't chosen something by now, predict 50-50. */
prob = PROB_EVEN;
emitnote:
REG_NOTES (last_insn)
= gen_rtx_EXPR_LIST (REG_BR_PROB, GEN_INT (prob),
REG_NOTES (last_insn));
} }
} }
...@@ -295,12 +314,9 @@ expected_value_to_br_prob () ...@@ -295,12 +314,9 @@ expected_value_to_br_prob ()
cond = simplify_rtx (cond); cond = simplify_rtx (cond);
/* Turn the condition into a scaled branch probability. */ /* Turn the condition into a scaled branch probability. */
if (cond == const1_rtx) if (cond != const1_rtx && cond != const0_rtx)
cond = GEN_INT (PROB_VERY_LIKELY);
else if (cond == const0_rtx)
cond = GEN_INT (PROB_VERY_UNLIKELY);
else
abort (); abort ();
REG_NOTES (insn) = alloc_EXPR_LIST (REG_BR_PROB, cond, REG_NOTES (insn)); predict_insn (insn,
cond == const1_rtx ? PROB_VERY_LIKELY : PROB_VERY_UNLIKELY);
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment