OSDN Git Service

PR preprocessor/19475
[pf3gnuchains/gcc-fork.git] / gcc / jump.c
index 6ead322..dc81c52 100644 (file)
@@ -1,6 +1,7 @@
 /* Optimize jump instructions, for GNU compiler.
    Copyright (C) 1987, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997
-   1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+   Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -67,9 +68,7 @@ static void init_label_info (rtx);
 static void mark_all_labels (rtx);
 static void delete_computation (rtx);
 static void redirect_exp_1 (rtx *, rtx, rtx, rtx);
-static int redirect_exp (rtx, rtx, rtx);
-static void invert_exp_1 (rtx);
-static int invert_exp (rtx);
+static int invert_exp_1 (rtx, rtx);
 static int returnjump_p_1 (rtx *, void *);
 static void delete_prior_computation (rtx, rtx);
 \f
@@ -90,7 +89,7 @@ rebuild_jump_labels (rtx f)
      count doesn't drop to zero.  */
 
   for (insn = forced_labels; insn; insn = XEXP (insn, 1))
-    if (GET_CODE (XEXP (insn, 0)) == CODE_LABEL)
+    if (LABEL_P (XEXP (insn, 0)))
       LABEL_NUSES (XEXP (insn, 0))++;
   timevar_pop (TV_REBUILD_JUMP);
 }
