aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2001-06-18 17:35:47 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2001-06-18 15:35:47 +0000
commit923cbdc322ee080c02b94a95eece0618a2a78b47 (patch)
tree0803743d2349ea46ce205c05df7cae76a3374b1f
parent049d2def48689b21149b6a7ad19c865e1d393627 (diff)
downloadgcc-923cbdc322ee080c02b94a95eece0618a2a78b47.zip
gcc-923cbdc322ee080c02b94a95eece0618a2a78b47.tar.gz
gcc-923cbdc322ee080c02b94a95eece0618a2a78b47.tar.bz2
unroll.c: Include predict.h.
* unroll.c: Include predict.h. (unroll_loop): Drop prediction notes on preconditioning. * predict.def (PRED_LOOP_PRECONDITIONG, PRED_LOOP_CONDITION): New; add comments on the others. * Makefile.in: (unroll.o): Add dependancy on predict.h. * loop.c (strength_reduce): Fix branch prediction. * stmt.c (emit_case_nodes): Optimize test whether index is in given interval. * predict.c (estimate_probability): Do not bail out early when note is present. (combine_predictions_for_insn): Fix note removal code. From-SVN: r43441
-rw-r--r--gcc/ChangeLog20
-rw-r--r--gcc/Makefile.in2
-rw-r--r--gcc/loop.c2
-rw-r--r--gcc/predict.c7
-rw-r--r--gcc/predict.def32
-rw-r--r--gcc/stmt.c24
-rw-r--r--gcc/unroll.c4
7 files changed, 82 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c45255a..51c11e7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,23 @@
+Mon Jun 18 17:27:24 CEST 2001 Jan Hubicka <jh@suse.cz>
+
+ * unroll.c: Include predict.h.
+ (unroll_loop): Drop prediction notes on preconditioning.
+ * predict.def (PRED_LOOP_PRECONDITIONG, PRED_LOOP_CONDITION):
+ New; add comments on the others.
+ * Makefile.in: (unroll.o): Add dependancy on predict.h.
+ * loop.c (strength_reduce): Fix branch prediction.
+
+Mon Jun 18 17:26:56 CEST 2001 Jan Hubicka <jh@suse.cz>
+
+ * stmt.c (emit_case_nodes): Optimize test whether index is in given
+ interval.
+
+Mon Jun 18 15:43:10 CEST 2001 Jan Hubicka <jh@suse.cz>
+
+ * predict.c (estimate_probability): Do not bail out early
+ when note is present.
+ (combine_predictions_for_insn): Fix note removal code.
+
2001-06-18 Ben Elliston <bje@redhat.com>
* except.c (resolve_fixup_regions): Initialise "cleanup".
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 6606cab..75b3dbc 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1450,7 +1450,7 @@ doloop.o : doloop.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h $(LOOP_H) \
$(EXPR_H) hard-reg-set.h $(BASIC_BLOCK_H) $(TM_P_H) toplev.h
unroll.o : unroll.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) insn-config.h function.h \
$(INTEGRATE_H) $(REGS_H) $(RECOG_H) flags.h $(EXPR_H) $(LOOP_H) toplev.h \
- hard-reg-set.h varray.h $(BASIC_BLOCK_H) $(TM_P_H)
+ hard-reg-set.h varray.h $(BASIC_BLOCK_H) $(TM_P_H) $(PREDICT_H)
flow.o : flow.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) ssa.h $(GGC_H) $(TM_P_H)
diff --git a/gcc/loop.c b/gcc/loop.c
index ec8dc0a..82f09f3 100644
--- a/gcc/loop.c
+++ b/gcc/loop.c
@@ -4505,7 +4505,7 @@ strength_reduce (loop, flags)
if ((flags & LOOP_BCT)
&& loop_info->n_iterations / loop_info->unroll_number > 1)
{
- int n = loop_info->n_iterations / loop_info->unroll_number - 1;
+ int n = loop_info->n_iterations / loop_info->unroll_number;
predict_insn (PREV_INSN (loop->end),
PRED_LOOP_ITERATIONS,
REG_BR_PROB_BASE - REG_BR_PROB_BASE / n);
diff --git a/gcc/predict.c b/gcc/predict.c
index 21c7149..38818cb 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -208,7 +208,6 @@ combine_predictions_for_insn (insn, bb)
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));
@@ -219,7 +218,8 @@ combine_predictions_for_insn (insn, bb)
best_probability = probability, best_predictor = predictor;
*pnote = XEXP (*pnote, 1);
}
- pnote = next_pnote;
+ else
+ pnote = &XEXP (*pnote, 1);
}
dump_prediction (PRED_FIRST_MATCH, best_probability, bb);
if (!prob_note)
@@ -313,9 +313,6 @@ estimate_probability (loops_info)
|| ! any_condjump_p (last_insn))
continue;
- if (find_reg_note (last_insn, REG_BR_PROB, 0))
- continue;
-
for (e = bb->succ; e; e = e->succ_next)
{
/* Predict edges to blocks that return immediately to be
diff --git a/gcc/predict.def b/gcc/predict.def
index 01d87a4..ff8171b 100644
--- a/gcc/predict.def
+++ b/gcc/predict.def
@@ -36,15 +36,47 @@ Boston, MA 02111-1307, USA. */
REG_BR_PROB_BASE / 2). */
+/* An combined heuristics using probability determined by first
+ matching heuristics from this list. */
DEF_PREDICTOR (PRED_FIRST_MATCH, "first match", PROB_ALWAYS)
+
+/* Mark unconditional jump as taken. */
DEF_PREDICTOR (PRED_UNCONDITIONAL, "unconditional jump", PROB_ALWAYS)
+
+/* Use number of loop iterations determined by loop unroller to set
+ probability. */
DEF_PREDICTOR (PRED_LOOP_ITERATIONS, "loop iterations", PROB_ALWAYS)
+
+/* Hints dropped by user via __builtin_expect feature. */
DEF_PREDICTOR (PRED_BUILTIN_EXPECT, "__builtin_expect", PROB_VERY_LIKELY)
+
+/* Branch to basic block containing call marked by noreturn attribute. */
DEF_PREDICTOR (PRED_NORETURN, "noreturn call", PROB_ALWAYS)
+
+/* Loopback edge is taken. */
DEF_PREDICTOR (PRED_LOOP_BRANCH, "loop branch", PROB_VERY_LIKELY)
+
+/* Edge causing loop to terminate is probably not taken. */
DEF_PREDICTOR (PRED_LOOP_EXIT, "loop exit", PROB_LIKELY)
+
+/* Condition emitted by preconditiong code to ensure that variable
+ setting number of iterations is greater than initial value of iterator. */
+DEF_PREDICTOR (PRED_LOOP_CONDITION, "loop condition", PROB_VERY_LIKELY)
+
+/* Preconditioning makes linear list of branches. */
+DEF_PREDICTOR (PRED_LOOP_PRECONDITIONING, "loop preconditioning", PROB_VERY_LIKELY)
+
+/* Copied condition for the first iteration of loop is probably true. */
DEF_PREDICTOR (PRED_LOOP_HEADER, "loop header", PROB_LIKELY)
+
+/* Pointers are usually not NULL. */
DEF_PREDICTOR (PRED_POINTER, "pointer", PROB_LIKELY)
+
+/* NE is probable, EQ not etc... */
DEF_PREDICTOR (PRED_OPCODE, "opcode", PROB_LIKELY)
+
+/* Branch guarding call is probably taken. */
DEF_PREDICTOR (PRED_CALL, "call", PROB_LIKELY)
+
+/* Branch causing function to terminate is probably not taken. */
DEF_PREDICTOR (PRED_ERROR_RETURN, "error return", PROB_LIKELY)
diff --git a/gcc/stmt.c b/gcc/stmt.c
index 3cefc7c..ee4523c 100644
--- a/gcc/stmt.c
+++ b/gcc/stmt.c
@@ -6293,8 +6293,10 @@ emit_case_nodes (index, node, default_label, index_type)
/* Node has no children so we check low and high bounds to remove
redundant tests. Only one of the bounds can exist,
since otherwise this node is bounded--a case tested already. */
+ int high_bound = node_has_high_bound (node, index_type);
+ int low_bound = node_has_low_bound (node, index_type);
- if (!node_has_high_bound (node, index_type))
+ if (!high_bound && low_bound)
{
emit_cmp_and_jump_insns (index,
convert_modes
@@ -6306,7 +6308,7 @@ emit_case_nodes (index, node, default_label, index_type)
default_label);
}
- if (!node_has_low_bound (node, index_type))
+ else if (!low_bound && high_bound)
{
emit_cmp_and_jump_insns (index,
convert_modes
@@ -6317,6 +6319,24 @@ emit_case_nodes (index, node, default_label, index_type)
LT, NULL_RTX, mode, unsignedp, 0,
default_label);
}
+ else if (!low_bound && !high_bound)
+ {
+ /* Instead of doing two branches emit test (index-low) <= (high-low). */
+ tree new_bound = fold (build (MINUS_EXPR, index_type, node->high,
+ node->low));
+ rtx new_index;
+
+ new_index = expand_binop (mode, sub_optab, index,
+ expand_expr (node->low, NULL_RTX,
+ VOIDmode, 0),
+ NULL_RTX, 0, OPTAB_WIDEN);
+
+ emit_cmp_and_jump_insns (new_index,
+ expand_expr (new_bound, NULL_RTX,
+ VOIDmode, 0),
+ GT, NULL_RTX, mode, 1, 0,
+ default_label);
+ }
emit_jump (label_rtx (node->code_label));
}
diff --git a/gcc/unroll.c b/gcc/unroll.c
index 94c58cd..9a09f5d 100644
--- a/gcc/unroll.c
+++ b/gcc/unroll.c
@@ -167,6 +167,7 @@ enum unroll_types
#include "toplev.h"
#include "hard-reg-set.h"
#include "basic-block.h"
+#include "predict.h"
/* This controls which loops are unrolled, and by how much we unroll
them. */
@@ -962,6 +963,7 @@ unroll_loop (loop, insn_count, strength_reduce_p)
emit_cmp_and_jump_insns (initial_value, final_value,
neg_inc ? LE : GE,
NULL_RTX, mode, 0, 0, labels[1]);
+ predict_insn_def (get_last_insn (), PRED_LOOP_CONDITION, NOT_TAKEN);
JUMP_LABEL (get_last_insn ()) = labels[1];
LABEL_NUSES (labels[1])++;
}
@@ -1007,6 +1009,8 @@ unroll_loop (loop, insn_count, strength_reduce_p)
labels[i]);
JUMP_LABEL (get_last_insn ()) = labels[i];
LABEL_NUSES (labels[i])++;
+ predict_insn (get_last_insn (), PRED_LOOP_PRECONDITIONING,
+ REG_BR_PROB_BASE / (unroll_number - i));
}
/* If the increment is greater than one, then we need another branch,