aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2001-06-10 00:39:25 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2001-06-09 22:39:25 +0000
commit4db384c950ec85ca96e4bcaf7b00c36f2f6ccbd5 (patch)
treec28f4818b4bed04584e0f35d196aab217d30a449 /gcc
parent5bb8dd28b87e7894d3dd5e03eacb09b975bbf0ca (diff)
downloadgcc-4db384c950ec85ca96e4bcaf7b00c36f2f6ccbd5.zip
gcc-4db384c950ec85ca96e4bcaf7b00c36f2f6ccbd5.tar.gz
gcc-4db384c950ec85ca96e4bcaf7b00c36f2f6ccbd5.tar.bz2
predict.def: New file.
* predict.def: New file. * predict.h: New file. * predict.c: Include predict.h. (predictor_info): New structure and array. (predict_edge, predict_insn): Rewrite; make global. (predict_edge_def, predict_insn_def): New global functions. (dump_prediction, combine_predictions_for_insns): New static functions. (estimate_probability): Change calls to predict_edge to predict_edge_def and calls to predict_insn to predict_insn_def; combine probabilities. (expected_value_to_br_prob): Behave as predictor. * rtl.h (REG_BR_PRED): Update coment. (invert_br_probabilities): New. * jump.c: Include predict.h (duplicate_loop_exit_test): Drop branch prediction notes. (invert_jump): Use invert_br_probabilities. * Makefile.in: Add dependancy on predict.h for jump and predict pass. * ifcvt.c (dead_or_predicable): Use invert_br_probabilities. * combine.c (distribute_notes): Handle BR_PRED. From-SVN: r43115
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog23
-rw-r--r--gcc/Makefile.in5
-rw-r--r--gcc/combine.c1
-rw-r--r--gcc/ifcvt.c6
-rw-r--r--gcc/jump.c26
-rw-r--r--gcc/predict.c208
-rw-r--r--gcc/predict.def47
-rw-r--r--gcc/predict.h46
-rw-r--r--gcc/rtl.h18
9 files changed, 325 insertions, 55 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 166a4b3..d38b78a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,26 @@
+Sun Jun 10 00:35:37 CEST 2001 Jan Hubicka <jh@suse.cz>
+
+ * predict.def: New file.
+ * predict.h: New file.
+ * predict.c: Include predict.h.
+ (predictor_info): New structure and array.
+ (predict_edge, predict_insn): Rewrite; make global.
+ (predict_edge_def, predict_insn_def): New global functions.
+ (dump_prediction, combine_predictions_for_insns): New
+ static functions.
+ (estimate_probability): Change calls to predict_edge
+ to predict_edge_def and calls to predict_insn to predict_insn_def;
+ combine probabilities.
+ (expected_value_to_br_prob): Behave as predictor.
+ * rtl.h (REG_BR_PRED): Update coment.
+ (invert_br_probabilities): New.
+ * jump.c: Include predict.h
+ (duplicate_loop_exit_test): Drop branch prediction notes.
+ (invert_jump): Use invert_br_probabilities.
+ * Makefile.in: Add dependancy on predict.h for jump and predict pass.
+ * ifcvt.c (dead_or_predicable): Use invert_br_probabilities.
+ * combine.c (distribute_notes): Handle BR_PRED.
+
Sat Jun 9 23:29:41 CEST 2001 Jan Hubicka <jh@suse.cz>
* predict.c (predict_insn, predict_edge): New static functions.
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 0c94050..c3ff713 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -572,6 +572,7 @@ INSN_ATTR_H = insn-attr.h $(srcdir)/insn-addr.h $(srcdir)/varray.h
C_COMMON_H = c-common.h $(SPLAY_TREE_H)
C_TREE_H = c-tree.h $(C_COMMON_H)
SYSTEM_H = system.h hwint.h $(srcdir)/../include/libiberty.h
+PREDICT_H = predict.h predict.def
# sed inserts variable overrides after the following line.
####target overrides
@@ -1403,7 +1404,7 @@ integrate.o : integrate.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \
params.h $(TM_P_H)
jump.o : jump.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h hard-reg-set.h $(REGS_H) \
insn-config.h $(RECOG_H) $(EXPR_H) real.h except.h function.h \
- toplev.h $(INSN_ATTR_H) $(TM_P_H) reload.h
+ toplev.h $(INSN_ATTR_H) $(TM_P_H) reload.h $(PREDICT_H)
simplify-rtx.o : simplify-rtx.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(REGS_H) \
hard-reg-set.h flags.h real.h insn-config.h $(RECOG_H) $(EXPR_H) toplev.h \
@@ -1509,7 +1510,7 @@ reg-stack.o : reg-stack.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) $(RECOG_H)
varray.h function.h $(TM_P_H)
predict.o: predict.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \
insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h \
- $(RECOG_H) function.h except.h $(EXPR_H) $(TM_P_H)
+ $(RECOG_H) function.h except.h $(EXPR_H) $(TM_P_H) $(PREDICT_H)
lists.o: lists.c $(CONFIG_H) $(SYSTEM_H) toplev.h $(RTL_H) $(GGC_H)
bb-reorder.o : bb-reorder.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \
insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h \
diff --git a/gcc/combine.c b/gcc/combine.c
index d3c70c3..a9ad710 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -11952,6 +11952,7 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
switch (REG_NOTE_KIND (note))
{
case REG_BR_PROB:
+ case REG_BR_PRED:
case REG_EXEC_COUNT:
/* Doesn't matter much where we put this, as long as it's somewhere.
It is preferable to keep these notes on branches, which is most
diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c
index b57cb13..4e3c43e 100644
--- a/gcc/ifcvt.c
+++ b/gcc/ifcvt.c
@@ -2410,11 +2410,7 @@ dead_or_predicable (test_bb, merge_bb, other_bb, new_dest, reversep)
JUMP_LABEL (jump) = new_dest;
if (reversep)
- {
- rtx note = find_reg_note (jump, REG_BR_PROB, NULL_RTX);
- if (note)
- XEXP (note, 0) = GEN_INT (REG_BR_PROB_BASE - INTVAL (XEXP (note, 0)));
- }
+ invert_br_probabilities (jump);
/* Move the insns out of MERGE_BB to before the branch. */
if (head != NULL)
diff --git a/gcc/jump.c b/gcc/jump.c
index feb7b4d..067b7aa 100644
--- a/gcc/jump.c
+++ b/gcc/jump.c
@@ -67,6 +67,7 @@ Boston, MA 02111-1307, USA. */
#include "except.h"
#include "toplev.h"
#include "reload.h"
+#include "predict.h"
/* ??? Eventually must record somehow the labels used by jumps
from nested functions. */
@@ -1248,6 +1249,23 @@ duplicate_loop_exit_test (loop_start)
replace_regs (REG_NOTES (copy), reg_map, max_reg, 1);
}
+ /* Predict conditional jump that do make loop looping as taken.
+ Other jumps are probably exit conditions, so predict
+ them as untaken. */
+ if (any_condjump_p (copy))
+ {
+ rtx label = JUMP_LABEL (copy);
+ if (label)
+ {
+ if (PREV_INSN (label)
+ && GET_CODE (PREV_INSN (label)) == NOTE
+ && (NOTE_LINE_NUMBER (PREV_INSN (label))
+ == NOTE_INSN_LOOP_CONT))
+ predict_insn_def (copy, PRED_LOOP_HEADER, TAKEN);
+ else
+ predict_insn_def (copy, PRED_LOOP_HEADER, NOT_TAKEN);
+ }
+ }
/* If this is a simple jump, add it to the jump chain. */
if (INSN_UID (copy) < max_jump_chain && JUMP_LABEL (copy)
@@ -3351,13 +3369,7 @@ invert_jump (jump, nlabel, delete_unused)
if (redirect_jump (jump, nlabel, delete_unused))
{
- /* An inverted jump means that a probability taken becomes a
- probability not taken. Subtract the branch probability from the
- probability base to convert it back to a taken probability. */
-
- rtx note = find_reg_note (jump, REG_BR_PROB, NULL_RTX);
- if (note)
- XEXP (note, 0) = GEN_INT (REG_BR_PROB_BASE - INTVAL (XEXP (note, 0)));
+ invert_br_probabilities (jump);
return 1;
}
diff --git a/gcc/predict.c b/gcc/predict.c
index 68b5b7c..d4210e0 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -46,7 +46,7 @@
#include "toplev.h"
#include "recog.h"
#include "expr.h"
-
+#include "predict.h"
/* Random guesstimation given names. */
#define PROB_NEVER (0)
@@ -57,34 +57,63 @@
#define PROB_VERY_LIKELY (REG_BR_PROB_BASE - PROB_VERY_UNLIKELY)
#define PROB_ALWAYS (REG_BR_PROB_BASE)
-static void predict_insn PARAMS ((rtx, int));
-static void predict_edge PARAMS ((edge, int));
+static void combine_predictions_for_insn PARAMS ((rtx, basic_block));
+static void dump_prediction PARAMS ((enum br_predictor, int,
+ basic_block));
-static void
-predict_insn (insn, probability)
- rtx insn;
- int probability;
+/* Information we hold about each branch predictor.
+ Filled using information from predict.def. */
+struct predictor_info
{
- rtx note = find_reg_note (insn, REG_BR_PROB, 0);
+ const char *name; /* Name used in the debugging dumps. */
+ int hitrate; /* Expected hitrate used by
+ predict_insn_def call. */
+};
- /* 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;
+#define DEF_PREDICTOR(ENUM, NAME, HITRATE) {NAME, HITRATE},
+struct predictor_info predictor_info[] = {
+#include "predict.def"
+
+ /* Upper bound on non-language-specific builtins. */
+ {NULL, 0}
+};
+#undef DEF_PREDICTOR
+void
+predict_insn (insn, predictor, probability)
+ rtx insn;
+ int probability;
+ enum br_predictor predictor;
+{
if (!any_condjump_p (insn))
abort ();
REG_NOTES (insn)
- = gen_rtx_EXPR_LIST (REG_BR_PROB,
- GEN_INT (probability), REG_NOTES (insn));
+ = gen_rtx_EXPR_LIST (REG_BR_PRED,
+ gen_rtx_CONCAT (VOIDmode,
+ GEN_INT ((int) predictor),
+ GEN_INT ((int) probability)),
+ REG_NOTES (insn));
+}
+
+/* Predict insn by given predictor. */
+void
+predict_insn_def (insn, predictor, taken)
+ rtx insn;
+ enum br_predictor predictor;
+ enum prediction taken;
+{
+ int probability = predictor_info[(int) predictor].hitrate;
+ if (taken != TAKEN)
+ probability = REG_BR_PROB_BASE - probability;
+ predict_insn (insn, predictor, probability);
}
/* Predict edge E with given probability if possible. */
-static void
-predict_edge (e, probability)
+void
+predict_edge (e, predictor, probability)
edge e;
int probability;
+ enum br_predictor predictor;
{
rtx last_insn;
last_insn = e->src->end;
@@ -98,7 +127,107 @@ predict_edge (e, probability)
if (e->flags & EDGE_FALLTHRU)
probability = REG_BR_PROB_BASE - probability;
- predict_insn (last_insn, probability);
+ predict_insn (last_insn, predictor, probability);
+}
+
+/* Predict edge E by given predictor if possible. */
+void
+predict_edge_def (e, predictor, taken)
+ edge e;
+ enum br_predictor predictor;
+ enum prediction taken;
+{
+ int probability = predictor_info[(int) predictor].hitrate;
+
+ if (taken != TAKEN)
+ probability = REG_BR_PROB_BASE - probability;
+ predict_edge (e, predictor, probability);
+}
+
+/* Invert all branch predictions or probability notes in the INSN. This needs
+ to be done each time we invert the condition used by the jump. */
+void
+invert_br_probabilities (insn)
+ rtx insn;
+{
+ rtx note = REG_NOTES (insn);
+
+ while (note)
+ {
+ if (REG_NOTE_KIND (note) == REG_BR_PROB)
+ XEXP (note, 0) = GEN_INT (REG_BR_PROB_BASE - INTVAL (XEXP (note, 0)));
+ else if (REG_NOTE_KIND (note) == REG_BR_PRED)
+ XEXP (XEXP (note, 0), 1)
+ = GEN_INT (REG_BR_PROB_BASE - INTVAL (XEXP (XEXP (note, 0), 1)));
+ note = XEXP (note, 1);
+ }
+}
+
+/* Dump information about the branch prediction to the output file. */
+static void
+dump_prediction (predictor, probability, bb)
+ enum br_predictor predictor;
+ int probability;
+ basic_block bb;
+{
+ edge e = bb->succ;
+
+ if (!rtl_dump_file)
+ return;
+
+ while (e->flags & EDGE_FALLTHRU)
+ e = e->succ_next;
+
+ fprintf (rtl_dump_file, " %s heuristics: %.1f%%",
+ predictor_info[predictor].name,
+ probability * 100.0 / REG_BR_PROB_BASE);
+
+ if (bb->count)
+ fprintf (rtl_dump_file, " exec %i hit %i (%.1f%%)",
+ bb->count, e->count, e->count * 100.0 / bb->count);
+ fprintf (rtl_dump_file, "\n");
+}
+
+/* Combine all REG_BR_PRED notes into single probability and attach REG_BR_PROB
+ note if not already present. Remove now useless REG_BR_PRED notes. */
+static void
+combine_predictions_for_insn (insn, bb)
+ rtx insn;
+ basic_block bb;
+{
+ rtx prob_note = find_reg_note (insn, REG_BR_PROB, 0);
+ rtx *pnote = &REG_NOTES (insn);
+ int best_probability = PROB_EVEN;
+ int best_predictor = END_PREDICTORS;
+
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, "Predictions for insn %i\n", INSN_UID (insn));
+
+ /* We implement "first match" heuristics and use probability guessed
+ by predictor with smallest index. In future we will use better
+ probability combination techniques. */
+ while (*pnote)
+ {
+ rtx *next_pnote = &XEXP (*pnote, 1);
+ if (REG_NOTE_KIND (*pnote) == REG_BR_PRED)
+ {
+ int predictor = INTVAL (XEXP (XEXP (*pnote, 0), 0));
+ int probability = INTVAL (XEXP (XEXP (*pnote, 0), 1));
+
+ dump_prediction (predictor, probability, bb);
+ if (best_predictor > predictor)
+ best_probability = probability, best_predictor = predictor;
+ *pnote = XEXP (*pnote, 1);
+ }
+ pnote = next_pnote;
+ }
+ dump_prediction (PRED_FIRST_MATCH, best_probability, bb);
+ if (!prob_note)
+ {
+ REG_NOTES (insn)
+ = gen_rtx_EXPR_LIST (REG_BR_PROB,
+ GEN_INT (best_probability), REG_NOTES (insn));
+ }
}
/* Statically estimate the probability that a branch will be taken.
@@ -134,7 +263,7 @@ estimate_probability (loops_info)
if (e->dest == loops_info->array[i].header)
{
header_found = 1;
- predict_edge (e, PROB_VERY_LIKELY);
+ predict_edge_def (e, PRED_LOOP_BRANCH, TAKEN);
}
/* Loop exit heruistics - predict as not taken an edge exiting
the loop if the conditinal has no loop header successors */
@@ -142,7 +271,7 @@ estimate_probability (loops_info)
for (e = BASIC_BLOCK(j)->succ; e; e = e->succ_next)
if (e->dest->index <= 0
|| !TEST_BIT (loops_info->array[i].nodes, e->dest->index))
- predict_edge (e, PROB_UNLIKELY);
+ predict_edge_def (e, PRED_LOOP_EXIT, NOT_TAKEN);
}
}
}
@@ -169,7 +298,7 @@ estimate_probability (loops_info)
/* ??? 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)
- predict_edge (e, PROB_NEVER);
+ predict_edge_def (e, PRED_NORETURN, NOT_TAKEN);
cond = get_condition (last_insn, &earliest);
if (! cond)
@@ -187,7 +316,7 @@ estimate_probability (loops_info)
|| (GET_CODE (XEXP (cond, 1)) == REG
&& REG_POINTER (XEXP (cond, 1)))))
- predict_insn (last_insn, PROB_UNLIKELY);
+ predict_insn_def (last_insn, PRED_POINTER, NOT_TAKEN);
break;
case NE:
if (GET_CODE (XEXP (cond, 0)) == REG
@@ -195,7 +324,7 @@ estimate_probability (loops_info)
&& (XEXP (cond, 1) == const0_rtx
|| (GET_CODE (XEXP (cond, 1)) == REG
&& REG_POINTER (XEXP (cond, 1)))))
- predict_insn (last_insn, PROB_LIKELY);
+ predict_insn_def (last_insn, PRED_POINTER, TAKEN);
break;
default:
@@ -210,41 +339,52 @@ estimate_probability (loops_info)
{
case CONST_INT:
/* Unconditional branch. */
- predict_insn (last_insn,
- cond == const0_rtx ? PROB_NEVER : PROB_ALWAYS);
+ predict_insn_def (last_insn, PRED_UNCONDITIONAL,
+ cond == const0_rtx ? NOT_TAKEN : TAKEN);
break;
case EQ:
case UNEQ:
- predict_insn (last_insn, PROB_UNLIKELY);
+ predict_insn_def (last_insn, PRED_OPCODE, NOT_TAKEN);
break;
case NE:
case LTGT:
- predict_insn (last_insn, PROB_LIKELY);
+ predict_insn_def (last_insn, PRED_OPCODE, TAKEN);
break;
case ORDERED:
- predict_insn (last_insn, PROB_LIKELY);
+ predict_insn_def (last_insn, PRED_OPCODE, TAKEN);
break;
case UNORDERED:
- predict_insn (last_insn, PROB_UNLIKELY);
+ predict_insn_def (last_insn, PRED_OPCODE, NOT_TAKEN);
break;
case LE:
case LT:
if (XEXP (cond, 1) == const0_rtx)
- predict_insn (last_insn, PROB_UNLIKELY);
+ 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 (last_insn, PROB_LIKELY);
+ predict_insn_def (last_insn, PRED_OPCODE, TAKEN);
break;
default:
break;
}
}
+
+ /* Attach the combined probability to each conditional jump. */
+ for (i = 0; i < n_basic_blocks - 1; i++)
+ {
+ rtx last_insn = BLOCK_END (i);
+
+ if (GET_CODE (last_insn) != JUMP_INSN
+ || ! any_condjump_p (last_insn))
+ continue;
+ combine_predictions_for_insn (last_insn, BASIC_BLOCK (i));
+ }
}
/* __builtin_expect dropped tokens into the insn stream describing
@@ -285,7 +425,7 @@ expected_value_to_br_prob ()
expected value yet, no point going further. */
if (GET_CODE (insn) != JUMP_INSN || ev == NULL_RTX)
continue;
- if (! condjump_p (insn) || simplejump_p (insn))
+ if (! any_condjump_p (insn))
continue;
break;
}
@@ -316,7 +456,7 @@ expected_value_to_br_prob ()
/* Turn the condition into a scaled branch probability. */
if (cond != const1_rtx && cond != const0_rtx)
abort ();
- predict_insn (insn,
- cond == const1_rtx ? PROB_VERY_LIKELY : PROB_VERY_UNLIKELY);
+ predict_insn_def (insn, PRED_BUILTIN_EXPECT,
+ cond == const1_rtx ? TAKEN : NOT_TAKEN);
}
}
diff --git a/gcc/predict.def b/gcc/predict.def
new file mode 100644
index 0000000..ce0fbbd
--- /dev/null
+++ b/gcc/predict.def
@@ -0,0 +1,47 @@
+/* This file contains the definitions and documentation for the
+ builtins used in the GNU compiler.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* Before including this file, you should define a macro:
+
+ DEF_PREDICTOR (ENUM, NAME, HITRATE)
+
+ This macro will be called once for each predictor. The ENUM will
+ be of type `enum predictor', and will enumerate all supported
+ predictors. The order of DEF_PREDICTOR calls is important, as
+ in the first match combining heuristics, the predictor appearing
+ first in this file will win.
+
+ NAME is used in the debugging output to determine predictor type.
+
+ HITRATE is the probability that edge predicted by predictor as taken
+ will be really taken (so it should be always above
+ REG_BR_PROB_BASE / 2). */
+
+
+DEF_PREDICTOR (PRED_FIRST_MATCH, "first match", PROB_ALWAYS)
+DEF_PREDICTOR (PRED_UNCONDITIONAL, "unconditional jump", PROB_ALWAYS)
+DEF_PREDICTOR (PRED_BUILTIN_EXPECT, "__builtin_expect", PROB_VERY_LIKELY)
+DEF_PREDICTOR (PRED_NORETURN, "noreturn call", PROB_ALWAYS)
+DEF_PREDICTOR (PRED_LOOP_BRANCH, "loop branch", PROB_VERY_LIKELY)
+DEF_PREDICTOR (PRED_LOOP_EXIT, "loop exit", PROB_LIKELY)
+DEF_PREDICTOR (PRED_LOOP_HEADER, "loop header", PROB_LIKELY)
+DEF_PREDICTOR (PRED_POINTER, "pointer", PROB_LIKELY)
+DEF_PREDICTOR (PRED_OPCODE, "opcode", PROB_LIKELY)
diff --git a/gcc/predict.h b/gcc/predict.h
new file mode 100644
index 0000000..3cc52de
--- /dev/null
+++ b/gcc/predict.h
@@ -0,0 +1,46 @@
+/* This file contains the definitions and documentation for the
+ builtins used in the GNU compiler.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#define DEF_PREDICTOR(ENUM, NAME, HITRATE) ENUM,
+enum br_predictor
+{
+#include "predict.def"
+
+ /* Upper bound on non-language-specific builtins. */
+ END_PREDICTORS
+};
+#undef DEF_PREDICTOR
+enum prediction
+{
+ NOT_TAKEN,
+ TAKEN
+};
+
+extern void predict_insn_def PARAMS ((rtx, enum br_predictor,
+ enum prediction));
+extern void predict_insn PARAMS ((rtx, enum br_predictor, int));
+
+/* Avoid unneeded dependancy on basic_block.h */
+#ifdef BASIC_BLOCK
+extern void predict_edge PARAMS ((edge, enum br_predictor, int));
+extern void predict_edge_def PARAMS ((edge, enum br_predictor,
+ enum prediction));
+#endif
diff --git a/gcc/rtl.h b/gcc/rtl.h
index 1cc0d73..32c22ec 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -497,10 +497,10 @@ enum reg_note
flow, are represented by a 0 reg note kind. */
REG_DEP_ANTI, REG_DEP_OUTPUT,
- /* REG_BR_PROB is attached to JUMP_INSNs and CALL_INSNs when the flag
- -fbranch-probabilities is given. It has an integer value. For jumps,
- it is the probability that this is a taken branch. For calls, it is
- the probability that this call won't return. */
+ /* REG_BR_PROB is attached to JUMP_INSNs and CALL_INSNs.
+ It has an integer value. For jumps, it is the probability that this is a
+ taken branch. For calls, it is the probability that this call won't
+ return. */
REG_BR_PROB,
/* REG_EXEC_COUNT is attached to the first insn of each basic block, and
@@ -516,8 +516,10 @@ enum reg_note
where SETJMP_VIA_SAVE_AREA is true. */
REG_SAVE_AREA,
- /* Attached to JUMP_INSNs only, it holds the branch prediction flags
- computed by get_jump_flags() after dbr scheduling is complete. */
+ /* REG_BR_PRED is attached to JUMP_INSNs and CALL_INSNSs. It contains
+ CONCAT of two integer value. First specifies the branch predictor
+ that added the note, second specifies the predicted hitrate of branch
+ in the same format as REG_BR_PROB note uses. */
REG_BR_PRED,
/* Attached to insns that are RTX_FRAME_RELATED_P, but are too complex
@@ -2020,7 +2022,9 @@ extern rtx stack_limit_rtx;
/* In regrename.c */
extern void regrename_optimize PARAMS ((void));
-/* In condexec.c */
+/* In ifcvt.c */
extern void if_convert PARAMS ((int));
+/* In predict.c */
+extern void invert_br_probabilities PARAMS ((rtx));
#endif /* ! GCC_RTL_H */