@@ -110,11 +109,11 @@ cleanup_barriers (void)
   for (insn = get_insns (); insn; insn = next)
     {
       next = NEXT_INSN (insn);
-      if (GET_CODE (insn) == BARRIER)
+      if (BARRIER_P (insn))
        {
          prev = prev_nonnote_insn (insn);
-         if (GET_CODE (prev) == BARRIER)
-           delete_barrier (insn);
+         if (BARRIER_P (prev))
+           delete_insn (insn);
          else if (prev != PREV_INSN (insn))
            reorder_insns (insn, insn, prev);
        }
@@ -132,7 +131,7 @@ purge_line_number_notes (rtx f)
      even if it became empty.  */
 
   for (insn = f; insn; insn = NEXT_INSN (insn))
-    if (GET_CODE (insn) == NOTE)
+    if (NOTE_P (insn))
       {
        if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_BEG)
          /* Any previous line note was for the prologue; gdb wants a new
@@ -142,8 +141,13 @@ purge_line_number_notes (rtx f)
          {
            /* Delete this note if it is identical to previous note.  */
            if (last_note
+#ifdef USE_MAPPED_LOCATION
+               && NOTE_SOURCE_LOCATION (insn) == NOTE_SOURCE_LOCATION (last_note)
+#else
                && NOTE_SOURCE_FILE (insn) == NOTE_SOURCE_FILE (last_note)
-               && NOTE_LINE_NUMBER (insn) == NOTE_LINE_NUMBER (last_note))
+               && NOTE_LINE_NUMBER (insn) == NOTE_LINE_NUMBER (last_note)
+#endif
+)
              {
                delete_related_insns (insn);
                continue;
@@ -163,11 +167,11 @@ init_label_info (rtx f)
   rtx insn;
 
   for (insn = f; insn; insn = NEXT_INSN (insn))
-    if (GET_CODE (insn) == CODE_LABEL)
+    if (LABEL_P (insn))
       LABEL_NUSES (insn) = (LABEL_PRESERVE_P (insn) != 0);
-    else if (GET_CODE (insn) == JUMP_INSN)
+    else if (JUMP_P (insn))
       JUMP_LABEL (insn) = 0;
-    else if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
+    else if (NONJUMP_INSN_P (insn) || CALL_P (insn))
       {
        rtx note, next;
 
@@ -192,28 +196,8 @@ mark_all_labels (rtx f)
   for (insn = f; insn; insn = NEXT_INSN (insn))
     if (INSN_P (insn))
       {
-       if (GET_CODE (insn) == CALL_INSN
-           && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
-         {
-           mark_all_labels (XEXP (PATTERN (insn), 0));
-           mark_all_labels (XEXP (PATTERN (insn), 1));
-           mark_all_labels (XEXP (PATTERN (insn), 2));
-
-           /* Canonicalize the tail recursion label attached to the
-              CALL_PLACEHOLDER insn.  */
-           if (XEXP (PATTERN (insn), 3))
-             {
-               rtx label_ref = gen_rtx_LABEL_REF (VOIDmode,
-                                                  XEXP (PATTERN (insn), 3));
-               mark_jump_label (label_ref, insn, 0);
-               XEXP (PATTERN (insn), 3) = XEXP (label_ref, 0);
-             }
-
-           continue;
-         }
-
        mark_jump_label (PATTERN (insn), insn, 0);
-       if (! INSN_DELETED_P (insn) && GET_CODE (insn) == JUMP_INSN)
+       if (! INSN_DELETED_P (insn) && JUMP_P (insn))
          {
            /* When we know the LABEL_REF contained in a REG used in
               an indirect jump, we'll have a REG_LABEL note so that
@@ -257,14 +241,16 @@ squeeze_notes (rtx* startp, rtx* endp)
   for (insn = start; insn != past_end; insn = next)
     {
       next = NEXT_INSN (insn);
-      if (GET_CODE (insn) == NOTE
+      if (NOTE_P (insn)
          && (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END
              || NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG
              || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG
-             || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END
-             || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_CONT
-             || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_VTOP))
+             || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END))
        {
+         /* BLOCK_BEG or BLOCK_END notes only exist in the `final' pass.  */
+         gcc_assert (NOTE_LINE_NUMBER (insn) != NOTE_INSN_BLOCK_BEG
+                     && NOTE_LINE_NUMBER (insn) != NOTE_INSN_BLOCK_END);
+
          if (insn == start)
            start = next;
          else
@@ -304,7 +290,7 @@ get_label_before (rtx insn)
      or make a new one if there is none.  */
   label = prev_nonnote_insn (insn);
 
-  if (label == 0 || GET_CODE (label) != CODE_LABEL)
+  if (label == 0 || !LABEL_P (label))
     {
       rtx prev = PREV_INSN (insn);
 
@@ -326,7 +312,7 @@ get_label_after (rtx insn)
      or make a new one if there is none.  */
   label = next_nonnote_insn (insn);
 
-  if (label == 0 || GET_CODE (label) != CODE_LABEL)
+  if (label == 0 || !LABEL_P (label))
     {
       label = gen_label_rtx ();
       emit_label_after (label, insn);
@@ -408,7 +394,7 @@ reversed_comparison_code_parts (enum rtx_code code, rtx arg0, rtx arg1, rtx insn
        return UNKNOWN;
 
       for (prev = prev_nonnote_insn (insn);
-          prev != 0 && GET_CODE (prev) != CODE_LABEL;
+          prev != 0 && !LABEL_P (prev);
           prev = prev_nonnote_insn (prev))
        {
          rtx set = set_of (arg0, prev);
@@ -463,6 +449,20 @@ reversed_comparison_code (rtx comparison, rtx insn)
                                         XEXP (comparison, 0),
                                         XEXP (comparison, 1), insn);
 }
+
+/* Return comparison with reversed code of EXP.
+   Return NULL_RTX in case we fail to do the reversal.  */
+rtx
+reversed_comparison (rtx exp, enum machine_mode mode)
+{
+  enum rtx_code reversed_code = reversed_comparison_code (exp, NULL_RTX);
+  if (reversed_code == UNKNOWN)
+    return NULL_RTX;
+  else
+    return simplify_gen_relational (reversed_code, mode, VOIDmode,
+                                    XEXP (exp, 0), XEXP (exp, 1));
+}
+
 \f
 /* Given an rtx-code for a comparison, return the code for the negated
    comparison.  If no such code exists, return UNKNOWN.
@@ -751,7 +751,7 @@ comparison_dominates_p (enum rtx_code code1, enum rtx_code code2)
 int
 simplejump_p (rtx insn)
 {
-  return (GET_CODE (insn) == JUMP_INSN
+  return (JUMP_P (insn)
          && GET_CODE (PATTERN (insn)) == SET
          && GET_CODE (SET_DEST (PATTERN (insn))) == PC
          && GET_CODE (SET_SRC (PATTERN (insn))) == LABEL_REF);
@@ -783,8 +783,6 @@ condjump_p (rtx insn)
                || (GET_CODE (XEXP (x, 1)) == PC
                    && (GET_CODE (XEXP (x, 2)) == LABEL_REF
                        || GET_CODE (XEXP (x, 2)) == RETURN))));
-
-  return 0;
 }
 
 /* Return nonzero if INSN is a (possibly) conditional jump inside a
@@ -828,7 +826,7 @@ rtx
 pc_set (rtx insn)
 {
   rtx pat;
-  if (GET_CODE (insn) != JUMP_INSN)
+  if (!JUMP_P (insn))
     return NULL_RTX;
   pat = PATTERN (insn);
 
@@ -918,7 +916,7 @@ returnjump_p_1 (rtx *loc, void *data ATTRIBUTE_UNUSED)
 int
 returnjump_p (rtx insn)
 {
-  if (GET_CODE (insn) != JUMP_INSN)
+  if (!JUMP_P (insn))
     return 0;
   return for_each_rtx (&PATTERN (insn), returnjump_p_1, NULL);
 }
@@ -931,7 +929,7 @@ onlyjump_p (rtx insn)
 {
   rtx set;
 
-  if (GET_CODE (insn) != JUMP_INSN)
+  if (!JUMP_P (insn))
     return 0;
 
   set = single_set (insn);
@@ -1018,12 +1016,12 @@ follow_jumps (rtx label)
   for (depth = 0;
        (depth < 10
        && (insn = next_active_insn (value)) != 0
-       && GET_CODE (insn) == JUMP_INSN
+       && JUMP_P (insn)
        && ((JUMP_LABEL (insn) != 0 && any_uncondjump_p (insn)
             && onlyjump_p (insn))
            || GET_CODE (PATTERN (insn)) == RETURN)
        && (next = NEXT_INSN (insn))
-       && GET_CODE (next) == BARRIER);
+       && BARRIER_P (next));
        depth++)
     {
       /* Don't chain through the insn that jumps into a loop
@@ -1033,7 +1031,7 @@ follow_jumps (rtx label)
       rtx tem;
       if (!reload_completed)
        for (tem = value; tem != insn; tem = NEXT_INSN (tem))
-         if (GET_CODE (tem) == NOTE
+         if (NOTE_P (tem)
              && (NOTE_LINE_NUMBER (tem) == NOTE_INSN_LOOP_BEG
                  /* ??? Optional.  Disables some optimizations, but makes
                     gcov output more accurate with -O.  */
@@ -1107,11 +1105,11 @@ mark_jump_label (rtx x, rtx insn, int in_mem)
 
        /* Ignore remaining references to unreachable labels that
           have been deleted.  */
-       if (GET_CODE (label) == NOTE
+       if (NOTE_P (label)
            && NOTE_LINE_NUMBER (label) == NOTE_INSN_DELETED_LABEL)
          break;
 
-       if (GET_CODE (label) != CODE_LABEL)
+       if (!LABEL_P (label))
          abort ();
 
        /* Ignore references to labels of containing functions.  */
@@ -1124,7 +1122,7 @@ mark_jump_label (rtx x, rtx insn, int in_mem)
 
        if (insn)
          {
-           if (GET_CODE (insn) == JUMP_INSN)
+           if (JUMP_P (insn))
              JUMP_LABEL (insn) = label;
            else
              {
@@ -1184,17 +1182,6 @@ delete_jump (rtx insn)
     delete_computation (insn);
 }
 
-/* Verify INSN is a BARRIER and delete it.  */
-
-void
-delete_barrier (rtx insn)
-{
-  if (GET_CODE (insn) != BARRIER)
-    abort ();
-
-  delete_insn (insn);
-}
-
 /* Recursively delete prior insns that compute the value (used only by INSN
    which the caller is deleting) stored in the register mentioned by NOTE
    which is a REG_DEAD note associated with INSN.  */
@@ -1206,15 +1193,15 @@ delete_prior_computation (rtx note, rtx insn)
   rtx reg = XEXP (note, 0);
 
   for (our_prev = prev_nonnote_insn (insn);
-       our_prev && (GET_CODE (our_prev) == INSN
-                   || GET_CODE (our_prev) == CALL_INSN);
+       our_prev && (NONJUMP_INSN_P (our_prev)
+                   || CALL_P (our_prev));
        our_prev = prev_nonnote_insn (our_prev))
     {
       rtx pat = PATTERN (our_prev);
 
       /* If we reach a CALL which is not calling a const function
         or the callee pops the arguments, then give up.  */
-      if (GET_CODE (our_prev) == CALL_INSN
+      if (CALL_P (our_prev)
          && (! CONST_OR_PURE_CALL_P (our_prev)
              || GET_CODE (pat) != SET || GET_CODE (SET_SRC (pat)) != CALL))
        break;
@@ -1227,14 +1214,14 @@ delete_prior_computation (rtx note, rtx insn)
        break;
 
       if (GET_CODE (pat) == USE
-         && GET_CODE (XEXP (pat, 0)) == INSN)
+         && NONJUMP_INSN_P (XEXP (pat, 0)))
        /* reorg creates USEs that look like this.  We leave them
           alone because reorg needs them for its own purposes.  */
        break;
 
       if (reg_set_p (reg, pat))
        {
-         if (side_effects_p (pat) && GET_CODE (our_prev) != CALL_INSN)
+         if (side_effects_p (pat) && !CALL_P (our_prev))
            break;
 
          if (GET_CODE (pat) == PARALLEL)
@@ -1257,7 +1244,7 @@ delete_prior_computation (rtx note, rtx insn)
                delete_computation (our_prev);
            }
          else if (GET_CODE (pat) == SET
-                  && GET_CODE (SET_DEST (pat)) == REG)
+                  && REG_P (SET_DEST (pat)))
            {
              int dest_regno = REGNO (SET_DEST (pat));
              int dest_endregno
@@ -1340,7 +1327,7 @@ delete_computation (rtx insn)
         will use them.  So if the previous insn
         exists to set the CC's, delete it
         (unless it performs auto-increments, etc.).  */
-      if (prev && GET_CODE (prev) == INSN
+      if (prev && NONJUMP_INSN_P (prev)
          && sets_cc0_p (PATTERN (prev)))
        {
          if (sets_cc0_p (PATTERN (prev)) > 0
@@ -1360,7 +1347,7 @@ delete_computation (rtx insn)
 
       if (REG_NOTE_KIND (note) != REG_DEAD
          /* Verify that the REG_NOTE is legitimate.  */
-         || GET_CODE (XEXP (note, 0)) != REG)
+         || !REG_P (XEXP (note, 0)))
        continue;
 
       delete_prior_computation (note, insn);
@@ -1380,7 +1367,7 @@ delete_computation (rtx insn)
 rtx
 delete_related_insns (rtx insn)
 {
-  int was_code_label = (GET_CODE (insn) == CODE_LABEL);
+  int was_code_label = (LABEL_P (insn));
   rtx note;
   rtx next = NEXT_INSN (insn), prev = PREV_INSN (insn);
 
@@ -1396,13 +1383,13 @@ delete_related_insns (rtx insn)
   /* If instruction is followed by a barrier,
      delete the barrier too.  */
 
-  if (next != 0 && GET_CODE (next) == BARRIER)
+  if (next != 0 && BARRIER_P (next))
     delete_insn (next);
 
   /* If deleting a jump, decrement the count of the label,
      and delete the label if it is now unused.  */
 
-  if (GET_CODE (insn) == JUMP_INSN && JUMP_LABEL (insn))
+  if (JUMP_P (insn) && JUMP_LABEL (insn))
     {
       rtx lab = JUMP_LABEL (insn), lab_next;
 
@@ -1433,7 +1420,7 @@ delete_related_insns (rtx insn)
 
   /* Likewise if we're deleting a dispatch table.  */
 
-  if (GET_CODE (insn) == JUMP_INSN
+  if (JUMP_P (insn)
       && (GET_CODE (PATTERN (insn)) == ADDR_VEC
          || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC))
     {
@@ -1450,15 +1437,15 @@ delete_related_insns (rtx insn)
     }
 
   /* Likewise for an ordinary INSN / CALL_INSN with a REG_LABEL note.  */
-  if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
+  if (NONJUMP_INSN_P (insn) || CALL_P (insn))
     for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
       if (REG_NOTE_KIND (note) == REG_LABEL
          /* This could also be a NOTE_INSN_DELETED_LABEL note.  */
-         && GET_CODE (XEXP (note, 0)) == CODE_LABEL)
+         && LABEL_P (XEXP (note, 0)))
        if (LABEL_NUSES (XEXP (note, 0)) == 0)
          delete_related_insns (XEXP (note, 0));
 
-  while (prev && (INSN_DELETED_P (prev) || GET_CODE (prev) == NOTE))
+  while (prev && (INSN_DELETED_P (prev) || NOTE_P (prev)))
     prev = PREV_INSN (prev);
 
   /* If INSN was a label and a dispatch table follows it,
@@ -1467,14 +1454,14 @@ delete_related_insns (rtx insn)
 
   if (was_code_label
       && NEXT_INSN (insn) != 0
-      && GET_CODE (NEXT_INSN (insn)) == JUMP_INSN
+      && JUMP_P (NEXT_INSN (insn))
       && (GET_CODE (PATTERN (NEXT_INSN (insn))) == ADDR_VEC
          || GET_CODE (PATTERN (NEXT_INSN (insn))) == ADDR_DIFF_VEC))
     next = delete_related_insns (NEXT_INSN (insn));
 
   /* If INSN was a label, delete insns following it if now unreachable.  */
 
-  if (was_code_label && prev && GET_CODE (prev) == BARRIER)
+  if (was_code_label && prev && BARRIER_P (prev))
     {
       enum rtx_code code;
       while (next)
@@ -1515,7 +1502,7 @@ delete_for_peephole (rtx from, rtx to)
       rtx next = NEXT_INSN (insn);
       rtx prev = PREV_INSN (insn);
 
-      if (GET_CODE (insn) != NOTE)
+      if (!NOTE_P (insn))
        {
          INSN_DELETED_P (insn) = 1;
 
@@ -1567,7 +1554,10 @@ redirect_exp_1 (rtx *loc, rtx olabel, rtx nlabel, rtx insn)
     }
   else if (code == RETURN && olabel == 0)
     {
-      x = gen_rtx_LABEL_REF (VOIDmode, nlabel);
+      if (nlabel)
+       x = gen_rtx_LABEL_REF (VOIDmode, nlabel);
+      else
+       x = gen_rtx_RETURN (VOIDmode);
       if (loc == &PATTERN (insn))
        x = gen_rtx_SET (VOIDmode, pc_rtx, x);
       validate_change (insn, loc, x, 1);
@@ -1596,25 +1586,6 @@ redirect_exp_1 (rtx *loc, rtx olabel, rtx nlabel, rtx insn)
     }
 }
 
-/* Similar, but apply the change group and report success or failure.  */
-
-static int
-redirect_exp (rtx olabel, rtx nlabel, rtx insn)
-{
-  rtx *loc;
-
-  if (GET_CODE (PATTERN (insn)) == PARALLEL)
-    loc = &XVECEXP (PATTERN (insn), 0, 0);
-  else
-    loc = &PATTERN (insn);
-
-  redirect_exp_1 (loc, olabel, nlabel, insn);
-  if (num_validated_changes () == 0)
-    return 0;
-
-  return apply_change_group ();
-}
-
 /* Make JUMP go to NLABEL instead of where it jumps now.  Accrue
    the modifications into the change group.  Return false if we did
    not see how to do that.  */
@@ -1648,14 +1619,28 @@ int
 redirect_jump (rtx jump, rtx nlabel, int delete_unused)
 {
   rtx olabel = JUMP_LABEL (jump);
-  rtx note;
 
   if (nlabel == olabel)
     return 1;
 
-  if (! redirect_exp (olabel, nlabel, jump))
+  if (! redirect_jump_1 (jump, nlabel) || ! apply_change_group ())
     return 0;
 
+  redirect_jump_2 (jump, olabel, nlabel, delete_unused, 0);
+  return 1;
+}
+
+/* Fix up JUMP_LABEL and label ref counts after OLABEL has been replaced with
+   NLABEL in JUMP.  If DELETE_UNUSED is non-negative, copy a
+   NOTE_INSN_FUNCTION_END found after OLABEL to the place after NLABEL.
+   If DELETE_UNUSED is positive, delete related insn to OLABEL if its ref
+   count has dropped to zero.  */
+void
+redirect_jump_2 (rtx jump, rtx olabel, rtx nlabel, int delete_unused,
+                int invert)
+{
+  rtx note;
+
   JUMP_LABEL (jump) = nlabel;
   if (nlabel)
     ++LABEL_NUSES (nlabel);
@@ -1663,56 +1648,38 @@ redirect_jump (rtx jump, rtx nlabel, int delete_unused)
   /* Update labels in any REG_EQUAL note.  */
   if ((note = find_reg_note (jump, REG_EQUAL, NULL_RTX)) != NULL_RTX)
     {
-      if (nlabel && olabel)
+      if (!nlabel || (invert && !invert_exp_1 (XEXP (note, 0), jump)))
+       remove_note (jump, note);
+      else
        {
-         rtx dest = XEXP (note, 0);
-
-         if (GET_CODE (dest) == IF_THEN_ELSE)
-           {
-             if (GET_CODE (XEXP (dest, 1)) == LABEL_REF
-                 && XEXP (XEXP (dest, 1), 0) == olabel)
-               XEXP (XEXP (dest, 1), 0) = nlabel;
-             if (GET_CODE (XEXP (dest, 2)) == LABEL_REF
-                 && XEXP (XEXP (dest, 2), 0) == olabel)
-               XEXP (XEXP (dest, 2), 0) = nlabel;
-           }
-         else
-           remove_note (jump, note);
+         redirect_exp_1 (&XEXP (note, 0), olabel, nlabel, jump);
+         confirm_change_group ();
        }
-      else
-        remove_note (jump, note);
     }
 
   /* If we're eliding the jump over exception cleanups at the end of a
      function, move the function end note so that -Wreturn-type works.  */
   if (olabel && nlabel
       && NEXT_INSN (olabel)
-      && GET_CODE (NEXT_INSN (olabel)) == NOTE
-      && NOTE_LINE_NUMBER (NEXT_INSN (olabel)) == NOTE_INSN_FUNCTION_END)
+      && NOTE_P (NEXT_INSN (olabel))
+      && NOTE_LINE_NUMBER (NEXT_INSN (olabel)) == NOTE_INSN_FUNCTION_END
+      && delete_unused >= 0)
     emit_note_after (NOTE_INSN_FUNCTION_END, nlabel);
 
-  if (olabel && --LABEL_NUSES (olabel) == 0 && delete_unused
+  if (olabel && --LABEL_NUSES (olabel) == 0 && delete_unused > 0
       /* Undefined labels will remain outside the insn stream.  */
       && INSN_UID (olabel))
     delete_related_insns (olabel);
-
-  return 1;
+  if (invert)
+    invert_br_probabilities (jump);
 }
 
-/* Invert the jump condition of rtx X contained in jump insn, INSN.
-   Accrue the modifications into the change group.  */
-
-static void
-invert_exp_1 (rtx insn)
+/* Invert the jump condition X contained in jump insn INSN.  Accrue the
+   modifications into the change group.  Return nonzero for success.  */
+static int
+invert_exp_1 (rtx x, rtx insn)
 {
-  RTX_CODE code;
-  rtx x = pc_set (insn);
-
-  if (!x)
-    abort ();
-  x = SET_SRC (x);
-
-  code = GET_CODE (x);
+  RTX_CODE code = GET_CODE (x);
 
   if (code == IF_THEN_ELSE)
     {
@@ -1734,30 +1701,16 @@ invert_exp_1 (rtx insn)
                                           GET_MODE (comp), XEXP (comp, 0),
                                           XEXP (comp, 1)),
                           1);
-         return;
+         return 1;
        }
 
       tem = XEXP (x, 1);
       validate_change (insn, &XEXP (x, 1), XEXP (x, 2), 1);
       validate_change (insn, &XEXP (x, 2), tem, 1);
+      return 1;
     }
   else
-    abort ();
-}
-
-/* Invert the jump condition of conditional jump insn, INSN.
-
-   Return 1 if we can do so, 0 if we cannot find a way to do so that
-   matches a pattern.  */
-
-static int
-invert_exp (rtx insn)
-{
-  invert_exp_1 (insn);
-  if (num_validated_changes () == 0)
     return 0;
-
-  return apply_change_group ();
 }
 
 /* Invert the condition of the jump JUMP, and make it jump to label
@@ -1768,14 +1721,18 @@ invert_exp (rtx insn)
 int
 invert_jump_1 (rtx jump, rtx nlabel)
 {
+  rtx x = pc_set (jump);
   int ochanges;
 
   ochanges = num_validated_changes ();
-  invert_exp_1 (jump);
+  if (!x || !invert_exp_1 (SET_SRC (x), jump))
+    abort ();
   if (num_validated_changes () == ochanges)
     return 0;
 
-  return redirect_jump_1 (jump, nlabel);
+  /* redirect_jump_1 will fail of nlabel == olabel, and the current use is
+     in Pmode, so checking this is not merely an optimization.  */
+  return nlabel == JUMP_LABEL (jump) || redirect_jump_1 (jump, nlabel);
 }
 
 /* Invert the condition of the jump JUMP, and make it jump to label
@@ -1784,30 +1741,14 @@ invert_jump_1 (rtx jump, rtx nlabel)
 int
 invert_jump (rtx jump, rtx nlabel, int delete_unused)
 {
-  /* We have to either invert the condition and change the label or
-     do neither.  Either operation could fail.  We first try to invert
-     the jump. If that succeeds, we try changing the label.  If that fails,
-     we invert the jump back to what it was.  */
-
-  if (! invert_exp (jump))
-    return 0;
+  rtx olabel = JUMP_LABEL (jump);
 
-  if (redirect_jump (jump, nlabel, delete_unused))
+  if (invert_jump_1 (jump, nlabel) && apply_change_group ())
     {
-      /* Remove REG_EQUAL note if we have one.  */
-      rtx note = find_reg_note (jump, REG_EQUAL, NULL_RTX);
-      if (note)
-       remove_note (jump, note);
-
-      invert_br_probabilities (jump);
-
+      redirect_jump_2 (jump, olabel, nlabel, delete_unused, 1);
       return 1;
     }
-
-  if (! invert_exp (jump))
-    /* This should just be putting it back the way it was.  */
-    abort ();
-
+  cancel_changes (0);
   return 0;
 }
 
@@ -1835,9 +1776,9 @@ rtx_renumbered_equal_p (rtx x, rtx y)
   if (x == y)
     return 1;
 
-  if ((code == REG || (code == SUBREG && GET_CODE (SUBREG_REG (x)) == REG))
-      && (GET_CODE (y) == REG || (GET_CODE (y) == SUBREG
-                                 && GET_CODE (SUBREG_REG (y)) == REG)))
+  if ((code == REG || (code == SUBREG && REG_P (SUBREG_REG (x))))
+      && (REG_P (y) || (GET_CODE (y) == SUBREG
+                                 && REG_P (SUBREG_REG (y)))))
     {
       int reg_x = -1, reg_y = -1;
       int byte_x = 0, byte_y = 0;
@@ -2014,7 +1955,7 @@ rtx_renumbered_equal_p (rtx x, rtx y)
 int
 true_regnum (rtx x)
 {
-  if (GET_CODE (x) == REG)
+  if (REG_P (x))
     {
       if (REGNO (x) >= FIRST_PSEUDO_REGISTER && reg_renumber[REGNO (x)] >= 0)
        return reg_renumber[REGNO (x)];