OSDN Git Service

* config/elfos.h, config/spu/spu.c, tree-ssa-operands.h,
[pf3gnuchains/gcc-fork.git] / gcc / predict.c
index 3c2775c..534258f 100644 (file)
@@ -74,14 +74,12 @@ static sreal real_zero, real_one, real_almost_one, real_br_prob_base,
 
 static void combine_predictions_for_insn (rtx, basic_block);
 static void dump_prediction (FILE *, enum br_predictor, int, basic_block, int);
-static void estimate_loops_at_level (struct loop *, bitmap);
-static void propagate_freq (struct loop *, bitmap);
-static void estimate_bb_frequencies (struct loops *);
 static void predict_paths_leading_to (basic_block, int *, enum br_predictor, enum prediction);
 static bool last_basic_block_p (basic_block);
 static void compute_function_frequency (void);
 static void choose_function_section (void);
 static bool can_predict_insn_p (rtx);
+static void estimate_bb_frequencies (void);
 
 /* Information we hold about each branch predictor.
    Filled using information from predict.def.  */
@@ -182,7 +180,7 @@ tree_predicted_by_p (basic_block bb, enum br_predictor predictor)
   
    The profile guessing code is good at predicting branch outcome (ie.
    taken/not taken), that is predicted right slightly over 75% of time.
-   It is however notorously poor on predicting the probability itself.
+   It is however notoriously poor on predicting the probability itself.
    In general the profile appear a lot flatter (with probabilities closer
    to 50%) than the reality so it is bad idea to use it to drive optimization
    such as those disabling dynamic branch prediction for well predictable
@@ -192,7 +190,7 @@ tree_predicted_by_p (basic_block bb, enum br_predictor predictor)
    predicted by number of iterations heuristics are predicted well.  This macro
    should be able to distinguish those, but at the moment it simply check for
    noreturn heuristic that is only one giving probability over 99% or bellow
-   1%.  In future we might want to propagate reliablity information across the
+   1%.  In future we might want to propagate reliability information across the
    CFG if we find this information useful on multiple places.   */
 static bool
 probability_reliable_p (int prob)
@@ -627,90 +625,57 @@ combine_predictions_for_bb (basic_block bb)
     }
 }
 
-/* Predict edge probabilities by exploiting loop structure.
-   When RTLSIMPLELOOPS is set, attempt to count number of iterations by analyzing
-   RTL otherwise use tree based approach.  */
+/* Predict edge probabilities by exploiting loop structure.  */
+
 static void
