diff options
Diffstat (limited to 'gcc/stmt.c')
-rw-r--r-- | gcc/stmt.c | 59 |
1 files changed, 56 insertions, 3 deletions
diff --git a/gcc/stmt.c b/gcc/stmt.c index 42a9659ade6..639587aa45e 100644 --- a/gcc/stmt.c +++ b/gcc/stmt.c @@ -54,6 +54,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "output.h" #include "ggc.h" #include "langhooks.h" +#include "predict.h" #define obstack_chunk_alloc xmalloc #define obstack_chunk_free free @@ -414,6 +415,7 @@ static tree resolve_operand_names PARAMS ((tree, tree, tree, const char **)); static char *resolve_operand_name_1 PARAMS ((char *, tree, tree)); static void expand_null_return_1 PARAMS ((rtx)); +static enum br_predictor return_prediction PARAMS ((rtx)); static void expand_value_return PARAMS ((rtx)); static int tail_recursion_args PARAMS ((tree, tree)); static void expand_cleanups PARAMS ((tree, tree, int, int)); @@ -2824,6 +2826,11 @@ int expand_continue_loop (whichloop) struct nesting *whichloop; { + /* Emit information for branch prediction. */ + rtx note; + + note = emit_note (NULL, NOTE_INSN_PREDICTION); + NOTE_PREDICTION (note) = NOTE_PREDICT (PRED_CONTINUE, IS_TAKEN); last_expr_type = 0; if (whichloop == 0) whichloop = loop_stack; @@ -2965,7 +2972,9 @@ expand_exit_something () void expand_null_return () { - rtx last_insn = get_last_insn (); + rtx last_insn; + + last_insn = get_last_insn (); /* If this function was declared to return a value, but we didn't, clobber the return registers so that they are not @@ -2975,14 +2984,58 @@ expand_null_return () expand_null_return_1 (last_insn); } +/* Try to guess whether the value of return means error code. */ +static enum br_predictor +return_prediction (val) + rtx val; +{ + /* Different heuristics for pointers and scalars. */ + if (POINTER_TYPE_P (TREE_TYPE (DECL_RESULT (current_function_decl)))) + { + /* NULL is usually not returned. */ + if (val == const0_rtx) + return PRED_NULL_RETURN; + } + else + { + /* Negative return values are often used to indicate + errors. */ + if (GET_CODE (val) == CONST_INT + && INTVAL (val) < 0) + return PRED_NEGATIVE_RETURN; + /* Constant return values are also usually erors, + zero/one often mean booleans so exclude them from the + heuristics. */ + if (CONSTANT_P (val) + && (val != const0_rtx && val != const1_rtx)) + return PRED_CONST_RETURN; + } + return PRED_NO_PREDICTION; +} + /* Generate RTL to return from the current function, with value VAL. */ static void expand_value_return (val) rtx val; { - rtx last_insn = get_last_insn (); - rtx return_reg = DECL_RTL (DECL_RESULT (current_function_decl)); + rtx last_insn; + rtx return_reg; + enum br_predictor pred; + + if ((pred = return_prediction (val)) != PRED_NO_PREDICTION) + { + /* Emit information for branch prediction. */ + rtx note; + + note = emit_note (NULL, NOTE_INSN_PREDICTION); + + NOTE_PREDICTION (note) = NOTE_PREDICT (pred, NOT_TAKEN); + + } + + last_insn = get_last_insn (); + return_reg = DECL_RTL (DECL_RESULT (current_function_decl)); /* Copy the value to the return location unless it's already there. */ |