From: Jan Hubicka Date: Mon, 18 Jun 2001 15:35:47 +0000 (+0200) Subject: unroll.c: Include predict.h. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=923cbdc322ee080c02b94a95eece0618a2a78b47;p=gcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c45255a787c..51c11e7acc2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,23 @@ +Mon Jun 18 17:27:24 CEST 2001 Jan Hubicka + + * 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 + + * stmt.c (emit_case_nodes): Optimize test whether index is in given + interval. + +Mon Jun 18 15:43:10 CEST 2001 Jan Hubicka + + * 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 * except.c (resolve_fixup_regions): Initialise "cleanup". diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 6606cabfa75..75b3dbcee8f 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 ec8dc0ac261..82f09f3ecbb 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 21c7149070f..38818cbc079 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 01d87a4c3f0..ff8171bcc68 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 3cefc7ce3ee..ee4523c33c5 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 94c58cd925c..9a09f5d3d3e 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,