summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2008-08-29 10:40:01 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2008-08-29 08:40:01 +0000
commit7299cb994088a68a4fec5e479a03fc8a71e50646 (patch)
tree42efa153d20247d1235c077d9e83fe93cb6e2be6
parenta4b930608f389022fdcb256796c187719307b410 (diff)
downloadgcc-7299cb994088a68a4fec5e479a03fc8a71e50646.tar.gz
cp-gimplify.c (cp_gimplify_expr): Add PRED_CONTINUE heuristic.
* 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
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/cp/ChangeLog4
-rw-r--r--gcc/cp/cp-gimplify.c1
-rw-r--r--gcc/passes.c1
-rw-r--r--gcc/predict.c69
-rw-r--r--gcc/tree-inline.c7
-rw-r--r--gcc/tree-pass.h1
7 files changed, 72 insertions, 23 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 24ce3a6c532..431661be58a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index b462401c654..49523996109 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index 8dda74d3cbe..243b1c61bfb 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -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;
diff --git a/gcc/passes.c b/gcc/passes.c
index f45507f27e0..7c76747b971 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -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);
diff --git a/gcc/predict.c b/gcc/predict.c
index 69ebe6b98b3..610772314b3 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -1176,9 +1176,10 @@ expr_expected_value (tree expr, bitmap visited)
}
-/* 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;
}
/* 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 */
+ }
+};
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 7ef58c3f40c..4fb28fef7e6 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -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))
diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
index f4e02e86a5e..c6a97cba730 100644
--- a/gcc/tree-pass.h
+++ b/gcc/tree-pass.h
@@ -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;