diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 22 | ||||
-rw-r--r-- | gcc/builtins.c | 147 | ||||
-rw-r--r-- | gcc/cfgcleanup.c | 5 | ||||
-rw-r--r-- | gcc/cfgexpand.c | 2 | ||||
-rw-r--r-- | gcc/cfglayout.c | 1 | ||||
-rw-r--r-- | gcc/doc/extend.texi | 7 | ||||
-rw-r--r-- | gcc/dojump.c | 31 | ||||
-rw-r--r-- | gcc/except.c | 4 | ||||
-rw-r--r-- | gcc/final.c | 2 | ||||
-rw-r--r-- | gcc/gengtype.c | 1 | ||||
-rw-r--r-- | gcc/predict.c | 73 | ||||
-rw-r--r-- | gcc/print-rtl.c | 8 | ||||
-rw-r--r-- | gcc/rtl.h | 2 |
13 files changed, 34 insertions, 271 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 203116d..020768f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,25 @@ +2006-11-11 Jan Hubicka <jh@suse.cz> + + * extended.texi (__builtin_expect): We no longer require second argument + to be constant. + * gengtype.c (adjust_field_rtx_def): Drop NOTE_INSN_EXPECTED_VALUE. + * builtins.c (expand_builtin_expect): Simplify. + (expand_builtin_expect_jump): Kill. + * final.c (final_scan_insn): Do not skip the removed notes. + * insn-notes.def (LOOP_BEG, LOOP_END, REPEATED_LINE_NUMBER, + EXPECTED_VALUE): Remove. + * dojump.c (do_jump): Do not care about __builtin_expect. + * predict.c (expected_value_to_br_prob): Kill. + * function.c (expand_function_end): Do not expand + NOTE_INSN_REPEATED_LINE_NUMBER. + * print-rtl.c (print_rtx): Do not pretty print the removed notes. + * expect.c (sjlj_emit_function_enter): Emit directly branch probability. + * cfgexpand.c (add_reg_br_prob_note): Export. + * cfgcleanup.c (rest_of_handle_jump2): Do not call + expected_value_to_br_prob. + * cfglayout.c (duplicate_insn_chain): Do not deal with removed notes. + * rtl.h (add_reg_br_prob_note): Declare. + 2006-11-11 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> * tree-pretty-print.c (dump_generic_node): Print sign of Inf. diff --git a/gcc/builtins.c b/gcc/builtins.c index f1fa123..5aa9e6f 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -4693,9 +4693,9 @@ expand_builtin_fputs (tree arglist, rtx target, bool unlocked) return 0; } -/* Expand a call to __builtin_expect. We return our argument and emit a - NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in - a non-jump context. */ +/* Expand a call to __builtin_expect. We just return our argument + as the builtin_expect semantic should've been already executed by + tree branch prediction pass. */ static rtx expand_builtin_expect (tree arglist, rtx target) @@ -4709,149 +4709,12 @@ expand_builtin_expect (tree arglist, rtx target) exp = TREE_VALUE (arglist); c = TREE_VALUE (TREE_CHAIN (arglist)); - if (TREE_CODE (c) != INTEGER_CST) - { - error ("second argument to %<__builtin_expect%> must be a constant"); - c = integer_zero_node; - } - target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL); - - /* Don't bother with expected value notes for integral constants. */ - if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT) - { - /* We do need to force this into a register so that we can be - moderately sure to be able to correctly interpret the branch - condition later. */ - target = force_reg (GET_MODE (target), target); - - rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL); - - note = emit_note (NOTE_INSN_EXPECTED_VALUE); - NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c); - } - + /* When guessing was done, the hints should be already stripped away. */ + gcc_assert (!flag_guess_branch_prob); return target; } -/* Like expand_builtin_expect, except do this in a jump context. This is - called from do_jump if the conditional is a __builtin_expect. Return either - a list of insns to emit the jump or NULL if we cannot optimize - __builtin_expect. We need to optimize this at jump time so that machines - like the PowerPC don't turn the test into a SCC operation, and then jump - based on the test being 0/1. */ - -rtx -expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label) -{ - tree arglist = TREE_OPERAND (exp, 1); - tree arg0 = TREE_VALUE (arglist); - tree arg1 = TREE_VALUE (TREE_CHAIN (arglist)); - rtx ret = NULL_RTX; - - /* Only handle __builtin_expect (test, 0) and - __builtin_expect (test, 1). */ - if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE - && (integer_zerop (arg1) || integer_onep (arg1))) - { - rtx insn, drop_through_label, temp; - - /* Expand the jump insns. */ - start_sequence (); - do_jump (arg0, if_false_label, if_true_label); - ret = get_insns (); - - drop_through_label = get_last_insn (); - if (drop_through_label && NOTE_P (drop_through_label)) - drop_through_label = prev_nonnote_insn (drop_through_label); - if (drop_through_label && !LABEL_P (drop_through_label)) - drop_through_label = NULL_RTX; - end_sequence (); - - if (! if_true_label) - if_true_label = drop_through_label; - if (! if_false_label) - if_false_label = drop_through_label; - - /* Go through and add the expect's to each of the conditional jumps. */ - insn = ret; - while (insn != NULL_RTX) - { - rtx next = NEXT_INSN (insn); - - if (JUMP_P (insn) && any_condjump_p (insn)) - { - rtx ifelse = SET_SRC (pc_set (insn)); - rtx then_dest = XEXP (ifelse, 1); - rtx else_dest = XEXP (ifelse, 2); - int taken = -1; - - /* First check if we recognize any of the labels. */ - if (GET_CODE (then_dest) == LABEL_REF - && XEXP (then_dest, 0) == if_true_label) - taken = 1; - else if (GET_CODE (then_dest) == LABEL_REF - && XEXP (then_dest, 0) == if_false_label) - taken = 0; - else if (GET_CODE (else_dest) == LABEL_REF - && XEXP (else_dest, 0) == if_false_label) - taken = 1; - else if (GET_CODE (else_dest) == LABEL_REF - && XEXP (else_dest, 0) == if_true_label) - taken = 0; - /* Otherwise check where we drop through. */ - else if (else_dest == pc_rtx) - { - if (next && NOTE_P (next)) - next = next_nonnote_insn (next); - - if (next && JUMP_P (next) - && any_uncondjump_p (next)) - temp = XEXP (SET_SRC (pc_set (next)), 0); - else - temp = next; - - /* TEMP is either a CODE_LABEL, NULL_RTX or something - else that can't possibly match either target label. */ - if (temp == if_false_label) - taken = 1; - else if (temp == if_true_label) - taken = 0; - } - else if (then_dest == pc_rtx) - { - if (next && NOTE_P (next)) - next = next_nonnote_insn (next); - - if (next && JUMP_P (next) - && any_uncondjump_p (next)) - temp = XEXP (SET_SRC (pc_set (next)), 0); - else - temp = next; - - if (temp == if_false_label) - taken = 0; - else if (temp == if_true_label) - taken = 1; - } - - if (taken != -1) - { - /* If the test is expected to fail, reverse the - probabilities. */ - if (integer_zerop (arg1)) - taken = 1 - taken; - predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken); - } - } - - insn = next; - } - } - - return ret; -} - void expand_builtin_trap (void) { diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c index 33c26fb..046ee77 100644 --- a/gcc/cfgcleanup.c +++ b/gcc/cfgcleanup.c @@ -2300,11 +2300,6 @@ struct tree_opt_pass pass_jump = static unsigned int rest_of_handle_jump2 (void) { - /* Turn NOTE_INSN_EXPECTED_VALUE into REG_BR_PROB. Do this - before jump optimization switches branch directions. */ - if (flag_guess_branch_prob) - expected_value_to_br_prob (); - delete_trivially_dead_insns (get_insns (), max_reg_num ()); reg_scan (get_insns (), max_reg_num ()); if (dump_file) diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index b688917..76f603f 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -45,7 +45,7 @@ Boston, MA 02110-1301, USA. */ ??? We really ought to pass the probability down to RTL expanders and let it re-distribute it when the conditional expands into multiple conditionals. This is however difficult to do. */ -static void +void add_reg_br_prob_note (rtx last, int probability) { if (profile_status == PROFILE_ABSENT) diff --git a/gcc/cfglayout.c b/gcc/cfglayout.c index 51a0a3b..6bd63c2 100644 --- a/gcc/cfglayout.c +++ b/gcc/cfglayout.c @@ -997,7 +997,6 @@ duplicate_insn_chain (rtx from, rtx to) case NOTE_INSN_BASIC_BLOCK: break; - case NOTE_INSN_REPEATED_LINE_NUMBER: case NOTE_INSN_SWITCH_TEXT_SECTIONS: emit_note_copy (insn); break; diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 1579b94..2a1391e 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -5874,10 +5874,9 @@ programmers are notoriously bad at predicting how their programs actually perform. However, there are applications in which this data is hard to collect. -The return value is the value of @var{exp}, which should be an -integral expression. The value of @var{c} must be a compile-time -constant. The semantics of the built-in are that it is expected -that @var{exp} == @var{c}. For example: +The return value is the value of @var{exp}, which should be an integral +expression. The semantics of the built-in are that it is expected that +@var{exp} == @var{c}. For example: @smallexample if (__builtin_expect (x, 0)) diff --git a/gcc/dojump.c b/gcc/dojump.c index be0f2d4..05bcd9b 100644 --- a/gcc/dojump.c +++ b/gcc/dojump.c @@ -551,37 +551,6 @@ do_jump (tree exp, rtx if_false_label, rtx if_true_label) } break; - /* Special case: - __builtin_expect (<test>, 0) and - __builtin_expect (<test>, 1) - - We need to do this here, so that <test> is not converted to a SCC - operation on machines that use condition code registers and COMPARE - like the PowerPC, and then the jump is done based on whether the SCC - operation produced a 1 or 0. */ - case CALL_EXPR: - /* Check for a built-in function. */ - { - tree fndecl = get_callee_fndecl (exp); - tree arglist = TREE_OPERAND (exp, 1); - - if (fndecl - && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL - && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_EXPECT - && arglist != NULL_TREE - && TREE_CHAIN (arglist) != NULL_TREE) - { - rtx seq = expand_builtin_expect_jump (exp, if_false_label, - if_true_label); - - if (seq != NULL_RTX) - { - emit_insn (seq); - return; - } - } - } - /* Fall through and generate the normal code. */ default: normal: diff --git a/gcc/except.c b/gcc/except.c index 39827c9..4bfebcf 100644 --- a/gcc/except.c +++ b/gcc/except.c @@ -1875,11 +1875,9 @@ sjlj_emit_function_enter (rtx dispatch_label) plus_constant (XEXP (fc, 0), sjlj_fc_jbuf_ofs), Pmode); - note = emit_note (NOTE_INSN_EXPECTED_VALUE); - NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, x, const0_rtx); - emit_cmp_and_jump_insns (x, const0_rtx, NE, 0, TYPE_MODE (integer_type_node), 0, dispatch_label); + add_reg_br_prob_note (get_insns (), REG_BR_PROB_BASE/100); } #else expand_builtin_setjmp_setup (plus_constant (XEXP (fc, 0), sjlj_fc_jbuf_ofs), diff --git a/gcc/final.c b/gcc/final.c index 9fd59d4..9b3d696 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -1698,8 +1698,6 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED, { case NOTE_INSN_DELETED: case NOTE_INSN_FUNCTION_END: - case NOTE_INSN_REPEATED_LINE_NUMBER: - case NOTE_INSN_EXPECTED_VALUE: break; case NOTE_INSN_SWITCH_TEXT_SECTIONS: diff --git a/gcc/gengtype.c b/gcc/gengtype.c index 2ca4ac7..1464c5f 100644 --- a/gcc/gengtype.c +++ b/gcc/gengtype.c @@ -519,7 +519,6 @@ adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt)) note_flds = create_field (note_flds, tree_tp, "rt_tree"); break; - case NOTE_INSN_EXPECTED_VALUE: case NOTE_INSN_VAR_LOCATION: note_flds = create_field (note_flds, rtx_tp, "rt_rtx"); break; diff --git a/gcc/predict.c b/gcc/predict.c index 9661322..5dd9e60 100644 --- a/gcc/predict.c +++ b/gcc/predict.c @@ -1340,79 +1340,6 @@ tree_estimate_probability (void) return 0; } -/* __builtin_expect dropped tokens into the insn stream describing expected - values of registers. Generate branch probabilities based off these - values. */ - -void -expected_value_to_br_prob (void) -{ - rtx insn, cond, ev = NULL_RTX, ev_reg = NULL_RTX; - - for (insn = get_insns (); insn ; insn = NEXT_INSN (insn)) - { - switch (GET_CODE (insn)) - { - case NOTE: - /* Look for expected value notes. */ - if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EXPECTED_VALUE) - { - ev = NOTE_EXPECTED_VALUE (insn); - ev_reg = XEXP (ev, 0); - delete_insn (insn); - } - continue; - - case CODE_LABEL: - /* Never propagate across labels. */ - ev = NULL_RTX; - continue; - - case JUMP_INSN: - /* Look for simple conditional branches. If we haven't got an - expected value yet, no point going further. */ - if (!JUMP_P (insn) || ev == NULL_RTX - || ! any_condjump_p (insn)) - continue; - break; - - default: - /* Look for insns that clobber the EV register. */ - if (ev && reg_set_p (ev_reg, insn)) - ev = NULL_RTX; - continue; - } - - /* Collect the branch condition, hopefully relative to EV_REG. */ - /* ??? At present we'll miss things like - (expected_value (eq r70 0)) - (set r71 -1) - (set r80 (lt r70 r71)) - (set pc (if_then_else (ne r80 0) ...)) - as canonicalize_condition will render this to us as - (lt r70, r71) - Could use cselib to try and reduce this further. */ - cond = XEXP (SET_SRC (pc_set (insn)), 0); - cond = canonicalize_condition (insn, cond, 0, NULL, ev_reg, - false, false); - if (! cond || XEXP (cond, 0) != ev_reg - || GET_CODE (XEXP (cond, 1)) != CONST_INT) - continue; - - /* Substitute and simplify. Given that the expression we're - building involves two constants, we should wind up with either - true or false. */ - cond = gen_rtx_fmt_ee (GET_CODE (cond), VOIDmode, - XEXP (ev, 1), XEXP (cond, 1)); - cond = simplify_rtx (cond); - - /* Turn the condition into a scaled branch probability. */ - gcc_assert (cond == const_true_rtx || cond == const0_rtx); - predict_insn_def (insn, PRED_BUILTIN_EXPECT, - cond == const_true_rtx ? TAKEN : NOT_TAKEN); - } -} - /* Check whether this is the last basic block of function. Commonly there is one extra common cleanup block. */ static bool diff --git a/gcc/print-rtl.c b/gcc/print-rtl.c index a9c1a93..d8ddc9b 100644 --- a/gcc/print-rtl.c +++ b/gcc/print-rtl.c @@ -299,14 +299,6 @@ print_rtx (rtx in_rtx) break; } - case NOTE_INSN_EXPECTED_VALUE: - indent += 2; - if (!sawclose) - fprintf (outfile, " "); - print_rtx (NOTE_EXPECTED_VALUE (in_rtx)); - indent -= 2; - break; - case NOTE_INSN_DELETED_LABEL: { const char *label = NOTE_DELETED_LABEL_NAME (in_rtx); @@ -2250,6 +2250,8 @@ extern GTY(()) rtx stack_limit_rtx; /* In predict.c */ extern void invert_br_probabilities (rtx); extern bool expensive_function_p (int); +/* In cfgexpand.c */ +extern void add_reg_br_prob_note (rtx last, int probability); /* In tracer.c */ extern void tracer (unsigned int); |