-predict_loops (struct loops *loops_info, bool rtlsimpleloops)
+predict_loops (void)
 {
-  unsigned i;
+  loop_iterator li;
+  struct loop *loop;
 
-  if (!rtlsimpleloops)
-    scev_initialize (loops_info);
+  scev_initialize ();
 
   /* Try to predict out blocks in a loop that are not part of a
      natural loop.  */
-  for (i = 1; i < loops_info->num; i++)
+  FOR_EACH_LOOP (li, loop, 0)
     {
       basic_block bb, *bbs;
-      unsigned j;
-      unsigned n_exits;
-      struct loop *loop = loops_info->parray[i];
-      struct niter_desc desc;
-      unsigned HOST_WIDE_INT niter;
-      edge *exits;
+      unsigned j, n_exits;
+      VEC (edge, heap) *exits;
+      struct tree_niter_desc niter_desc;
+      edge ex;
 
-      exits = get_loop_exit_edges (loop, &n_exits);
+      exits = get_loop_exit_edges (loop);
+      n_exits = VEC_length (edge, exits);
 
-      if (rtlsimpleloops)
+      for (j = 0; VEC_iterate (edge, exits, j, ex); j++)
        {
-         iv_analysis_loop_init (loop);
-         find_simple_exit (loop, &desc);
+         tree niter = NULL;
 
-         if (desc.simple_p && desc.const_iter)
-           {
-             int prob;
-             niter = desc.niter + 1;
-             if (niter == 0)        /* We might overflow here.  */
-               niter = desc.niter;
-             if (niter
-                 > (unsigned int) PARAM_VALUE (PARAM_MAX_PREDICTED_ITERATIONS))
-               niter = PARAM_VALUE (PARAM_MAX_PREDICTED_ITERATIONS);
-
-             prob = (REG_BR_PROB_BASE
-                     - (REG_BR_PROB_BASE + niter /2) / niter);
-             /* Branch prediction algorithm gives 0 frequency for everything
-                after the end of loop for loop having 0 probability to finish.  */
-             if (prob == REG_BR_PROB_BASE)
-               prob = REG_BR_PROB_BASE - 1;
-             predict_edge (desc.in_edge, PRED_LOOP_ITERATIONS,
-                           prob);
-           }
-       }
-      else
-       {
-         struct tree_niter_desc niter_desc;
+         if (number_of_iterations_exit (loop, ex, &niter_desc, false))
+           niter = niter_desc.niter;
+         if (!niter || TREE_CODE (niter_desc.niter) != INTEGER_CST)
+           niter = loop_niter_by_eval (loop, ex);
 
-         for (j = 0; j < n_exits; j++)
+         if (TREE_CODE (niter) == INTEGER_CST)
            {
-             tree niter = NULL;
-
-             if (number_of_iterations_exit (loop, exits[j], &niter_desc, false))
-               niter = niter_desc.niter;
-             if (!niter || TREE_CODE (niter_desc.niter) != INTEGER_CST)
-               niter = loop_niter_by_eval (loop, exits[j]);
-
-             if (TREE_CODE (niter) == INTEGER_CST)
+             int probability;
+             int max = PARAM_VALUE (PARAM_MAX_PREDICTED_ITERATIONS);
+             if (host_integerp (niter, 1)
+                 && tree_int_cst_lt (niter,
+                                     build_int_cstu (NULL_TREE, max - 1)))
                {
-                 int probability;
-                 int max = PARAM_VALUE (PARAM_MAX_PREDICTED_ITERATIONS);
-                 if (host_integerp (niter, 1)
-                     && tree_int_cst_lt (niter,
-                                         build_int_cstu (NULL_TREE, max - 1)))
-                   {
-                     HOST_WIDE_INT nitercst = tree_low_cst (niter, 1) + 1;
-                     probability = ((REG_BR_PROB_BASE + nitercst / 2)
-                                    / nitercst);
-                   }
-                 else
-                   probability = ((REG_BR_PROB_BASE + max / 2) / max);
-
-                 predict_edge (exits[j], PRED_LOOP_ITERATIONS, probability);
+                 HOST_WIDE_INT nitercst = tree_low_cst (niter, 1) + 1;
+                 probability = ((REG_BR_PROB_BASE + nitercst / 2)
+                                / nitercst);
                }
-           }
+             else
+               probability = ((REG_BR_PROB_BASE + max / 2) / max);
 
+             predict_edge (ex, PRED_LOOP_ITERATIONS, probability);
+           }
        }
-      free (exits);
+      VEC_free (edge, heap, exits);
 
       bbs = get_loop_body (loop);
 
@@ -726,8 +691,7 @@ predict_loops (struct loops *loops_info, bool rtlsimpleloops)
             statements construct loops via "non-loop" constructs
             in the source language and are better to be handled
             separately.  */
-         if ((rtlsimpleloops && !can_predict_insn_p (BB_END (bb)))
-             || predicted_by_p (bb, PRED_CONTINUE))
+         if (predicted_by_p (bb, PRED_CONTINUE))
            continue;
 
          /* Loop branch heuristics - predict an edge back to a
@@ -776,11 +740,7 @@ predict_loops (struct loops *loops_info, bool rtlsimpleloops)
       free (bbs);
     }
 
-  if (!rtlsimpleloops)
-    {
-      scev_finalize ();
-      current_loops = NULL;
-    }
+  scev_finalize ();
 }
 
 /* Attempt to predict probabilities of BB outgoing edges using local
@@ -942,9 +902,10 @@ expr_expected_value (tree expr, bitmap visited)
            }
          return val;
        }
-      if (TREE_CODE (def) != MODIFY_EXPR || TREE_OPERAND (def, 0) != expr)
+      if (TREE_CODE (def) != GIMPLE_MODIFY_STMT
+         || GIMPLE_STMT_OPERAND (def, 0) != expr)
        return NULL;
-      return expr_expected_value (TREE_OPERAND (def, 1), visited);
+      return expr_expected_value (GIMPLE_STMT_OPERAND (def, 1), visited);
     }
   else if (TREE_CODE (expr) == CALL_EXPR)
     {
@@ -1008,15 +969,15 @@ strip_builtin_expect (void)
          tree fndecl;
          tree arglist;
 
-         if (TREE_CODE (stmt) == MODIFY_EXPR
-             && TREE_CODE (TREE_OPERAND (stmt, 1)) == CALL_EXPR
-             && (fndecl = get_callee_fndecl (TREE_OPERAND (stmt, 1)))
+         if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
+             && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == CALL_EXPR
+             && (fndecl = get_callee_fndecl (GIMPLE_STMT_OPERAND (stmt, 1)))
              && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
              && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_EXPECT
-             && (arglist = TREE_OPERAND (TREE_OPERAND (stmt, 1), 1))
+             && (arglist = TREE_OPERAND (GIMPLE_STMT_OPERAND (stmt, 1), 1))
              && TREE_CHAIN (arglist))
            {
-             TREE_OPERAND (stmt, 1) = TREE_VALUE (arglist);
+             GIMPLE_STMT_OPERAND (stmt, 1) = TREE_VALUE (arglist);
              update_stmt (stmt);
            }
        }
@@ -1207,8 +1168,8 @@ apply_return_prediction (int *heads)
   return_val = TREE_OPERAND (return_stmt, 0);
   if (!return_val)
     return;
-  if (TREE_CODE (return_val) == MODIFY_EXPR)
-    return_val = TREE_OPERAND (return_val, 1);
+  if (TREE_CODE (return_val) == GIMPLE_MODIFY_STMT)
+    return_val = GIMPLE_STMT_OPERAND (return_val, 1);
   if (TREE_CODE (return_val) != SSA_NAME
       || !SSA_NAME_DEF_STMT (return_val)
       || TREE_CODE (SSA_NAME_DEF_STMT (return_val)) != PHI_NODE)
@@ -1247,8 +1208,7 @@ tree_bb_level_predictions (void)
   basic_block bb;
   int *heads;
 
-  heads = XNEWVEC (int, last_basic_block);
-  memset (heads, ENTRY_BLOCK, sizeof (int) * last_basic_block);
+  heads = XCNEWVEC (int, last_basic_block);
   heads[ENTRY_BLOCK_PTR->next_bb->index] = last_basic_block;
 
   apply_return_prediction (heads);
@@ -1262,10 +1222,10 @@ tree_bb_level_predictions (void)
          tree stmt = bsi_stmt (bsi);
          switch (TREE_CODE (stmt))
            {
-             case MODIFY_EXPR:
-               if (TREE_CODE (TREE_OPERAND (stmt, 1)) == CALL_EXPR)
+             case GIMPLE_MODIFY_STMT:
+               if (TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == CALL_EXPR)
                  {
-                   stmt = TREE_OPERAND (stmt, 1);
+                   stmt = GIMPLE_STMT_OPERAND (stmt, 1);
                    goto call_expr;
                  }
                break;
@@ -1289,11 +1249,10 @@ static unsigned int
 tree_estimate_probability (void)
 {
   basic_block bb;
-  struct loops loops_info;
 
-  flow_loops_find (&loops_info);
-  if (dump_file && (dump_flags & TDF_DETAILS))
-    flow_loops_dump (&loops_info, dump_file, NULL, 0);
+  loop_optimizer_init (0);
+  if (current_loops && dump_file && (dump_flags & TDF_DETAILS))
+    flow_loops_dump (dump_file, NULL, 0);
 
   add_noreturn_fake_exit_edges ();
   connect_infinite_loops_to_exit ();
@@ -1302,8 +1261,9 @@ tree_estimate_probability (void)
 
   tree_bb_level_predictions ();
 
-  mark_irreducible_loops (&loops_info);
-  predict_loops (&loops_info, false);
+  mark_irreducible_loops ();
+  if (current_loops)
+    predict_loops ();
 
   FOR_EACH_BB (bb)
     {
@@ -1347,8 +1307,9 @@ tree_estimate_probability (void)
                {
                  tree stmt = bsi_stmt (bi);
                  if ((TREE_CODE (stmt) == CALL_EXPR
-                      || (TREE_CODE (stmt) == MODIFY_EXPR
-                          && TREE_CODE (TREE_OPERAND (stmt, 1)) == CALL_EXPR))
+                      || (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
+                          && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1))
+                             == CALL_EXPR))
                      /* Constant and pure calls are hardly used to signalize
                         something exceptional.  */
                      && TREE_SIDE_EFFECTS (stmt))
