OSDN Git Service

* config/elfos.h, config/spu/spu.c, tree-ssa-operands.h,
[pf3gnuchains/gcc-fork.git] / gcc / predict.c
index 9661322..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.  */
@@ -627,38 +625,37 @@ 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)
+predict_loops (void)
 {
-  unsigned i;
+  loop_iterator li;
+  struct loop *loop;
 
-  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];
-      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);
 
-
-      for (j = 0; j < n_exits; j++)
+      for (j = 0; VEC_iterate (edge, exits, j, ex); j++)
        {
          tree niter = NULL;
 
-         if (number_of_iterations_exit (loop, exits[j], &niter_desc, false))
+         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, exits[j]);
+           niter = loop_niter_by_eval (loop, ex);
 
          if (TREE_CODE (niter) == INTEGER_CST)
            {
@@ -675,10 +672,10 @@ predict_loops (struct loops *loops_info)
              else
                probability = ((REG_BR_PROB_BASE + max / 2) / max);
 
-             predict_edge (exits[j], PRED_LOOP_ITERATIONS, probability);
+             predict_edge (ex, PRED_LOOP_ITERATIONS, probability);
            }
        }
-      free (exits);
+      VEC_free (edge, heap, exits);
 
       bbs = get_loop_body (loop);
 
@@ -744,7 +741,6 @@ predict_loops (struct loops *loops_info)
     }
 
   scev_finalize ();
-  current_loops = NULL;
 }
 
 /* Attempt to predict probabilities of BB outgoing edges using local
@@ -906,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)
     {
@@ -972,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);
            }
        }
@@ -1171,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)
@@ -1211,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);
@@ -1226,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;
@@ -1253,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 ();
@@ -1266,8 +1261,9 @@ tree_estimate_probability (void)
 
   tree_bb_level_predictions ();
 
-  mark_irreducible_loops (&loops_info);
-  predict_loops (&loops_info);
+  mark_irreducible_loops ();
+  if (current_loops)
+    predict_loops ();
 
   FOR_EACH_BB (bb)
     {
@@ -1311,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))
@@ -1329,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)
@@ -1340,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
@@ -1511,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;
@@ -1653,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;
 
@@ -1662,23 +1586,42 @@ 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.
@@ -1743,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;
@@ -1751,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)
         {
@@ -1770,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)
@@ -1789,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)
@@ -1808,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)