From 4a1849e3a1e51cb463703ec17861392086dce70b Mon Sep 17 00:00:00 2001 From: hubicka Date: Tue, 18 Mar 2008 15:21:06 +0000 Subject: [PATCH] * tree-pretty-print.c: Include predict.h. (dump_generic_node): Dump predictor. * tree.h (PREDICT_EXPR_OUTCOME, PREDICT_EXPR_PREDICTION): Update. * tree-gimple.c (is_gimple_stmt): Add PREDICT_EXPR. * gimple-low.c (lower_stmt): Likewise. * expr.c (expand_expr_real): Likewise. * predict.c (tree_bb_level_predictions): Use PREDICT_EXPRs and remove them. (build_predict_expr, build_predict_expr): New. * predict.h (predictor_name, build_predict_expr): Update. * c-typeck.c (c_finish_bc_stmt): Add prediction. * gimplify.c (gimplify_expr): Add PREDICT_EXPR. * predict.def (PRED_CONTINUE): Update hitrate. * tree.def (PREDICT_EXPR): Define. * tree-ssa-dce.c (mark_stmt_if_obviously_necessary): Mark PREDICT_EXPR; do not handle BIND_EXPR. * tree-inline.c (estimate_num_insns_1): PREDICT_EXPR is free. * tree-cfg.c (verify_gimple_stmt): PREDICT_EXPR is valid. * tree-ssa-operands.c (get_expr_operands): PREDICT_EXPR takes no operands. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@133313 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 46 ++++++++++++++++++++++++++++++++++++++++++++++ gcc/c-typeck.c | 3 +++ gcc/expr.c | 1 + gcc/gimple-low.c | 1 + gcc/gimplify.c | 4 ++++ gcc/predict.c | 26 +++++++++++++++++++++++++- gcc/predict.def | 2 +- gcc/predict.h | 2 ++ gcc/tree-cfg.c | 1 + gcc/tree-gimple.c | 1 + gcc/tree-inline.c | 1 + gcc/tree-pretty-print.c | 11 +++++++++++ gcc/tree-ssa-dce.c | 2 +- gcc/tree-ssa-operands.c | 1 + gcc/tree.def | 6 ++++++ gcc/tree.h | 6 ++++++ 16 files changed, 111 insertions(+), 3 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 615cf5735cd..82374258411 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,26 @@ +2008-03-18 Jan Hubicka + + * tree-pretty-print.c: Include predict.h. + (dump_generic_node): Dump predictor. + * tree.h (PREDICT_EXPR_OUTCOME, PREDICT_EXPR_PREDICTION): Update. + * tree-gimple.c (is_gimple_stmt): Add PREDICT_EXPR. + * gimple-low.c (lower_stmt): Likewise. + * expr.c (expand_expr_real): Likewise. + * predict.c (tree_bb_level_predictions): Use PREDICT_EXPRs and remove + them. + (build_predict_expr, build_predict_expr): New. + * predict.h (predictor_name, build_predict_expr): Update. + * c-typeck.c (c_finish_bc_stmt): Add prediction. + * gimplify.c (gimplify_expr): Add PREDICT_EXPR. + * predict.def (PRED_CONTINUE): Update hitrate. + * tree.def (PREDICT_EXPR): Define. + * tree-ssa-dce.c (mark_stmt_if_obviously_necessary): Mark PREDICT_EXPR; + do not handle BIND_EXPR. + * tree-inline.c (estimate_num_insns_1): PREDICT_EXPR is free. + * tree-cfg.c (verify_gimple_stmt): PREDICT_EXPR is valid. + * tree-ssa-operands.c (get_expr_operands): PREDICT_EXPR takes no + operands. + 2008-03-18 Michael Matz * gcov-io.h (__gcov_merge_ior, __gcov_fork): Mark hidden. @@ -23,6 +46,29 @@ 2008-03-17 Richard Guenther + * tree-pretty-print.c: Include predict.h. + (dump_generic_node): Dump predictor. + * tree.h (PREDICT_EXPR_OUTCOME, PREDICT_EXPR_PREDICTION): Update. + * tree-gimple.c (is_gimple_stmt): Add PREDICT_EXPR. + * gimple-low.c (lower_stmt): Likewise. + * expr.c (expand_expr_real): Likewise. + * predict.c (tree_bb_level_predictions): Use PREDICT_EXPRs and remove + them. + (build_predict_expr, build_predict_expr): New. + * predict.h (predictor_name, build_predict_expr): Update. + * c-typeck.c (c_finish_bc_stmt): Add prediction. + * gimplify.c (gimplify_expr): Add PREDICT_EXPR. + * predict.def (PRED_CONTINUE): Update hitrate. + * tree.def (PREDICT_EXPR): Define. + * tree-ssa-dce.c (mark_stmt_if_obviously_necessary): Mark PREDICT_EXPR; + do not handle BIND_EXPR. + * tree-inline.c (estimate_num_insns_1): PREDICT_EXPR is free. + * tree-cfg.c (verify_gimple_stmt): PREDICT_EXPR is valid. + * tree-ssa-operands.c (get_expr_operands): PREDICT_EXPR takes no + operands. + +2008-03-17 Richard Guenther + PR tree-optimization/19637 * fold-const.c (fold_unary): Remove restrictions of removing intermediate pointer-conversions (P2)(P1)P0. diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 94d4eea8dc3..4d476c5d4dd 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -7503,6 +7503,9 @@ c_finish_bc_stmt (tree *label_p, bool is_break) if (skip) return NULL_TREE; + if (!is_break) + add_stmt (build_predict_expr (PRED_CONTINUE, NOT_TAKEN)); + return add_stmt (build1 (GOTO_EXPR, void_type_node, label)); } diff --git a/gcc/expr.c b/gcc/expr.c index 3294f1a23e0..83e8e442a8a 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -7055,6 +7055,7 @@ expand_expr_real (tree exp, rtx target, enum machine_mode tmode, /* Handle ERROR_MARK before anybody tries to access its type. */ if (TREE_CODE (exp) == ERROR_MARK + || TREE_CODE (exp) == PREDICT_EXPR || (!GIMPLE_TUPLE_P (exp) && TREE_CODE (TREE_TYPE (exp)) == ERROR_MARK)) { ret = CONST0_RTX (tmode); diff --git a/gcc/gimple-low.c b/gcc/gimple-low.c index a860dd1caf1..7330464ebf1 100644 --- a/gcc/gimple-low.c +++ b/gcc/gimple-low.c @@ -235,6 +235,7 @@ lower_stmt (tree_stmt_iterator *tsi, struct lower_data *data) case NOP_EXPR: case ASM_EXPR: case GOTO_EXPR: + case PREDICT_EXPR: case LABEL_EXPR: case SWITCH_EXPR: case CHANGE_DYNAMIC_TYPE_EXPR: diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 102ce3e7354..acdfb994960 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -5837,6 +5837,10 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p, NULL, is_gimple_val, fb_rvalue); break; + /* Predictions are always gimplified. */ + case PREDICT_EXPR: + goto out; + case LABEL_EXPR: ret = GS_ALL_DONE; gcc_assert (decl_function_context (LABEL_EXPR_LABEL (*expr_p)) diff --git a/gcc/predict.c b/gcc/predict.c index cedb3d54818..a20b3526ce3 100644 --- a/gcc/predict.c +++ b/gcc/predict.c @@ -1293,10 +1293,11 @@ tree_bb_level_predictions (void) { block_stmt_iterator bsi = bsi_last (bb); - for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi)) + for (bsi = bsi_start (bb); !bsi_end_p (bsi);) { tree stmt = bsi_stmt (bsi); tree decl; + bool next = false; switch (TREE_CODE (stmt)) { @@ -1319,9 +1320,17 @@ call_expr:; predict_paths_leading_to (bb, PRED_COLD_FUNCTION, NOT_TAKEN); break; + case PREDICT_EXPR: + predict_paths_leading_to (bb, PREDICT_EXPR_PREDICTOR (stmt), + PREDICT_EXPR_OUTCOME (stmt)); + bsi_remove (&bsi, true); + next = true; + break; default: break; } + if (!next) + bsi_next (&bsi); } } } @@ -1915,6 +1924,21 @@ gate_estimate_probability (void) return flag_guess_branch_prob; } +/* Build PREDICT_EXPR. */ +tree +build_predict_expr (enum br_predictor predictor, enum prediction taken) +{ + tree t = build1 (PREDICT_EXPR, NULL_TREE, build_int_cst (NULL, predictor)); + PREDICT_EXPR_OUTCOME (t) = taken; + return t; +} + +const char * +predictor_name (enum br_predictor predictor) +{ + return predictor_info[predictor].name; +} + struct tree_opt_pass pass_profile = { "profile", /* name */ diff --git a/gcc/predict.def b/gcc/predict.def index a858c016aa7..62ae9d9f8d3 100644 --- a/gcc/predict.def +++ b/gcc/predict.def @@ -66,7 +66,7 @@ DEF_PREDICTOR (PRED_LOOP_ITERATIONS_GUESSED, "guessed loop iterations", PROB_ALWAYS, PRED_FLAG_FIRST_MATCH) /* Branch containing goto is probably not taken. */ -DEF_PREDICTOR (PRED_CONTINUE, "continue", HITRATE (56), 0) +DEF_PREDICTOR (PRED_CONTINUE, "continue", HITRATE (50), 0) /* Branch to basic block containing call marked by noreturn attribute. */ DEF_PREDICTOR (PRED_NORETURN, "noreturn call", HITRATE (99), diff --git a/gcc/predict.h b/gcc/predict.h index 6c48c3e1d42..6552c7293fd 100644 --- a/gcc/predict.h +++ b/gcc/predict.h @@ -38,5 +38,7 @@ enum prediction extern void predict_insn_def (rtx, enum br_predictor, enum prediction); extern int counts_to_freqs (void); extern void estimate_bb_frequencies (void); +extern const char *predictor_name (enum br_predictor); +extern tree build_predict_expr (enum br_predictor, enum prediction); #endif /* GCC_PREDICT_H */ diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 5e551aa4517..329566411b0 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -4059,6 +4059,7 @@ verify_gimple_stmt (tree stmt) case NOP_EXPR: case CHANGE_DYNAMIC_TYPE_EXPR: case ASM_EXPR: + case PREDICT_EXPR: return false; default: diff --git a/gcc/tree-gimple.c b/gcc/tree-gimple.c index 93e99e6cbed..bc482983847 100644 --- a/gcc/tree-gimple.c +++ b/gcc/tree-gimple.c @@ -325,6 +325,7 @@ is_gimple_stmt (tree t) case CALL_EXPR: case GIMPLE_MODIFY_STMT: + case PREDICT_EXPR: /* These are valid regardless of their type. */ return true; diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 74895a82c93..54cacb5a79b 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -2265,6 +2265,7 @@ estimate_num_insns_1 (tree *tp, int *walk_subtrees, void *data) case COMPLEX_CST: case VECTOR_CST: case STRING_CST: + case PREDICT_EXPR: *walk_subtrees = 0; return NULL; diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c index b64571dbae2..8b5f847e476 100644 --- a/gcc/tree-pretty-print.c +++ b/gcc/tree-pretty-print.c @@ -35,6 +35,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-pass.h" #include "fixed-value.h" #include "value-prof.h" +#include "predict.h" /* Local functions, macros and variables. */ static int op_prio (const_tree); @@ -1592,6 +1593,16 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags, is_expr = false; break; + case PREDICT_EXPR: + pp_string (buffer, "// predicted "); + if (PREDICT_EXPR_OUTCOME (node)) + pp_string (buffer, "likely by "); + else + pp_string (buffer, "unlikely by "); + pp_string (buffer, predictor_name (PREDICT_EXPR_PREDICTOR (node))); + pp_string (buffer, " predictor."); + break; + case RETURN_EXPR: pp_string (buffer, "return"); op0 = TREE_OPERAND (node, 0); diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c index bc1700338d8..640c1f38f5c 100644 --- a/gcc/tree-ssa-dce.c +++ b/gcc/tree-ssa-dce.c @@ -277,7 +277,7 @@ mark_stmt_if_obviously_necessary (tree stmt, bool aggressive) can then remove the block and labels. */ switch (TREE_CODE (stmt)) { - case BIND_EXPR: + case PREDICT_EXPR: case LABEL_EXPR: case CASE_LABEL_EXPR: mark_stmt_necessary (stmt, false); diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c index ceb18ba55a6..8869e6ed95a 100644 --- a/gcc/tree-ssa-operands.c +++ b/gcc/tree-ssa-operands.c @@ -2376,6 +2376,7 @@ get_expr_operands (tree stmt, tree *expr_p, int flags) case OMP_RETURN: case OMP_SECTION: case OMP_SECTIONS_SWITCH: + case PREDICT_EXPR: /* Expressions that make no memory references. */ return; diff --git a/gcc/tree.def b/gcc/tree.def index 4a55ee0aaf9..89c18dfd16c 100644 --- a/gcc/tree.def +++ b/gcc/tree.def @@ -1170,6 +1170,12 @@ DEFTREECODE (VEC_EXTRACT_ODD_EXPR, "vec_extractodd_expr", tcc_binary, 2) DEFTREECODE (VEC_INTERLEAVE_HIGH_EXPR, "vec_interleavehigh_expr", tcc_binary, 2) DEFTREECODE (VEC_INTERLEAVE_LOW_EXPR, "vec_interleavelow_expr", tcc_binary, 2) +/* PREDICT_EXPR. Specify hint for branch prediction. The + PREDICT_EXPR_PREDICTOR specify predictor and PREDICT_EXPR_OUTCOME the + outcome (0 for not taken and 1 for taken). Once the profile is guessed + all conditional branches leading to execution paths executing the + PREDICT_EXPR will get predicted by the specified predictor. */ +DEFTREECODE (PREDICT_EXPR, "predict_expr", tcc_unary, 1) /* Local variables: mode:c diff --git a/gcc/tree.h b/gcc/tree.h index de6654de80f..0cb2fadca75 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -436,6 +436,7 @@ struct gimple_stmt GTY(()) expression. CALL_EXPR_TAILCALL in CALL_EXPR CASE_LOW_SEEN in CASE_LABEL_EXPR + RETURN_EXPR_OUTCOME in RETURN_EXPR static_flag: @@ -1158,6 +1159,11 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int, #define CASE_LOW_SEEN(NODE) \ (CASE_LABEL_EXPR_CHECK (NODE)->base.addressable_flag) +#define PREDICT_EXPR_OUTCOME(NODE) \ + (PREDICT_EXPR_CHECK(NODE)->base.addressable_flag) +#define PREDICT_EXPR_PREDICTOR(NODE) \ + ((enum br_predictor)tree_low_cst (TREE_OPERAND (PREDICT_EXPR_CHECK (NODE), 0), 0)) + /* In a VAR_DECL, nonzero means allocate static storage. In a FUNCTION_DECL, nonzero if function has been defined. In a CONSTRUCTOR, nonzero means allocate static storage. -- 2.11.4.GIT