@@ -1365,10 +1326,10 @@ tree_estimate_probability (void)
     combine_predictions_for_bb (bb);
 
   strip_builtin_expect ();
-  estimate_bb_frequencies (&loops_info);
+  estimate_bb_frequencies ();
   free_dominance_info (CDI_POST_DOMINATORS);
   remove_fake_exit_edges ();
-  flow_loops_free (&loops_info);
+  loop_optimizer_finalize ();
   if (dump_file && (dump_flags & TDF_DETAILS))
     dump_tree_cfg (dump_file, dump_flags);
   if (profile_status == PROFILE_ABSENT)
@@ -1376,79 +1337,6 @@ tree_estimate_probability (void)
   return 0;
 }
 \f
-/* __builtin_expect dropped tokens into the insn stream describing expected
-   values of registers.  Generate branch probabilities based off these
-   values.  */
-
-void
-expected_value_to_br_prob (void)
-{
-  rtx insn, cond, ev = NULL_RTX, ev_reg = NULL_RTX;
-
-  for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
-    {
-      switch (GET_CODE (insn))
-       {
-       case NOTE:
-         /* Look for expected value notes.  */
-         if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EXPECTED_VALUE)
-           {
-             ev = NOTE_EXPECTED_VALUE (insn);
-             ev_reg = XEXP (ev, 0);
-             delete_insn (insn);
-           }
-         continue;
-
-       case CODE_LABEL:
-         /* Never propagate across labels.  */
-         ev = NULL_RTX;
-         continue;
-
-       case JUMP_INSN:
-         /* Look for simple conditional branches.  If we haven't got an
-            expected value yet, no point going further.  */
-         if (!JUMP_P (insn) || ev == NULL_RTX
-             || ! any_condjump_p (insn))
-           continue;
-         break;
-
-       default:
-         /* Look for insns that clobber the EV register.  */
-         if (ev && reg_set_p (ev_reg, insn))
-           ev = NULL_RTX;
-         continue;
-       }
-
-      /* Collect the branch condition, hopefully relative to EV_REG.  */
-      /* ???  At present we'll miss things like
-               (expected_value (eq r70 0))
-               (set r71 -1)
-               (set r80 (lt r70 r71))
-               (set pc (if_then_else (ne r80 0) ...))
-        as canonicalize_condition will render this to us as
-               (lt r70, r71)
-        Could use cselib to try and reduce this further.  */
-      cond = XEXP (SET_SRC (pc_set (insn)), 0);
-      cond = canonicalize_condition (insn, cond, 0, NULL, ev_reg,
-                                    false, false);
-      if (! cond || XEXP (cond, 0) != ev_reg
-         || GET_CODE (XEXP (cond, 1)) != CONST_INT)
-       continue;
-
-      /* Substitute and simplify.  Given that the expression we're
-        building involves two constants, we should wind up with either
-        true or false.  */
-      cond = gen_rtx_fmt_ee (GET_CODE (cond), VOIDmode,
-                            XEXP (ev, 1), XEXP (cond, 1));
-      cond = simplify_rtx (cond);
-
-      /* Turn the condition into a scaled branch probability.  */
-      gcc_assert (cond == const_true_rtx || cond == const0_rtx);
-      predict_insn_def (insn, PRED_BUILTIN_EXPECT,
-                       cond == const_true_rtx ? TAKEN : NOT_TAKEN);
-    }
-}
-\f
 /* Check whether this is the last basic block of function.  Commonly
    there is one extra common cleanup block.  */
 static bool
