cp-gimplify.c (cp_gimplify_expr): Add PRED_CONTINUE heuristic.
authorJan Hubicka <jh@suse.cz>
Fri, 29 Aug 2008 08:40:01 +0000 (10:40 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Fri, 29 Aug 2008 08:40:01 +0000 (08:40 +0000)
* cp-gimplify.c (cp_gimplify_expr): Add PRED_CONTINUE heuristic.
* tree-pass.h (pass_strip_predict_hints): Declare.
* predict.c (strip_builtin_expect): Rename to ...
(strip_predict_hints): ... this one; strip also GIMPLE_PREDICT.
(tree_bb_level_predictions): Do not remove GIMPLE_PREDICT.
(tree_estimate_probability): Do not strip builtin_expect.
(pass_strip_predict_hints): New pass.
* tree-inline.c (expand_call_inline): When inlining cold function, predict
it as unlikely.
* passes.c (init_optimization_passes): Add pass_strip_predict_hints.

From-SVN: r139755

gcc/ChangeLog
gcc/cp/ChangeLog
gcc/cp/cp-gimplify.c
gcc/passes.c
gcc/predict.c
gcc/tree-inline.c
gcc/tree-pass.h

index 24ce3a6..431661b 100644 (file)
@@ -1,3 +1,15 @@
+2008-08-29  Jan Hubicka  <jh@suse.cz>
+
+       * tree-pass.h (pass_strip_predict_hints): Declare.
+       * predict.c (strip_builtin_expect): Rename to ...
+       (strip_predict_hints): ... this one; strip also GIMPLE_PREDICT.
+       (tree_bb_level_predictions): Do not remove GIMPLE_PREDICT.
+       (tree_estimate_probability): Do not strip builtin_expect.
+       (pass_strip_predict_hints): New pass.
+       * tree-inline.c (expand_call_inline): When inlining cold function, predict
+       it as unlikely.
+       * passes.c (init_optimization_passes): Add pass_strip_predict_hints.
+
 2008-08-29  Richard Guenther  <rguenther@suse.de>
 
        PR tree-optimization/37207
index b462401..4952399 100644 (file)
@@ -1,3 +1,7 @@
+2008-08-29  Jan Hubicka  <jh@suse.cz>
+
+       * cp-gimplify.c (cp_gimplify_expr): Add PRED_CONTINUE heuristic.
+
 2008-08-28  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/37260
index 8dda74d..243b1c6 100644 (file)
@@ -610,6 +610,7 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
       break;
 
     case CONTINUE_STMT:
+      gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_CONTINUE, NOT_TAKEN));
       gimple_seq_add_stmt (pre_p, gimple_build_goto (get_bc_label (bc_continue)));
       *expr_p = NULL_TREE;
       ret = GS_ALL_DONE;
index f45507f..7c76747 100644 (file)
@@ -585,6 +585,7 @@ init_optimization_passes (void)
       struct opt_pass **p = &pass_all_optimizations.pass.sub;
       /* Initial scalar cleanups before alias computation.
         They ensure memory accesses are not indirect wherever possible.  */
+      NEXT_PASS (pass_strip_predict_hints);
       NEXT_PASS (pass_update_address_taken);
       NEXT_PASS (pass_rename_ssa_copies);
       NEXT_PASS (pass_complete_unrolli);
index 69ebe6b..6107723 100644 (file)
@@ -1176,9 +1176,10 @@ expr_expected_value (tree expr, bitmap visited)
 }
 
 \f
