alias.c: Remove unused headers.
[gcc.git] / gcc / jump.c
index acc96341d651ba030facec37ca249d15106585b0..c41710db73d942616dec4999729559dcda69c4a4 100644 (file)
@@ -1,7 +1,5 @@
 /* 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, 2005, 2007, 2008, 2009, 2010,
-   2011 Free Software Foundation, Inc.
+   Copyright (C) 1987-2015 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -38,24 +36,19 @@ along with GCC; see the file COPYING3.  If not see
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
-#include "tm.h"
+#include "backend.h"
+#include "target.h"
 #include "rtl.h"
+#include "tree.h"
+#include "cfghooks.h"
+#include "tree-pass.h"
 #include "tm_p.h"
-#include "flags.h"
-#include "hard-reg-set.h"
-#include "regs.h"
 #include "insn-config.h"
-#include "insn-attr.h"
+#include "regs.h"
+#include "emit-rtl.h"
 #include "recog.h"
-#include "function.h"
-#include "basic-block.h"
-#include "expr.h"
-#include "except.h"
-#include "diagnostic-core.h"
-#include "reload.h"
-#include "predict.h"
-#include "tree-pass.h"
-#include "target.h"
+#include "cfgrtl.h"
+#include "rtl-iter.h"
 
 /* Optimize jump y; x: ... y: jumpif... x?
    Don't know if it is worth bothering with.  */
@@ -64,19 +57,18 @@ along with GCC; see the file COPYING3.  If not see
    or even change what is live at any point.
    So perhaps let combiner do it.  */
 
-static void init_label_info (rtx);
-static void mark_all_labels (rtx);
-static void mark_jump_label_1 (rtx, rtx, bool, bool);
-static void mark_jump_label_asm (rtx, rtx);
+static void init_label_info (rtx_insn *);
+static void mark_all_labels (rtx_insn *);
+static void mark_jump_label_1 (rtx, rtx_insn *, bool, bool);
+static void mark_jump_label_asm (rtx, rtx_insn *);
 static void redirect_exp_1 (rtx *, rtx, rtx, rtx);
 static int invert_exp_1 (rtx, rtx);
-static int returnjump_p_1 (rtx *, void *);
 \f
 /* Worker for rebuild_jump_labels and rebuild_jump_labels_chain.  */
 static void
-rebuild_jump_labels_1 (rtx f, bool count_forced)
+rebuild_jump_labels_1 (rtx_insn *f, bool count_forced)
 {
-  rtx insn;
+  rtx_insn_list *insn;
 
   timevar_push (TV_REBUILD_JUMP);
   init_label_info (f);
@@ -87,9 +79,9 @@ rebuild_jump_labels_1 (rtx f, bool count_forced)
      count doesn't drop to zero.  */
 
   if (count_forced)
-    for (insn = forced_labels; insn; insn = XEXP (insn, 1))
-      if (LABEL_P (XEXP (insn, 0)))
-       LABEL_NUSES (XEXP (insn, 0))++;
+    for (insn = forced_labels; insn; insn = insn->next ())
+      if (LABEL_P (insn->insn ()))
+       LABEL_NUSES (insn->insn ())++;
   timevar_pop (TV_REBUILD_JUMP);
 }
 
@@ -98,7 +90,7 @@ rebuild_jump_labels_1 (rtx f, bool count_forced)
    instructions and jumping insns that have labels as operands
    (e.g. cbranchsi4).  */
 void
-rebuild_jump_labels (rtx f)
+rebuild_jump_labels (rtx_insn *f)
 {
   rebuild_jump_labels_1 (f, true);
 }
@@ -107,7 +99,7 @@ rebuild_jump_labels (rtx f)
    forced_labels.  It can be used on insn chains that aren't the 
    main function chain.  */
 void
-rebuild_jump_labels_chain (rtx chain)
+rebuild_jump_labels_chain (rtx_insn *chain)
 {
   rebuild_jump_labels_1 (chain, false);
 }
@@ -120,55 +112,105 @@ rebuild_jump_labels_chain (rtx chain)
    This simple pass moves barriers and removes duplicates so that the
    old code is happy.
  */