@@ -1547,12 +1435,12 @@ typedef struct edge_info_def
 #define EDGE_INFO(E)   ((edge_info) (E)->aux)
 
 /* Helper function for estimate_bb_frequencies.
-   Propagate the frequencies for LOOP.  */
+   Propagate the frequencies in blocks marked in
+   TOVISIT, starting in HEAD.  */
 
 static void
-propagate_freq (struct loop *loop, bitmap tovisit)
+propagate_freq (basic_block head, bitmap tovisit)
 {
-  basic_block head = loop->header;
   basic_block bb;
   basic_block last;
   unsigned i;
@@ -1689,7 +1577,7 @@ propagate_freq (struct loop *loop, bitmap tovisit)
 /* Estimate probabilities of loopback edges in loops at same nest level.  */
 
 static void
-estimate_loops_at_level (struct loop *first_loop, bitmap tovisit)
+estimate_loops_at_level (struct loop *first_loop)
 {
   struct loop *loop;
 
@@ -1698,25 +1586,44 @@ estimate_loops_at_level (struct loop *first_loop, bitmap tovisit)
       edge e;
       basic_block *bbs;
       unsigned i;
+      bitmap tovisit = BITMAP_ALLOC (NULL);
 
-      estimate_loops_at_level (loop->inner, tovisit);
+      estimate_loops_at_level (loop->inner);
 
-      /* Do not do this for dummy function loop.  */
-      if (EDGE_COUNT (loop->latch->succs) > 0)
-       {
-         /* Find current loop back edge and mark it.  */
-         e = loop_latch_edge (loop);
-         EDGE_INFO (e)->back_edge = 1;
-       }
+      /* Find current loop back edge and mark it.  */
+      e = loop_latch_edge (loop);
+      EDGE_INFO (e)->back_edge = 1;
 
       bbs = get_loop_body (loop);
       for (i = 0; i < loop->num_nodes; i++)
        bitmap_set_bit (tovisit, bbs[i]->index);
       free (bbs);
-      propagate_freq (loop, tovisit);
+      propagate_freq (loop->header, tovisit);
+      BITMAP_FREE (tovisit);
     }
 }
 