-/* Get rid of all builtin_expect calls we no longer need.  */
-static void
-strip_builtin_expect (void)
+/* Get rid of all builtin_expect calls and GIMPLE_PREDICT statements
+   we no longer need.  */
+static unsigned int
+strip_predict_hints (void)
 {
   basic_block bb;
   gimple ass_stmt;
@@ -1187,28 +1188,34 @@ strip_builtin_expect (void)
   FOR_EACH_BB (bb)
     {
       gimple_stmt_iterator bi;
-      for (bi = gsi_start_bb (bb); !gsi_end_p (bi); gsi_next (&bi))
+      for (bi = gsi_start_bb (bb); !gsi_end_p (bi);)
        {
          gimple stmt = gsi_stmt (bi);
-         tree fndecl;
-
-         if (gimple_code (stmt) != GIMPLE_CALL)
-           continue;
 
-         fndecl = gimple_call_fndecl (stmt);
-
-         if (fndecl
-             && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
-             && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_EXPECT
-             && gimple_call_num_args (stmt) == 2)
+         if (gimple_code (stmt) == GIMPLE_PREDICT)
+           {
+             gsi_remove (&bi, true);
+             continue;
+           }
+         else if (gimple_code (stmt) == GIMPLE_CALL)
            {
-             var = gimple_call_lhs (stmt);
-             ass_stmt = gimple_build_assign (var, gimple_call_arg (stmt, 0));
+             tree fndecl = gimple_call_fndecl (stmt);
 
-             gsi_replace (&bi, ass_stmt, true);
+             if (fndecl
+                 && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
+                 && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_EXPECT
+                 && gimple_call_num_args (stmt) == 2)
+               {
+                 var = gimple_call_lhs (stmt);
+                 ass_stmt = gimple_build_assign (var, gimple_call_arg (stmt, 0));
+
+                 gsi_replace (&bi, ass_stmt, true);
+               }
            }
+         gsi_next (&bi);
        }
     }
+  return 0;
 }
 \f
 /* Predict using opcode of the last statement in basic block.  */
@@ -1434,7 +1441,7 @@ tree_bb_level_predictions (void)
     {
       gimple_stmt_iterator gsi;
 
-      for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
+      for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
        {
          gimple stmt = gsi_stmt (gsi);
          tree decl;
@@ -1455,11 +1462,9 @@ tree_bb_level_predictions (void)
            {
              predict_paths_leading_to (bb, gimple_predict_predictor (stmt),
                                        gimple_predict_outcome (stmt));
-             gsi_remove (&gsi, true);
-             continue;
+             /* Keep GIMPLE_PREDICT around so early inlining will propagate
+                hints to callers.  */
            }
-
-         gsi_next (&gsi);
        }
     }
 }
@@ -1587,7 +1592,6 @@ tree_estimate_probability (void)
   pointer_map_destroy (bb_predictions);
   bb_predictions = NULL;
 
-  strip_builtin_expect ();
   estimate_bb_frequencies ();
   free_dominance_info (CDI_POST_DOMINATORS);
   remove_fake_exit_edges ();
@@ -2084,3 +2088,22 @@ struct gimple_opt_pass pass_profile =
   TODO_ggc_collect | TODO_verify_ssa                   /* todo_flags_finish */
  }
 };
+
+struct gimple_opt_pass pass_strip_predict_hints = 
+{
+ {
+  GIMPLE_PASS,
+  "",                                  /* name */
+  NULL,                                        /* gate */
+  strip_predict_hints,                 /* execute */
+  NULL,                                        /* sub */
+  NULL,                                        /* next */
+  0,                                   /* static_pass_number */
+  TV_BRANCH_PROB,                      /* tv_id */
+  PROP_cfg,                            /* properties_required */
+  0,                                   /* properties_provided */
+  0,                                   /* properties_destroyed */
+  0,                                   /* todo_flags_start */
+  TODO_ggc_collect | TODO_verify_ssa                   /* todo_flags_finish */
+ }
+};
index 7ef58c3..4fb28fe 100644 (file)
@@ -3209,6 +3209,13 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
   gcc_assert (!id->src_cfun->after_inlining);
 
   id->entry_bb = bb;
+  if (lookup_attribute ("cold", DECL_ATTRIBUTES (fn)))
+    {
+      gimple_stmt_iterator si = gsi_last_bb (bb);
+      gsi_insert_after (&si, gimple_build_predict (PRED_COLD_FUNCTION,
+                                                  NOT_TAKEN),
+                       GSI_NEW_STMT);
+    }
   initialize_inlined_parameters (id, stmt, fn, bb);
 
   if (DECL_INITIAL (fn))
index f4e02e8..c6a97cb 100644 (file)
@@ -346,6 +346,7 @@ extern struct gimple_opt_pass pass_merge_phi;
 extern struct gimple_opt_pass pass_split_crit_edges;
 extern struct gimple_opt_pass pass_pre;
 extern struct gimple_opt_pass pass_profile;
+extern struct gimple_opt_pass pass_strip_predict_hints;
 extern struct gimple_opt_pass pass_lower_complex_O0;
 extern struct gimple_opt_pass pass_lower_complex;
 extern struct gimple_opt_pass pass_lower_vector;