aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog22
-rw-r--r--gcc/builtins.c147
-rw-r--r--gcc/cfgcleanup.c5
-rw-r--r--gcc/cfgexpand.c2
-rw-r--r--gcc/cfglayout.c1
-rw-r--r--gcc/doc/extend.texi7
-rw-r--r--gcc/dojump.c31
-rw-r--r--gcc/except.c4
-rw-r--r--gcc/final.c2
-rw-r--r--gcc/gengtype.c1
-rw-r--r--gcc/predict.c73
-rw-r--r--gcc/print-rtl.c8
-rw-r--r--gcc/rtl.h2
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);
diff --git a/gcc/rtl.h b/gcc/rtl.h
index abc3d5a..54dad70 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -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);