OSDN Git Service

* loop.c (canonicalize_condition): Add WANT_REG argument.
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 17 Apr 2000 19:21:09 +0000 (19:21 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 17 Apr 2000 19:21:09 +0000 (19:21 +0000)
        Stop the search if we match it.
        * expr.h (canonicalize_condition): Update decl.
        * predict.c (expected_value_to_br_prob): Use it.  Track last
        expected value note.
        (find_expected_value): Remove.

        * reorg.c (mostly_true_jump): Always use BR_PROB if present.

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

gcc/ChangeLog
gcc/expr.h
gcc/loop.c
gcc/predict.c
gcc/reorg.c

index b87c030..9fcbff8 100644 (file)
@@ -1,3 +1,14 @@
+2000-04-17  Richard Henderson  <rth@cygnus.com>
+
+       * loop.c (canonicalize_condition): Add WANT_REG argument.
+       Stop the search if we match it.
+       * expr.h (canonicalize_condition): Update decl.
+       * predict.c (expected_value_to_br_prob): Use it.  Track last
+       expected value note.
+       (find_expected_value): Remove.
+
+       * reorg.c (mostly_true_jump): Always use BR_PROB if present.
+
 2000-04-17  Zack Weinberg  <zack@wolery.cumb.org>
 
        * aclocal.m4 (AM_GNU_GETTEXT): Don't AC_REQUIRE([AC_FUNC_MMAP]).
index a349d9a..8d7a9d8 100644 (file)
@@ -894,7 +894,7 @@ extern rtx emit_store_flag_force PARAMS ((rtx, enum rtx_code, rtx, rtx,
 
 /* Given an insn and condition, return a canonical description of
    the test being made.  */
-extern rtx canonicalize_condition PARAMS ((rtx, rtx, int, rtx *));
+extern rtx canonicalize_condition PARAMS ((rtx, rtx, int, rtx *, rtx));
 
 /* Given a JUMP_INSN, return a canonical description of the test
    being made.  */
index cbb1731..8a3eb4d 100644 (file)
@@ -9013,14 +9013,19 @@ update_reg_last_use (x, insn)
    If EARLIEST is non-zero, it is a pointer to a place where the earliest
    insn used in locating the condition was found.  If a replacement test
    of the condition is desired, it should be placed in front of that
-   insn and we will be sure that the inputs are still valid.  */
+   insn and we will be sure that the inputs are still valid.
+
+   If WANT_REG is non-zero, we wish the condition to be relative to that
+   register, if possible.  Therefore, do not canonicalize the condition
+   further.  */
 
 rtx
-canonicalize_condition (insn, cond, reverse, earliest)
+canonicalize_condition (insn, cond, reverse, earliest, want_reg)
      rtx insn;
      rtx cond;
      int reverse;
      rtx *earliest;
+     rtx want_reg;
 {
   enum rtx_code code;
   rtx prev = insn;
@@ -9050,7 +9055,9 @@ canonicalize_condition (insn, cond, reverse, earliest)
      the same tests as a function of STORE_FLAG_VALUE as find_comparison_args
      in cse.c  */
 
-  while (GET_RTX_CLASS (code) == '<' && op1 == CONST0_RTX (GET_MODE (op0)))
+  while (GET_RTX_CLASS (code) == '<'
+         && op1 == CONST0_RTX (GET_MODE (op0))
+        && op0 != want_reg)
     {
       /* Set non-zero when we find something of interest.  */
       rtx x = 0;
@@ -9291,7 +9298,7 @@ get_condition (jump, earliest)
     = GET_CODE (XEXP (SET_SRC (PATTERN (jump)), 2)) == LABEL_REF
       && XEXP (XEXP (SET_SRC (PATTERN (jump)), 2), 0) == JUMP_LABEL (jump);
 
-  return canonicalize_condition (jump, cond, reverse, earliest);
+  return canonicalize_condition (jump, cond, reverse, earliest, NULL_RTX);
 }
 
 /* Similar to above routine, except that we also put an invariant last
index 767afdc..958dbf9 100644 (file)
@@ -190,29 +190,46 @@ static rtx find_expected_value            PARAMS ((rtx, rtx));
 void
 expected_value_to_br_prob ()
 {
-  rtx insn, cond, earliest, ev;
+  rtx insn, cond, ev = NULL_RTX, ev_reg;
 
   for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
     {
-      /* Look for simple conditional branches.  */
-      if (GET_CODE (insn) != JUMP_INSN)
-       continue;
-      if (! condjump_p (insn) || simplejump_p (insn))
-       continue;
+      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);
+           }
+         continue;
+
+       case CODE_LABEL:
+         /* Never propagate across labels.  */
+         ev = NULL_RTX;
+         continue;
 
-      /* Collect the branch condition.  Some machines can branch on
-        user values directly, others need a compare instruction.  If
-        the branch condition involves a MODE_INT register, try that
-        expression first.  Otherwise use get_condition.  */
+       default:
+         /* Look for insns that clobber the EV register.  */
+         if (ev && reg_set_p (ev_reg, insn))
+           ev = NULL_RTX;
+         continue;
+
+       case JUMP_INSN:
+         /* Look for simple conditional branches.  If we havn't got an
+            expected value yet, no point going further.  */
+         if (GET_CODE (insn) != JUMP_INSN || ev == NULL_RTX)
+           continue;
+         if (! condjump_p (insn) || simplejump_p (insn))
+           continue;
+         break;
+       }
+
+      /* Collect the branch condition, hopefully relative to EV_REG.  */
       cond = XEXP (SET_SRC (PATTERN (insn)), 0);
-      if (GET_RTX_CLASS (GET_CODE (cond)) != '<')
-       abort ();
-      if (GET_CODE (XEXP (cond, 0)) == REG
-         && GET_MODE_CLASS (GET_MODE (XEXP (cond, 0))) == MODE_INT
-         && (ev = find_expected_value (cond, insn)) != NULL_RTX)
-       ;
-      else if ((cond = get_condition (insn, &earliest)) == NULL_RTX
-              || (ev = find_expected_value (cond, earliest)) == NULL_RTX)
+      cond = canonicalize_condition (insn, cond, 0, NULL, ev_reg);
+      if (! cond || XEXP (cond, 0) != ev_reg)
        continue;
 
       /* Substitute and simplify.  Given that the expression we're 
@@ -223,48 +240,10 @@ expected_value_to_br_prob ()
       cond = simplify_rtx (cond);
 
       /* Turn the condition into a scaled branch probability.  */
-      if (cond == const0_rtx)
-       cond = const1_rtx;
-      else if (cond == const1_rtx)
-       cond = GEN_INT (REG_BR_PROB_BASE - 1);
-      else
+      if (cond == const1_rtx)
+       cond = GEN_INT (REG_BR_PROB_BASE);
+      else if (cond != const0_rtx)
        abort ();
       REG_NOTES (insn) = alloc_EXPR_LIST (REG_BR_PROB, cond, REG_NOTES (insn));
     }
 }
