OSDN Git Service

* extended.texi (__builtin_expect): We no longer require second argument
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 11 Nov 2006 16:54:57 +0000 (16:54 +0000)
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 11 Nov 2006 16:54:57 +0000 (16:54 +0000)
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@118696 138bc75d-0d04-0410-961f-82ee72b054a4

13 files changed:
gcc/ChangeLog
gcc/builtins.c
gcc/cfgcleanup.c
gcc/cfgexpand.c
gcc/cfglayout.c
gcc/doc/extend.texi
gcc/dojump.c
gcc/except.c
gcc/final.c
gcc/gengtype.c
gcc/predict.c
gcc/print-rtl.c
gcc/rtl.h

index 203116d..020768f 100644 (file)
@@ -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.
index f1fa123..5aa9e6f 100644 (file)
@@ -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)
 {
index 33c26fb..046ee77 100644 (file)
@@ -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)
index b688917..76f603f 100644 (file)
@@ -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)
index 51a0a3b..6bd63c2 100644 (file)
@@ -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;
index 1579b94..2a1391e 100644 (file)
@@ -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))
index be0f2d4..05bcd9b 100644 (file)
@@ -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:
index 39827c9..4bfebcf 100644 (file)
@@ -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),
index 9fd59d4..9b3d696 100644 (file)
@@ -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:
index 2ca4ac7..1464c5f 100644 (file)
@@ -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;
index 9661322..5dd9e60 100644 (file)
@@ -1340,79 +1340,6 @@ tree_estimate_probability (void)
   return 0;
 }
 \f
-/* __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);
-    }
-}
-\f
 /* Check whether this is the last basic block of function.  Commonly
    there is one extra common cleanup block.  */
 static bool
index a9c1a93..d8ddc9b 100644 (file)
@@ -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);
index abc3d5a..54dad70 100644 (file)
--- 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);