cfgloopmanip.c (create_preheader): Do not use loop_preheader_edge.
[platform/upstream/gcc.git] / gcc / predict.c
index f390ebe..7cae1b7 100644 (file)
@@ -75,7 +75,6 @@ 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 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);
@@ -118,6 +117,13 @@ maybe_hot_bb_p (basic_block bb)
       && (bb->count
          < profile_info->sum_max / PARAM_VALUE (HOT_BB_COUNT_FRACTION)))
     return false;
+  if (!profile_info || !flag_branch_probabilities)
+    {
+      if (cfun->function_frequency == FUNCTION_FREQUENCY_UNLIKELY_EXECUTED)
+        return false;
+      if (cfun->function_frequency == FUNCTION_FREQUENCY_HOT)
+        return true;
+    }
   if (bb->frequency < BB_FREQ_MAX / PARAM_VALUE (HOT_BB_FREQUENCY_FRACTION))
     return false;
   return true;
@@ -132,6 +138,9 @@ probably_cold_bb_p (basic_block bb)
       && (bb->count
          < profile_info->sum_max / PARAM_VALUE (HOT_BB_COUNT_FRACTION)))
     return true;
+  if ((!profile_info || !flag_branch_probabilities)
+      && cfun->function_frequency == FUNCTION_FREQUENCY_UNLIKELY_EXECUTED)
+    return true;
   if (bb->frequency < BB_FREQ_MAX / PARAM_VALUE (HOT_BB_FREQUENCY_FRACTION))
     return true;
   return false;
@@ -143,6 +152,9 @@ probably_never_executed_bb_p (basic_block bb)
 {
   if (profile_info && flag_branch_probabilities)
     return ((bb->count + profile_info->runs / 2) / profile_info->runs) == 0;
+  if ((!profile_info || !flag_branch_probabilities)
+      && cfun->function_frequency == FUNCTION_FREQUENCY_UNLIKELY_EXECUTED)
+    return true;
   return false;
 }
 
@@ -1235,6 +1247,7 @@ tree_bb_level_predictions (void)
       for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
        {
          tree stmt = bsi_stmt (bsi);
+         tree decl;
          switch (TREE_CODE (stmt))
            {
              case GIMPLE_MODIFY_STMT:
@@ -1249,6 +1262,12 @@ call_expr:;
                if (call_expr_flags (stmt) & ECF_NORETURN)
                  predict_paths_leading_to (bb, heads, PRED_NORETURN,
                                            NOT_TAKEN);
+               decl = get_callee_fndecl (stmt);
+               if (decl
+                   && lookup_attribute ("cold",
+                                        DECL_ATTRIBUTES (decl)))
+                 predict_paths_leading_to (bb, heads, PRED_COLD_FUNCTION,
+                                           NOT_TAKEN);
                break;
              default:
                break;
@@ -1271,7 +1290,9 @@ tree_estimate_probability (void)
 
   add_noreturn_fake_exit_edges ();
   connect_infinite_loops_to_exit ();
-  calculate_dominance_info (CDI_DOMINATORS);
+  /* We use loop_niter_by_eval, which requires that the loops have
+     preheaders.  */
+  create_preheaders (CP_SIMPLE_PREHEADERS);
   calculate_dominance_info (CDI_POST_DOMINATORS);
 
   tree_bb_level_predictions ();
@@ -1290,20 +1311,41 @@ tree_estimate_probability (void)
        {
          /* Predict early returns to be probable, as we've already taken
             care for error returns and other cases are often used for
-            fast paths through function.  */
-         if (e->dest == EXIT_BLOCK_PTR
-             && TREE_CODE (last_stmt (bb)) == RETURN_EXPR
-             && !single_pred_p (bb))
+            fast paths through function. 
+
+            Since we've already removed the return statements, we are
+            looking for CFG like:
+
+              if (conditional)
+                {
+                  ..
+                  goto return_block
+                }
+              some other blocks
+            return_block:
+              return_stmt.  */
+         if (e->dest != bb->next_bb
+             && e->dest != EXIT_BLOCK_PTR
+             && single_succ_p (e->dest)
+             && single_succ_edge (e->dest)->dest == EXIT_BLOCK_PTR
+             && TREE_CODE (last_stmt (e->dest)) == RETURN_EXPR)
            {
              edge e1;
              edge_iterator ei1;
 
-             FOR_EACH_EDGE (e1, ei1, bb->preds)
-               if (!predicted_by_p (e1->src, PRED_NULL_RETURN)
-                   && !predicted_by_p (e1->src, PRED_CONST_RETURN)
-                   && !predicted_by_p (e1->src, PRED_NEGATIVE_RETURN)
-                   && !last_basic_block_p (e1->src))
-                 predict_edge_def (e1, PRED_TREE_EARLY_RETURN, NOT_TAKEN);
+             if (single_succ_p (bb))
+               {
+                 FOR_EACH_EDGE (e1, ei1, bb->preds)
+                   if (!predicted_by_p (e1->src, PRED_NULL_RETURN)
+                       && !predicted_by_p (e1->src, PRED_CONST_RETURN)
+                       && !predicted_by_p (e1->src, PRED_NEGATIVE_RETURN))
+                     predict_edge_def (e1, PRED_TREE_EARLY_RETURN, NOT_TAKEN);
+               }
+              else
+               if (!predicted_by_p (e->src, PRED_NULL_RETURN)
+                   && !predicted_by_p (e->src, PRED_CONST_RETURN)
+                   && !predicted_by_p (e->src, PRED_NEGATIVE_RETURN))
+                 predict_edge_def (e, PRED_TREE_EARLY_RETURN, NOT_TAKEN);
            }
 
          /* Look for block we are guarding (ie we dominate it,
@@ -1353,20 +1395,6 @@ tree_estimate_probability (void)
   return 0;
 }
 \f
-/* Check whether this is the last basic block of function.  Commonly
-   there is one extra common cleanup block.  */
-static bool
-last_basic_block_p (basic_block bb)
-{
-  if (bb == EXIT_BLOCK_PTR)
-    return false;
-
-  return (bb->next_bb == EXIT_BLOCK_PTR
-         || (bb->next_bb->next_bb == EXIT_BLOCK_PTR
-             && single_succ_p (bb)
-             && single_succ (bb)->next_bb == EXIT_BLOCK_PTR));
-}
-
 /* Sets branch probabilities according to PREDiction and
    FLAGS. HEADS[bb->index] should be index of basic block in that we
    need to alter branch predictions (i.e. the first of our dominators
@@ -1779,7 +1807,15 @@ compute_function_frequency (void)
   basic_block bb;
 
   if (!profile_info || !flag_branch_probabilities)
-    return;
+    {
+      if (lookup_attribute ("cold", DECL_ATTRIBUTES (current_function_decl))
+         != NULL)
+        cfun->function_frequency = FUNCTION_FREQUENCY_UNLIKELY_EXECUTED;
+      else if (lookup_attribute ("hot", DECL_ATTRIBUTES (current_function_decl))
+              != NULL)
+        cfun->function_frequency = FUNCTION_FREQUENCY_HOT;
+      return;
+    }
   cfun->function_frequency = FUNCTION_FREQUENCY_UNLIKELY_EXECUTED;
   FOR_EACH_BB (bb)
     {