-
-/* Search backwards for a NOTE_INSN_EXPECTED_VALUE note with a register
-   that matches the condition.  */
-
-static rtx
-find_expected_value (cond, earliest)
-     rtx cond, earliest;
-{
-  rtx insn, reg = XEXP (cond, 0);
-  int timeout;
-
-  /* The condition should be (op (reg) (const_int)), otherwise we
-     won't be able to intuit anything about it.  */
-  if (GET_CODE (reg) != REG
-      || GET_CODE (XEXP (cond, 1)) != CONST_INT
-      || GET_MODE_CLASS (GET_MODE (reg)) != MODE_INT)
-    return NULL_RTX;
-
-  /* Assuming the user wrote something like `if (__builtin_expect(...))',
-     we shouldn't have to search too far.  Also stop if we reach a code
-     label or if REG is modified.  */
-  for (insn = earliest, timeout = 10;
-       insn && timeout > 0;
-       insn = PREV_INSN (insn), --timeout)
-    {
-      if (GET_CODE (insn) == NOTE
-         && NOTE_LINE_NUMBER (insn) == NOTE_INSN_EXPECTED_VALUE
-         && XEXP (NOTE_EXPECTED_VALUE (insn), 0) == reg)
-       return NOTE_EXPECTED_VALUE (insn);
-
-      if (GET_CODE (insn) == CODE_LABEL || reg_set_p (reg, insn))
-       break;
-    }
-
-  return NULL_RTX;
-}
index 379def7..cce40c0 100644 (file)
@@ -900,30 +900,29 @@ mostly_true_jump (jump_insn, condition)
      rtx jump_insn, condition;
 {
   rtx target_label = JUMP_LABEL (jump_insn);
-  rtx insn;
+  rtx insn, note;
   int rare_dest = rare_destination (target_label);
   int rare_fallthrough = rare_destination (NEXT_INSN (jump_insn));
 
   /* If branch probabilities are available, then use that number since it
      always gives a correct answer.  */
-  if (flag_branch_probabilities)
+  note = find_reg_note (jump_insn, REG_BR_PROB, 0);
+  if (note)
     {
-      rtx note = find_reg_note (jump_insn, REG_BR_PROB, 0);
-      if (note)
-       {
-         int prob = XINT (note, 0);
+      int prob = INTVAL (XEXP (note, 0));
 
-         if (prob >= REG_BR_PROB_BASE * 9 / 10)
-           return 2;
-         else if (prob >= REG_BR_PROB_BASE / 2)
-           return 1;
-         else if (prob >= REG_BR_PROB_BASE / 10)
-           return 0;
-         else
-           return -1;
-       }
+      if (prob >= REG_BR_PROB_BASE * 9 / 10)
+        return 2;
+      else if (prob >= REG_BR_PROB_BASE / 2)
+        return 1;
+      else if (prob >= REG_BR_PROB_BASE / 10)
+        return 0;
+      else
+        return -1;
     }
 
+  /* ??? Ought to use estimate_probability instead.  */
+
   /* If this is a branch outside a loop, it is highly unlikely.  */
   if (GET_CODE (PATTERN (jump_insn)) == SET
       && GET_CODE (SET_SRC (PATTERN (jump_insn))) == IF_THEN_ELSE