* 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.
From-SVN: r133313
+2008-03-18 Jan Hubicka <jh@suse.cz>
+
+ * 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 <matz@suse.de>
* gcov-io.h (__gcov_merge_ior, __gcov_fork): Mark hidden.
* gimplify.c (gimplify_expr): Gimplify second operand of
OMP_ATOMIC_LOAD.
+2008-03-17 Richard Guenther <rguenther@suse.de>
+
+ * 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 <rguenther@suse.de>
PR tree-optimization/19637
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));
}
/* 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);
case NOP_EXPR:
case ASM_EXPR:
case GOTO_EXPR:
+ case PREDICT_EXPR:
case LABEL_EXPR:
case SWITCH_EXPR:
case CHANGE_DYNAMIC_TYPE_EXPR:
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))
{
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))
{
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);
}
}
}
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 */
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),
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 */
case NOP_EXPR:
case CHANGE_DYNAMIC_TYPE_EXPR:
case ASM_EXPR:
+ case PREDICT_EXPR:
return false;
default:
case CALL_EXPR:
case GIMPLE_MODIFY_STMT:
+ case PREDICT_EXPR:
/* These are valid regardless of their type. */
return true;
case COMPLEX_CST:
case VECTOR_CST:
case STRING_CST:
+ case PREDICT_EXPR:
*walk_subtrees = 0;
return NULL;
#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);
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);
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);
case OMP_RETURN:
case OMP_SECTION:
case OMP_SECTIONS_SWITCH:
+ case PREDICT_EXPR:
/* Expressions that make no memory references. */
return;
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
expression.
CALL_EXPR_TAILCALL in CALL_EXPR
CASE_LOW_SEEN in CASE_LABEL_EXPR
+ RETURN_EXPR_OUTCOME in RETURN_EXPR
static_flag:
#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.