-unsigned int
+static unsigned int
 cleanup_barriers (void)
 {
-  rtx insn, next, prev;
-  for (insn = get_insns (); insn; insn = next)
+  rtx_insn *insn;
+  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
     {
-      next = NEXT_INSN (insn);
       if (BARRIER_P (insn))
        {
-         prev = prev_nonnote_insn (insn);
+         rtx_insn *prev = prev_nonnote_insn (insn);
          if (!prev)
            continue;
+
+         if (CALL_P (prev))
+           {
+             /* Make sure we do not split a call and its corresponding
+                CALL_ARG_LOCATION note.  */
+             rtx_insn *next = NEXT_INSN (prev);
+
+             if (NOTE_P (next)
+                 && NOTE_KIND (next) == NOTE_INSN_CALL_ARG_LOCATION)
+               prev = next;
+           }
+
          if (BARRIER_P (prev))
            delete_insn (insn);
          else if (prev != PREV_INSN (insn))
-           reorder_insns (insn, insn, prev);
+           {
+             basic_block bb = BLOCK_FOR_INSN (prev);
+             rtx_insn *end = PREV_INSN (insn);
+             reorder_insns_nobb (insn, insn, prev);
+             if (bb)
+               {
+                 /* If the backend called in machine reorg compute_bb_for_insn
+                    and didn't free_bb_for_insn again, preserve basic block
+                    boundaries.  Move the end of basic block to PREV since
+                    it is followed by a barrier now, and clear BLOCK_FOR_INSN
+                    on the following notes.
+                    ???  Maybe the proper solution for the targets that have
+                    cfg around after machine reorg is not to run cleanup_barriers
+                    pass at all.  */
+                 BB_END (bb) = prev;
+                 do
+                   {
+                     prev = NEXT_INSN (prev);
+                     if (prev != insn && BLOCK_FOR_INSN (prev) == bb)
+                       BLOCK_FOR_INSN (prev) = NULL;
+                   }
+                 while (prev != end);
+               }
+           }
        }
     }
   return 0;
 }
 