+/* Propagates frequencies through structure of loops.  */
+
+static void
+estimate_loops (void)
+{
+  bitmap tovisit = BITMAP_ALLOC (NULL);
+  basic_block bb;
+
+  /* Start by estimating the frequencies in the loops.  */
+  if (current_loops)
+    estimate_loops_at_level (current_loops->tree_root->inner);
+
+  /* Now propagate the frequencies through all the blocks.  */
+  FOR_ALL_BB (bb)
+    {
+      bitmap_set_bit (tovisit, bb->index);
+    }
+  propagate_freq (ENTRY_BLOCK_PTR, tovisit);
+  BITMAP_FREE (tovisit);
+}
+
 /* Convert counts measured by profile driven feedback to frequencies.
    Return nonzero iff there was any nonzero execution count.  */
 
@@ -1779,7 +1686,7 @@ expensive_function_p (int threshold)
 /* Estimate basic blocks frequency by given branch probabilities.  */
 
 static void
-estimate_bb_frequencies (struct loops *loops)
+estimate_bb_frequencies (void)
 {
   basic_block bb;
   sreal freq_max;
@@ -1787,7 +1694,6 @@ estimate_bb_frequencies (struct loops *loops)
   if (!flag_branch_probabilities || !counts_to_freqs ())
     {
       static int real_values_initialized = 0;
-      bitmap tovisit;
 
       if (!real_values_initialized)
         {
@@ -1806,7 +1712,6 @@ estimate_bb_frequencies (struct loops *loops)
       single_succ_edge (ENTRY_BLOCK_PTR)->probability = REG_BR_PROB_BASE;
 
       /* Set up block info for each basic block.  */
-      tovisit = BITMAP_ALLOC (NULL);
       alloc_aux_for_blocks (sizeof (struct block_info_def));
       alloc_aux_for_edges (sizeof (struct edge_info_def));
       FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
@@ -1825,7 +1730,7 @@ estimate_bb_frequencies (struct loops *loops)
 
       /* First compute probabilities locally for each loop from innermost
          to outermost to examine probabilities for back edges.  */
-      estimate_loops_at_level (loops->tree_root, tovisit);
+      estimate_loops ();
 
       memcpy (&freq_max, &real_zero, sizeof (real_zero));
       FOR_EACH_BB (bb)
@@ -1844,7 +1749,6 @@ estimate_bb_frequencies (struct loops *loops)
 
       free_aux_for_blocks ();
       free_aux_for_edges ();
-      BITMAP_FREE (tovisit);
     }
   compute_function_frequency ();
   if (flag_reorder_functions)