diff options
author | Jan Hubicka <jh@suse.cz> | 2008-08-29 10:40:01 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2008-08-29 08:40:01 +0000 |
commit | 7299cb994088a68a4fec5e479a03fc8a71e50646 (patch) | |
tree | 42efa153d20247d1235c077d9e83fe93cb6e2be6 | |
parent | a4b930608f389022fdcb256796c187719307b410 (diff) | |
download | gcc-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/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/cp/cp-gimplify.c | 1 | ||||
-rw-r--r-- | gcc/passes.c | 1 | ||||
-rw-r--r-- | gcc/predict.c | 69 | ||||
-rw-r--r-- | gcc/tree-inline.c | 7 | ||||
-rw-r--r-- | gcc/tree-pass.h | 1 |
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; |