-struct rtl_opt_pass pass_cleanup_barriers =
+namespace {
+
+const pass_data pass_data_cleanup_barriers =
 {
- {
-  RTL_PASS,
-  "barriers",                           /* name */
-  NULL,                                 /* gate */
-  cleanup_barriers,                     /* execute */
-  NULL,                                 /* sub */
-  NULL,                                 /* next */
-  0,                                    /* static_pass_number */
-  TV_NONE,                              /* tv_id */
-  0,                                    /* properties_required */
-  0,                                    /* properties_provided */
-  0,                                    /* properties_destroyed */
-  0,                                    /* todo_flags_start */
-  0                                     /* todo_flags_finish */
- }
+  RTL_PASS, /* type */
+  "barriers", /* name */
+  OPTGROUP_NONE, /* optinfo_flags */
+  TV_NONE, /* tv_id */
+  0, /* properties_required */
+  0, /* properties_provided */
+  0, /* properties_destroyed */
+  0, /* todo_flags_start */
+  0, /* todo_flags_finish */
 };
 
+class pass_cleanup_barriers : public rtl_opt_pass
+{
+public:
+  pass_cleanup_barriers (gcc::context *ctxt)
+    : rtl_opt_pass (pass_data_cleanup_barriers, ctxt)
+  {}
+
+  /* opt_pass methods: */
+  virtual unsigned int execute (function *) { return cleanup_barriers (); }
+
+}; // class pass_cleanup_barriers
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_cleanup_barriers (gcc::context *ctxt)
+{
+  return new pass_cleanup_barriers (ctxt);
+}
+
 \f
 /* Initialize LABEL_NUSES and JUMP_LABEL fields, add REG_LABEL_TARGET
    for remaining targets for JUMP_P.  Delete any REG_LABEL_OPERAND
    notes whose labels don't occur in the insn any more.  */
 
 static void
-init_label_info (rtx f)
+init_label_info (rtx_insn *f)
 {
-  rtx insn;
+  rtx_insn *insn;
 
   for (insn = f; insn; insn = NEXT_INSN (insn))
     {
@@ -204,7 +246,7 @@ init_label_info (rtx f)
    load into a jump_insn that uses it.  */
 
 static void
-maybe_propagate_label_ref (rtx jump_insn, rtx prev_nonjump_insn)
+maybe_propagate_label_ref (rtx_insn *jump_insn, rtx_insn *prev_nonjump_insn)
 {
   rtx label_note, pc, pc_src;
 
@@ -239,7 +281,7 @@ maybe_propagate_label_ref (rtx jump_insn, rtx prev_nonjump_insn)
             CODE_LABEL in the LABEL_REF of the "set".  We can
             conveniently use it for the marker function, which
             requires a LABEL_REF wrapping.  */
-         gcc_assert (XEXP (label_note, 0) == XEXP (SET_SRC (label_set), 0));
+         gcc_assert (XEXP (label_note, 0) == LABEL_REF_LABEL (SET_SRC (label_set)));
 
          mark_jump_label_1 (label_set, jump_insn, false, true);
 
@@ -252,21 +294,21 @@ maybe_propagate_label_ref (rtx jump_insn, rtx prev_nonjump_insn)
    Combine consecutive labels, and count uses of labels.  */
 
 static void
-mark_all_labels (rtx f)
+mark_all_labels (rtx_insn *f)
 {
-  rtx insn;
+  rtx_insn *insn;
 
   if (current_ir_type () == IR_RTL_CFGLAYOUT)
     {
       basic_block bb;
-      FOR_EACH_BB (bb)
+      FOR_EACH_BB_FN (bb, cfun)
        {
          /* In cfglayout mode, we don't bother with trivial next-insn
             propagation of LABEL_REFs into JUMP_LABEL.  This will be
             handled by other optimizers using better algorithms.  */
          FOR_BB_INSNS (bb, insn)
            {
-             gcc_assert (! INSN_DELETED_P (insn));
+             gcc_assert (! insn->deleted ());
              if (NONDEBUG_INSN_P (insn))
                mark_jump_label (PATTERN (insn), insn, 0);
            }
@@ -275,28 +317,24 @@ mark_all_labels (rtx f)
             basic blocks.  If those non-insns represent tablejump data,
             they contain label references that we must record.  */
          for (insn = BB_HEADER (bb); insn; insn = NEXT_INSN (insn))
-           if (INSN_P (insn))
-             {
-               gcc_assert (JUMP_TABLE_DATA_P (insn));
-               mark_jump_label (PATTERN (insn), insn, 0);
-             }
+           if (JUMP_TABLE_DATA_P (insn))
+             mark_jump_label (PATTERN (insn), insn, 0);
          for (insn = BB_FOOTER (bb); insn; insn = NEXT_INSN (insn))
-           if (INSN_P (insn))
-             {
-               gcc_assert (JUMP_TABLE_DATA_P (insn));
-               mark_jump_label (PATTERN (insn), insn, 0);
-             }
+           if (JUMP_TABLE_DATA_P (insn))
+             mark_jump_label (PATTERN (insn), insn, 0);
        }
     }
   else
     {
-      rtx prev_nonjump_insn = NULL;
+      rtx_insn *prev_nonjump_insn = NULL;
       for (insn = f; insn; insn = NEXT_INSN (insn))
        {
-         if (INSN_DELETED_P (insn))
+         if (insn->deleted ())
            ;
          else if (LABEL_P (insn))
            prev_nonjump_insn = NULL;
+         else if (JUMP_TABLE_DATA_P (insn))
+           mark_jump_label (PATTERN (insn), insn, 0);
          else if (NONDEBUG_INSN_P (insn))
            {
              mark_jump_label (PATTERN (insn), insn, 0);
@@ -322,7 +360,7 @@ enum rtx_code
 reversed_comparison_code_parts (enum rtx_code code, const_rtx arg0,
                                const_rtx arg1, const_rtx insn)
 {
-  enum machine_mode mode;
+  machine_mode mode;
 
   /* If this is not actually a comparison, we can't reverse it.  */
   if (GET_RTX_CLASS (code) != RTX_COMPARE
@@ -338,13 +376,7 @@ reversed_comparison_code_parts (enum rtx_code code, const_rtx arg0,
      machine description to do tricks.  */
   if (GET_MODE_CLASS (mode) == MODE_CC
       && REVERSIBLE_CC_MODE (mode))
-    {
-#ifdef REVERSE_CONDITION
-      return REVERSE_CONDITION (code, mode);
-#else
-      return reverse_condition (code);
-#endif
-    }
+    return REVERSE_CONDITION (code, mode);
 
   /* Try a few special cases based on the comparison code.  */
   switch (code)
@@ -378,7 +410,6 @@ reversed_comparison_code_parts (enum rtx_code code, const_rtx arg0,
 
   if (GET_MODE_CLASS (mode) == MODE_CC || CC0_P (arg0))
     {
-      const_rtx prev;
       /* Try to search for the comparison to determine the real mode.
          This code is expensive, but with sane machine description it
          will be never used, since REVERSIBLE_CC_MODE will return true
@@ -389,9 +420,9 @@ reversed_comparison_code_parts (enum rtx_code code, const_rtx arg0,
       /* These CONST_CAST's are okay because prev_nonnote_insn just
         returns its argument and we assign it to a const_rtx
         variable.  */
-      for (prev = prev_nonnote_insn (CONST_CAST_RTX(insn));
+      for (rtx_insn *prev = prev_nonnote_insn (CONST_CAST_RTX (insn));
           prev != 0 && !LABEL_P (prev);
-          prev = prev_nonnote_insn (CONST_CAST_RTX(prev)))
+          prev = prev_nonnote_insn (prev))
        {
          const_rtx set = set_of (arg0, prev);
          if (set && GET_CODE (set) == SET
@@ -449,7 +480,7 @@ reversed_comparison_code (const_rtx comparison, const_rtx insn)
 /* Return comparison with reversed code of EXP.
    Return NULL_RTX in case we fail to do the reversal.  */
 rtx
-reversed_comparison (const_rtx exp, enum machine_mode mode)
+reversed_comparison (const_rtx exp, machine_mode mode)
 {
   enum rtx_code reversed_code = reversed_comparison_code (exp, NULL_RTX);
   if (reversed_code == UNKNOWN)
@@ -745,7 +776,7 @@ comparison_dominates_p (enum rtx_code code1, enum rtx_code code2)
 /* Return 1 if INSN is an unconditional jump and nothing else.  */
 
 int
-simplejump_p (const_rtx insn)
+simplejump_p (const rtx_insn *insn)
 {
   return (JUMP_P (insn)
          && GET_CODE (PATTERN (insn)) == SET
@@ -760,7 +791,7 @@ simplejump_p (const_rtx insn)
    branch and compare insns.  Use any_condjump_p instead whenever possible.  */
 
 int
-condjump_p (const_rtx insn)
+condjump_p (const rtx_insn *insn)
 {
   const_rtx x = PATTERN (insn);
 
@@ -788,7 +819,7 @@ condjump_p (const_rtx insn)
    branch and compare insns.  Use any_condjump_p instead whenever possible.  */
 
 int
-condjump_in_parallel_p (const_rtx insn)
+condjump_in_parallel_p (const rtx_insn *insn)
 {
   const_rtx x = PATTERN (insn);
 
@@ -819,7 +850,7 @@ condjump_in_parallel_p (const_rtx insn)
 /* Return set of PC, otherwise NULL.  */
 
 rtx
-pc_set (const_rtx insn)
+pc_set (const rtx_insn *insn)
 {
   rtx pat;
   if (!JUMP_P (insn))
@@ -840,7 +871,7 @@ pc_set (const_rtx insn)
    possibly bundled inside a PARALLEL.  */
 
 int
-any_uncondjump_p (const_rtx insn)
+any_uncondjump_p (const rtx_insn *insn)
 {
   const_rtx x = pc_set (insn);
   if (!x)
@@ -860,7 +891,7 @@ any_uncondjump_p (const_rtx insn)
    Note that unlike condjump_p it returns false for unconditional jumps.  */
 
 int
-any_condjump_p (const_rtx insn)
+any_condjump_p (const rtx_insn *insn)
 {
   const_rtx x = pc_set (insn);
   enum rtx_code a, b;
@@ -881,7 +912,7 @@ any_condjump_p (const_rtx insn)
 /* Return the label of a conditional jump.  */
 
 rtx
-condjump_label (const_rtx insn)
+condjump_label (const rtx_insn *insn)
 {
   rtx x = pc_set (insn);
 
@@ -899,62 +930,57 @@ condjump_label (const_rtx insn)
   return NULL_RTX;
 }
 
-/* Return true if INSN is a (possibly conditional) return insn.  */
-
-static int
-returnjump_p_1 (rtx *loc, void *data ATTRIBUTE_UNUSED)
-{
-  rtx x = *loc;
-
-  if (x == NULL)
-    return false;
-
-  switch (GET_CODE (x))
-    {
-    case RETURN:
-    case SIMPLE_RETURN:
-    case EH_RETURN:
-      return true;
-
-    case SET:
-      return SET_IS_RETURN_P (x);
-
-    default:
-      return false;
-    }
-}
-
 /* Return TRUE if INSN is a return jump.  */
 
 int
-returnjump_p (rtx insn)
+returnjump_p (const rtx_insn *insn)
 {
-  if (!JUMP_P (insn))
-    return 0;
-  return for_each_rtx (&PATTERN (insn), returnjump_p_1, NULL);
+  if (JUMP_P (insn))
+    {
+      subrtx_iterator::array_type array;
+      FOR_EACH_SUBRTX (iter, array, PATTERN (insn), NONCONST)
+       {
+         const_rtx x = *iter;
+         switch (GET_CODE (x))
+           {
+           case RETURN:
+           case SIMPLE_RETURN:
+           case EH_RETURN:
+             return true;
+
+           case SET:
+             if (SET_IS_RETURN_P (x))
+               return true;
+             break;
+
+           default:
+             break;
+           }
+       }
+    }
+  return false;
 }
 
 /* Return true if INSN is a (possibly conditional) return insn.  */
 
-static int
-eh_returnjump_p_1 (rtx *loc, void *data ATTRIBUTE_UNUSED)
-{
-  return *loc && GET_CODE (*loc) == EH_RETURN;
-}
-
 int
-eh_returnjump_p (rtx insn)
+eh_returnjump_p (rtx_insn *insn)
 {
-  if (!JUMP_P (insn))
-    return 0;
-  return for_each_rtx (&PATTERN (insn), eh_returnjump_p_1, NULL);
+  if (JUMP_P (insn))
+    {
+      subrtx_iterator::array_type array;
+      FOR_EACH_SUBRTX (iter, array, PATTERN (insn), NONCONST)
+       if (GET_CODE (*iter) == EH_RETURN)
+         return true;
+    }
+  return false;
 }
 
 /* Return true if INSN is a jump that only transfers control and
    nothing more.  */
 
 int
-onlyjump_p (const_rtx insn)
+onlyjump_p (const rtx_insn *insn)
 {
   rtx set;
 
@@ -975,14 +1001,12 @@ onlyjump_p (const_rtx insn)
 /* Return true iff INSN is a jump and its JUMP_LABEL is a label, not
    NULL or a return.  */
 bool
-jump_to_label_p (rtx insn)
+jump_to_label_p (const rtx_insn *insn)
 {
   return (JUMP_P (insn)
          && JUMP_LABEL (insn) != NULL && !ANY_RETURN_P (JUMP_LABEL (insn)));
 }
 
-#ifdef HAVE_cc0
-
 /* Return nonzero if X is an RTX that only sets the condition codes
    and has no side effects.  */
 
@@ -1031,7 +1055,6 @@ sets_cc0_p (const_rtx x)
     }
   return 0;
 }
-#endif
 \f
 /* Find all CODE_LABELs referred to in X, and increment their use
    counts.  If INSN is a JUMP_INSN and there is at least one
@@ -1050,7 +1073,7 @@ sets_cc0_p (const_rtx x)
    that loop-optimization is done with.  */
 
 void
-mark_jump_label (rtx x, rtx insn, int in_mem)
+mark_jump_label (rtx x, rtx_insn *insn, int in_mem)
 {
   rtx asmop = extract_asm_operands (x);
   if (asmop)
@@ -1067,7 +1090,7 @@ mark_jump_label (rtx x, rtx insn, int in_mem)
    note.  */
 
 static void
-mark_jump_label_1 (rtx x, rtx insn, bool in_mem, bool is_target)
+mark_jump_label_1 (rtx x, rtx_insn *insn, bool in_mem, bool is_target)
 {
   RTX_CODE code = GET_CODE (x);
   int i;
@@ -1096,9 +1119,12 @@ mark_jump_label_1 (rtx x, rtx insn, bool in_mem, bool is_target)
       break;
 
     case SEQUENCE:
-      for (i = 0; i < XVECLEN (x, 0); i++)
-       mark_jump_label (PATTERN (XVECEXP (x, 0, i)),
-                        XVECEXP (x, 0, i), 0);
+      {
+       rtx_sequence *seq = as_a <rtx_sequence *> (x);
+       for (i = 0; i < seq->len (); i++)
+         mark_jump_label (PATTERN (seq->insn (i)),
+                          seq->insn (i), 0);
+      }
       return;
 
     case SYMBOL_REF:
@@ -1122,7 +1148,7 @@ mark_jump_label_1 (rtx x, rtx insn, bool in_mem, bool is_target)
 
     case LABEL_REF:
       {
-       rtx label = XEXP (x, 0);
+       rtx label = LABEL_REF_LABEL (x);
 
        /* Ignore remaining references to unreachable labels that
           have been deleted.  */
@@ -1136,8 +1162,8 @@ mark_jump_label_1 (rtx x, rtx insn, bool in_mem, bool is_target)
        if (LABEL_REF_NONLOCAL_P (x))
          break;
 
-       XEXP (x, 0) = label;
-       if (! insn || ! INSN_DELETED_P (insn))
+       LABEL_REF_LABEL (x) = label;
+       if (! insn || ! insn->deleted ())
          ++LABEL_NUSES (label);
 
        if (insn)
@@ -1164,16 +1190,16 @@ mark_jump_label_1 (rtx x, rtx insn, bool in_mem, bool is_target)
        return;
       }
 
-  /* Do walk the labels in a vector, but not the first operand of an
-     ADDR_DIFF_VEC.  Don't set the JUMP_LABEL of a vector.  */
+    /* Do walk the labels in a vector, but not the first operand of an
+       ADDR_DIFF_VEC.  Don't set the JUMP_LABEL of a vector.  */
     case ADDR_VEC:
     case ADDR_DIFF_VEC:
-      if (! INSN_DELETED_P (insn))
+      if (! insn->deleted ())
        {
          int eltnum = code == ADDR_DIFF_VEC ? 1 : 0;
 
          for (i = 0; i < XVECLEN (x, eltnum); i++)
-           mark_jump_label_1 (XVECEXP (x, eltnum, i), NULL_RTX, in_mem,
+           mark_jump_label_1 (XVECEXP (x, eltnum, i), NULL, in_mem,
                               is_target);
        }
       return;
@@ -1208,7 +1234,7 @@ mark_jump_label_1 (rtx x, rtx insn, bool in_mem, bool is_target)
    need to be considered targets.  */
 
 static void
-mark_jump_label_asm (rtx asmop, rtx insn)
+mark_jump_label_asm (rtx asmop, rtx_insn *insn)
 {
   int i;
 
@@ -1227,18 +1253,19 @@ mark_jump_label_asm (rtx asmop, rtx insn)
    Usage of this instruction is deprecated.  Use delete_insn instead and
    subsequent cfg_cleanup pass to delete unreachable code if needed.  */
 
-rtx
-delete_related_insns (rtx insn)
+rtx_insn *
+delete_related_insns (rtx uncast_insn)
 {
+  rtx_insn *insn = as_a <rtx_insn *> (uncast_insn);
   int was_code_label = (LABEL_P (insn));
   rtx note;
-  rtx next = NEXT_INSN (insn), prev = PREV_INSN (insn);
+  rtx_insn *next = NEXT_INSN (insn), *prev = PREV_INSN (insn);
 
-  while (next && INSN_DELETED_P (next))
+  while (next && next->deleted ())
     next = NEXT_INSN (next);
 
   /* This insn is already deleted => return first following nondeleted.  */
-  if (INSN_DELETED_P (insn))
+  if (insn->deleted ())
     return next;
 
   delete_insn (insn);
@@ -1257,9 +1284,9 @@ delete_related_insns (rtx insn)
          && GET_CODE (PATTERN (insn)) == SEQUENCE
          && CALL_P (XVECEXP (PATTERN (insn), 0, 0))))
     {
-      rtx p;
+      rtx_insn *p;
 
-      for (p = next && INSN_DELETED_P (next) ? NEXT_INSN (next) : next;
+      for (p = next && next->deleted () ? NEXT_INSN (next) : next;
           p && NOTE_P (p);
           p = NEXT_INSN (p))
        if (NOTE_KIND (p) == NOTE_INSN_CALL_ARG_LOCATION)
@@ -1274,7 +1301,8 @@ delete_related_insns (rtx insn)
 
   if (jump_to_label_p (insn))
     {
-      rtx lab = JUMP_LABEL (insn), lab_next;
+      rtx lab = JUMP_LABEL (insn);
+      rtx_jump_table_data *lab_next;
 
       if (LABEL_NUSES (lab) == 0)
        /* This can delete NEXT or PREV,
@@ -1293,16 +1321,16 @@ delete_related_insns (rtx insn)
 
   /* Likewise if we're deleting a dispatch table.  */
 
-  if (JUMP_TABLE_DATA_P (insn))
+  if (rtx_jump_table_data *table = dyn_cast <rtx_jump_table_data *> (insn))
     {
-      rtx pat = PATTERN (insn);
-      int i, diff_vec_p = GET_CODE (pat) == ADDR_DIFF_VEC;
-      int len = XVECLEN (pat, diff_vec_p);
+      rtvec labels = table->get_labels ();
+      int i;
+      int len = GET_NUM_ELEM (labels);
 
       for (i = 0; i < len; i++)
-       if (LABEL_NUSES (XEXP (XVECEXP (pat, diff_vec_p, i), 0)) == 0)
-         delete_related_insns (XEXP (XVECEXP (pat, diff_vec_p, i), 0));
-      while (next && INSN_DELETED_P (next))
+       if (LABEL_NUSES (XEXP (RTVEC_ELT (labels, i), 0)) == 0)
+         delete_related_insns (XEXP (RTVEC_ELT (labels, i), 0));
+      while (next && next->deleted ())
        next = NEXT_INSN (next);
       return next;
     }
@@ -1318,7 +1346,7 @@ delete_related_insns (rtx insn)
        if (LABEL_NUSES (XEXP (note, 0)) == 0)
          delete_related_insns (XEXP (note, 0));
 
-  while (prev && (INSN_DELETED_P (prev) || NOTE_P (prev)))
+  while (prev && (prev->deleted () || NOTE_P (prev)))
     prev = PREV_INSN (prev);
 
   /* If INSN was a label and a dispatch table follows it,
@@ -1341,7 +1369,14 @@ delete_related_insns (rtx insn)
          if (code == NOTE)
            next = NEXT_INSN (next);
          /* Keep going past other deleted labels to delete what follows.  */
-         else if (code == CODE_LABEL && INSN_DELETED_P (next))
+         else if (code == CODE_LABEL && next->deleted ())
+           next = NEXT_INSN (next);
+         /* Keep the (use (insn))s created by dbr_schedule, which needs
+            them in order to track liveness relative to a previous
+            barrier.  */
+         else if (INSN_P (next)
+                  && GET_CODE (PATTERN (next)) == USE
+                  && INSN_P (XEXP (PATTERN (next), 0)))
            next = NEXT_INSN (next);
          else if (code == BARRIER || INSN_P (next))
            /* Note: if this deletes a jump, it can cause more
@@ -1358,7 +1393,7 @@ delete_related_insns (rtx insn)
      but I see no clean and sure alternative way
      to find the first insn after INSN that is not now deleted.
      I hope this works.  */
-  while (next && INSN_DELETED_P (next))
+  while (next && next->deleted ())
     next = NEXT_INSN (next);
   return next;
 }
@@ -1369,27 +1404,27 @@ delete_related_insns (rtx insn)
    peephole insn that will replace them.  */
 
 void
-delete_for_peephole (rtx from, rtx to)
+delete_for_peephole (rtx_insn *from, rtx_insn *to)
 {
-  rtx insn = from;
+  rtx_insn *insn = from;
 
   while (1)
     {
-      rtx next = NEXT_INSN (insn);
-      rtx prev = PREV_INSN (insn);
+      rtx_insn *next = NEXT_INSN (insn);
+      rtx_insn *prev = PREV_INSN (insn);
 
       if (!NOTE_P (insn))
        {
-         INSN_DELETED_P (insn) = 1;
+         insn->set_deleted();
 
          /* Patch this insn out of the chain.  */
          /* We don't do this all at once, because we
             must preserve all NOTEs.  */
          if (prev)
-           NEXT_INSN (prev) = next;
+           SET_NEXT_INSN (prev) = next;
 
          if (next)
-           PREV_INSN (next) = prev;
+           SET_PREV_INSN (next) = prev;
        }
 
       if (insn == to)
@@ -1426,12 +1461,12 @@ redirect_exp_1 (rtx *loc, rtx olabel, rtx nlabel, rtx insn)
   int i;
   const char *fmt;
 
-  if ((code == LABEL_REF && XEXP (x, 0) == olabel)
+  if ((code == LABEL_REF && LABEL_REF_LABEL (x) == olabel)
       || x == olabel)
     {
       x = redirect_target (nlabel);
       if (GET_CODE (x) == LABEL_REF && loc == &PATTERN (insn))
-       x = gen_rtx_SET (VOIDmode, pc_rtx, x);
+       x = gen_rtx_SET (pc_rtx, x);
       validate_change (insn, loc, x, 1);
       return;
     }
@@ -1439,7 +1474,7 @@ redirect_exp_1 (rtx *loc, rtx olabel, rtx nlabel, rtx insn)
   if (code == SET && SET_DEST (x) == pc_rtx
       && ANY_RETURN_P (nlabel)
       && GET_CODE (SET_SRC (x)) == LABEL_REF
-      && XEXP (SET_SRC (x), 0) == olabel)
+      && LABEL_REF_LABEL (SET_SRC (x)) == olabel)
     {
       validate_change (insn, loc, nlabel, 1);
       return;
@@ -1473,7 +1508,7 @@ redirect_exp_1 (rtx *loc, rtx olabel, rtx nlabel, rtx insn)
    not see how to do that.  */
 
 int
-redirect_jump_1 (rtx jump, rtx nlabel)
+redirect_jump_1 (rtx_insn *jump, rtx nlabel)
 {
   int ochanges = num_validated_changes ();
   rtx *loc, asmop;
@@ -1508,9 +1543,9 @@ redirect_jump_1 (rtx jump, rtx nlabel)
    (this can only occur when trying to produce return insns).  */
 
 int
-redirect_jump (rtx jump, rtx nlabel, int delete_unused)
+redirect_jump (rtx_jump_insn *jump, rtx nlabel, int delete_unused)
 {
-  rtx olabel = JUMP_LABEL (jump);
+  rtx olabel = jump->jump_label ();
 
   if (!nlabel)
     {
@@ -1540,7 +1575,7 @@ redirect_jump (rtx jump, rtx nlabel, int delete_unused)
    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,
+redirect_jump_2 (rtx_jump_insn *jump, rtx olabel, rtx nlabel, int delete_unused,
                 int invert)
 {
   rtx note;
@@ -1568,6 +1603,12 @@ redirect_jump_2 (rtx jump, rtx olabel, rtx nlabel, int delete_unused,
        }
     }
 
+  /* Handle the case where we had a conditional crossing jump to a return
+     label and are now changing it into a direct conditional return.
+     The jump is no longer crossing in that case.  */
+  if (ANY_RETURN_P (nlabel))
+    CROSSING_JUMP_P (jump) = 0;
+
   if (!ANY_RETURN_P (olabel)
       && --LABEL_NUSES (olabel) == 0 && delete_unused > 0
       /* Undefined labels will remain outside the insn stream.  */
@@ -1622,7 +1663,7 @@ invert_exp_1 (rtx x, rtx insn)
    inversion and redirection.  */
 
 int
-invert_jump_1 (rtx jump, rtx nlabel)
+invert_jump_1 (rtx_jump_insn *jump, rtx nlabel)
 {
   rtx x = pc_set (jump);
   int ochanges;
@@ -1646,7 +1687,7 @@ invert_jump_1 (rtx jump, rtx nlabel)
    NLABEL instead of where it jumps now.  Return true if successful.  */
 
 int
-invert_jump (rtx jump, rtx nlabel, int delete_unused)
+invert_jump (rtx_jump_insn *jump, rtx nlabel, int delete_unused)
 {
   rtx olabel = JUMP_LABEL (jump);
 
@@ -1757,12 +1798,12 @@ rtx_renumbered_equal_p (const_rtx x, const_rtx y)
     case LABEL_REF:
       /* We can't assume nonlocal labels have their following insns yet.  */
       if (LABEL_REF_NONLOCAL_P (x) || LABEL_REF_NONLOCAL_P (y))
-       return XEXP (x, 0) == XEXP (y, 0);
+       return LABEL_REF_LABEL (x) == LABEL_REF_LABEL (y);
 
       /* Two label-refs are equivalent if they point at labels
         in the same position in the instruction stream.  */
-      return (next_real_insn (XEXP (x, 0))
-             == next_real_insn (XEXP (y, 0)));
+      return (next_real_insn (LABEL_REF_LABEL (x))
+             == next_real_insn (LABEL_REF_LABEL (y)));
 
     case SYMBOL_REF:
       return XSTR (x, 0) == XSTR (y, 0);