unroll.c: Include predict.h.
authorJan Hubicka <jh@suse.cz>
Mon, 18 Jun 2001 15:35:47 +0000 (17:35 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Mon, 18 Jun 2001 15:35:47 +0000 (15:35 +0000)
* 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

gcc/ChangeLog
gcc/Makefile.in
gcc/loop.c
gcc/predict.c
gcc/predict.def
gcc/stmt.c
gcc/unroll.c

index c45255a787c6d28cd068aad394e911bb1b0ce1eb..51c11e7acc2b56385ad4e1aaf857a72a06498d11 100644 (file)
@@ -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".
index 6606cabfa758b505cbc849182e770c5cbdf5aefe..75b3dbcee8f7b612e136f3204eb98e4f7400d7e5 100644 (file)
@@ -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)
index ec8dc0ac261f9204fe63c1b6a1be072dff72c6fc..82f09f3ecbb3741da9a9bb4d83706373a7581045 100644 (file)
@@ -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);
index 21c7149070f17d7fa68c15501caf4c90d9af1b2b..38818cbc079963d49067508c7d563820ecfae99e 100644 (file)
@@ -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
index 01d87a4c3f0cc29e27c35ff84afb08d372e95ab3..ff8171bcc6872406020c7564310e041d324f59cf 100644 (file)
@@ -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)
index 3cefc7ce3eed1b05319d5f369bed52e167c9a015..ee4523c33c50e19a82a0b991769ff7d4b9b6e12f 100644 (file)
@@ -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));
        }
index 94c58cd925cea78409f0977dec68dc25206da91d..9a09f5d3d3e08cde131f68f7044e4ce8f6b692de 100644 (file)
@@ -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,