OSDN Git Service

* cfgcleanup.c (old_insns_match_p): Remove code to substitute
[pf3gnuchains/gcc-fork.git] / gcc / cfgcleanup.c
index a5a5d07..3d1fbb2 100644 (file)
@@ -1,12 +1,13 @@
 /* Control flow optimization code for GNU compiler.
    Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+   Free Software Foundation, Inc.
 
 This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
+Software Foundation; either version 3, or (at your option) any later
 version.
 
 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -15,9 +16,8 @@ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 for more details.
 
 You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 
 /* This file contains optimizer of the control flow.  The main entry point is
    cleanup_cfg.  Following optimizations are performed:
@@ -53,39 +53,30 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 #include "tree-pass.h"
 #include "cfgloop.h"
 #include "expr.h"
+#include "df.h"
+#include "dce.h"
+#include "dbgcnt.h"
 
-/* cleanup_cfg maintains following flags for each basic block.  */
-
-enum bb_flags
-{
-    /* Set if BB is the forwarder block to avoid too many
-       forwarder_block_p calls.  */
-    BB_FORWARDER_BLOCK = 1,
-    BB_NONTHREADABLE_BLOCK = 2
-};
-
-#define BB_FLAGS(BB) (enum bb_flags) (BB)->aux
-#define BB_SET_FLAG(BB, FLAG) \
-  (BB)->aux = (void *) (long) ((enum bb_flags) (BB)->aux | (FLAG))
-#define BB_CLEAR_FLAG(BB, FLAG) \
-  (BB)->aux = (void *) (long) ((enum bb_flags) (BB)->aux & ~(FLAG))
-
-#define FORWARDER_BLOCK_P(BB) (BB_FLAGS (BB) & BB_FORWARDER_BLOCK)
+#define FORWARDER_BLOCK_P(BB) ((BB)->flags & BB_FORWARDER_BLOCK)
 
 /* Set to true when we are running first pass of try_optimize_cfg loop.  */
 static bool first_pass;
+
+/* Set to true if crossjumps occured in the latest run of try_optimize_cfg.  */
+static bool crossjumps_occured;
+
 static bool try_crossjump_to_edge (int, edge, edge);
 static bool try_crossjump_bb (int, basic_block);
 static bool outgoing_edges_match (int, basic_block, basic_block);
 static int flow_find_cross_jump (int, basic_block, basic_block, rtx *, rtx *);
-static bool insns_match_p (int, rtx, rtx);
+static bool old_insns_match_p (int, rtx, rtx);
 
 static void merge_blocks_move_predecessor_nojumps (basic_block, basic_block);
 static void merge_blocks_move_successor_nojumps (basic_block, basic_block);
 static bool try_optimize_cfg (int);
 static bool try_simplify_condjump (basic_block);
 static bool try_forward_edges (int, basic_block);
-static edge thread_jump (int, edge, basic_block);
+static edge thread_jump (edge, basic_block);
 static bool mark_effect (rtx, bitmap);
 static void notice_new_block (basic_block);
 static void update_forwarder_flag (basic_block);
@@ -101,7 +92,7 @@ notice_new_block (basic_block bb)
     return;
 
   if (forwarder_block_p (bb))
-    BB_SET_FLAG (bb, BB_FORWARDER_BLOCK);
+    bb->flags |= BB_FORWARDER_BLOCK;
 }
 
 /* Recompute forwarder flag after block has been modified.  */
@@ -110,9 +101,9 @@ static void
 update_forwarder_flag (basic_block bb)
 {
   if (forwarder_block_p (bb))
-    BB_SET_FLAG (bb, BB_FORWARDER_BLOCK);
+    bb->flags |= BB_FORWARDER_BLOCK;
   else
-    BB_CLEAR_FLAG (bb, BB_FORWARDER_BLOCK);
+    bb->flags &= ~BB_FORWARDER_BLOCK;
 }
 \f
 /* Simplify a conditional jump around an unconditional jump.
@@ -150,12 +141,12 @@ try_simplify_condjump (basic_block cbranch_block)
 
   /* If we are partitioning hot/cold basic blocks, we don't want to
      mess up unconditional or indirect jumps that cross between hot
-     and cold sections. 
+     and cold sections.
 
      Basic block partitioning may result in some jumps that appear to
-     be optimizable (or blocks that appear to be mergeable), but which really 
-     must be left untouched (they are required to make it safely across 
-     partition boundaries).  See the comments at the top of 
+     be optimizable (or blocks that appear to be mergeable), but which really
+     must be left untouched (they are required to make it safely across
+     partition boundaries).  See the comments at the top of
      bb-reorder.c:partition_hot_cold_basic_blocks for complete details.  */
 
   if (BB_PARTITION (jump_block) != BB_PARTITION (jump_dest_block)
@@ -208,7 +199,7 @@ mark_effect (rtx exp, regset nonequal)
   switch (GET_CODE (exp))
     {
       /* In case we do clobber the register, mark it as equal, as we know the
-         value is dead so it don't have to match.  */
+        value is dead so it don't have to match.  */
     case CLOBBER:
       if (REG_P (XEXP (exp, 0)))
        {
@@ -275,7 +266,7 @@ mentions_nonequal_regs (rtx *x, void *data)
    if exist, NULL otherwise.  */
 
 static edge
-thread_jump (int mode, edge e, basic_block b)
+thread_jump (edge e, basic_block b)
 {
   rtx set1, set2, cond1, cond2, insn;
   enum rtx_code code1, code2, reversed_code2;
@@ -285,7 +276,7 @@ thread_jump (int mode, edge e, basic_block b)
   bool failed = false;
   reg_set_iterator rsi;
 
-  if (BB_FLAGS (b) & BB_NONTHREADABLE_BLOCK)
+  if (b->flags & BB_NONTHREADABLE_BLOCK)
     return NULL;
 
   /* At the moment, we do handle only conditional jumps, but later we may
@@ -294,7 +285,7 @@ thread_jump (int mode, edge e, basic_block b)
     return NULL;
   if (EDGE_COUNT (b->succs) != 2)
     {
-      BB_SET_FLAG (b, BB_NONTHREADABLE_BLOCK);
+      b->flags |= BB_NONTHREADABLE_BLOCK;
       return NULL;
     }
 
@@ -304,7 +295,7 @@ thread_jump (int mode, edge e, basic_block b)
 
   if (!any_condjump_p (BB_END (b)) || !onlyjump_p (BB_END (b)))
     {
-      BB_SET_FLAG (b, BB_NONTHREADABLE_BLOCK);
+      b->flags |= BB_NONTHREADABLE_BLOCK;
       return NULL;
     }
 
@@ -342,7 +333,7 @@ thread_jump (int mode, edge e, basic_block b)
        insn = NEXT_INSN (insn))
     if (INSN_P (insn) && side_effects_p (PATTERN (insn)))
       {
-       BB_SET_FLAG (b, BB_NONTHREADABLE_BLOCK);
+       b->flags |= BB_NONTHREADABLE_BLOCK;
        return NULL;
       }
 
@@ -386,7 +377,7 @@ thread_jump (int mode, edge e, basic_block b)
      have life information in cfg_cleanup.  */
   if (failed)
     {
-      BB_SET_FLAG (b, BB_NONTHREADABLE_BLOCK);
+      b->flags |= BB_NONTHREADABLE_BLOCK;
       goto failed_exit;
     }
 
@@ -395,11 +386,6 @@ thread_jump (int mode, edge e, basic_block b)
   if (for_each_rtx (&cond2, mentions_nonequal_regs, nonequal))
     goto failed_exit;
 
-  /* In case liveness information is available, we need to prove equivalence
-     only of the live values.  */
-  if (mode & CLEANUP_UPDATE_LIFE)
-    AND_REG_SET (nonequal, b->il.rtl->global_live_at_end);
-
   EXECUTE_IF_SET_IN_REG_SET (nonequal, 0, i, rsi)
     goto failed_exit;
 
@@ -429,12 +415,12 @@ try_forward_edges (int mode, basic_block b)
 
   /* If we are partitioning hot/cold basic blocks, we don't want to
      mess up unconditional or indirect jumps that cross between hot
-     and cold sections. 
-  
+     and cold sections.
+
      Basic block partitioning may result in some jumps that appear to
-     be optimizable (or blocks that appear to be mergeable), but which really m
-     ust be left untouched (they are required to make it safely across 
-     partition boundaries).  See the comments at the top of 
+     be optimizable (or blocks that appear to be mergeable), but which really
+     must be left untouched (they are required to make it safely across
+     partition boundaries).  See the comments at the top of
      bb-reorder.c:partition_hot_cold_basic_blocks for complete details.  */
 
   if (find_reg_note (BB_END (b), REG_CROSSING_JUMP, NULL_RTX))
@@ -443,16 +429,16 @@ try_forward_edges (int mode, basic_block b)
   for (ei = ei_start (b->succs); (e = ei_safe_edge (ei)); )
     {
       basic_block target, first;
-      int counter;
+      int counter, goto_locus;
       bool threaded = false;
       int nthreaded_edges = 0;
-      bool may_thread = first_pass | (b->flags & BB_DIRTY);
+      bool may_thread = first_pass | df_get_bb_dirty (b);
 
       /* Skip complex edges because we don't know how to update them.
 
-         Still handle fallthru edges, as we can succeed to forward fallthru
-         edge to the same place as the branch edge of conditional branch
-         and turn conditional branch to an unconditional branch.  */
+        Still handle fallthru edges, as we can succeed to forward fallthru
+        edge to the same place as the branch edge of conditional branch
+        and turn conditional branch to an unconditional branch.  */
       if (e->flags & EDGE_COMPLEX)
        {
          ei_next (&ei);
@@ -460,14 +446,15 @@ try_forward_edges (int mode, basic_block b)
        }
 
       target = first = e->dest;
-      counter = 0;
+      counter = NUM_FIXED_BLOCKS;
+      goto_locus = e->goto_locus;
 
       /* If we are partitioning hot/cold basic_blocks, we don't want to mess
         up jumps that cross between hot/cold sections.
 
         Basic block partitioning may result in some jumps that appear
-        to be optimizable (or blocks that appear to be mergeable), but which 
-        really must be left untouched (they are required to make it safely 
+        to be optimizable (or blocks that appear to be mergeable), but which
+        really must be left untouched (they are required to make it safely
         across partition boundaries).  See the comments at the top of
         bb-reorder.c:partition_hot_cold_basic_blocks for complete
         details.  */
@@ -480,28 +467,49 @@ try_forward_edges (int mode, basic_block b)
        {
          basic_block new_target = NULL;
          bool new_target_threaded = false;
-         may_thread |= target->flags & BB_DIRTY;
+         may_thread |= df_get_bb_dirty (target);
 
          if (FORWARDER_BLOCK_P (target)
-             && !(single_succ_edge (target)->flags & EDGE_CROSSING)
+             && !(single_succ_edge (target)->flags & EDGE_CROSSING)
              && single_succ (target) != EXIT_BLOCK_PTR)
            {
              /* Bypass trivial infinite loops.  */
              new_target = single_succ (target);
              if (target == new_target)
                counter = n_basic_blocks;
+             else if (!optimize)
+               {
+                 /* When not optimizing, ensure that edges or forwarder
+                    blocks with different locus are not optimized out.  */
+                 int locus = single_succ_edge (target)->goto_locus;
+
+                 if (locus && goto_locus && !locator_eq (locus, goto_locus))
+                   counter = n_basic_blocks;
+                 else if (locus)
+                   goto_locus = locus;
+
+                 if (INSN_P (BB_END (target)))
+                   {
+                     locus = INSN_LOCATOR (BB_END (target));
+
+                     if (locus && goto_locus
+                         && !locator_eq (locus, goto_locus))
+                       counter = n_basic_blocks;
+                     else if (locus)
+                       goto_locus = locus;
+                   }
+               }
            }
 
          /* Allow to thread only over one edge at time to simplify updating
             of probabilities.  */
          else if ((mode & CLEANUP_THREADING) && may_thread)
            {
-             edge t = thread_jump (mode, e, target);
+             edge t = thread_jump (e, target);
              if (t)
                {
                  if (!threaded_edges)
-                   threaded_edges = xmalloc (sizeof (*threaded_edges)
-                                             * n_basic_blocks);
+                   threaded_edges = XNEWVEC (edge, n_basic_blocks);
                  else
                    {
                      int i;
@@ -522,7 +530,7 @@ try_forward_edges (int mode, basic_block b)
                  if (t->dest == b)
                    break;
 
-                 gcc_assert (nthreaded_edges < n_basic_blocks);
+                 gcc_assert (nthreaded_edges < n_basic_blocks - NUM_FIXED_BLOCKS);
                  threaded_edges[nthreaded_edges++] = t;
 
                  new_target = t->dest;
@@ -533,39 +541,6 @@ try_forward_edges (int mode, basic_block b)
          if (!new_target)
            break;
 
-         /* Avoid killing of loop pre-headers, as it is the place loop
-            optimizer wants to hoist code to.
-
-            For fallthru forwarders, the LOOP_BEG note must appear between
-            the header of block and CODE_LABEL of the loop, for non forwarders
-            it must appear before the JUMP_INSN.  */
-         if ((mode & CLEANUP_PRE_LOOP) && optimize && flag_loop_optimize)
-           {
-             rtx insn = (EDGE_SUCC (target, 0)->flags & EDGE_FALLTHRU
-                         ? BB_HEAD (target) : prev_nonnote_insn (BB_END (target)));
-
-             if (!NOTE_P (insn))
-               insn = NEXT_INSN (insn);
-
-             for (; insn && !LABEL_P (insn) && !INSN_P (insn);
-                  insn = NEXT_INSN (insn))
-               if (NOTE_P (insn)
-                   && NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG)
-                 break;
-
-             if (NOTE_P (insn))
-               break;
-
-             /* Do not clean up branches to just past the end of a loop
-                at this time; it can mess up the loop optimizer's
-                recognition of some patterns.  */
-
-             insn = PREV_INSN (BB_HEAD (target));
-             if (insn && NOTE_P (insn)
-                   && NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END)
-               break;
-           }
-
          counter++;
          target = new_target;
          threaded |= new_target_threaded;
@@ -587,6 +562,8 @@ try_forward_edges (int mode, basic_block b)
          int edge_frequency;
          int n = 0;
 
+         e->goto_locus = goto_locus;
+
          /* Don't force if target is exit block.  */
          if (threaded && target != EXIT_BLOCK_PTR)
            {
@@ -612,7 +589,7 @@ try_forward_edges (int mode, basic_block b)
                            / REG_BR_PROB_BASE);
 
          if (!FORWARDER_BLOCK_P (b) && forwarder_block_p (b))
-           BB_SET_FLAG (b, BB_FORWARDER_BLOCK);
+           b->flags |= BB_FORWARDER_BLOCK;
 
          do
            {
@@ -672,16 +649,15 @@ static void
 merge_blocks_move_predecessor_nojumps (basic_block a, basic_block b)
 {
   rtx barrier;
-  bool only_notes;
 
   /* If we are partitioning hot/cold basic blocks, we don't want to
      mess up unconditional or indirect jumps that cross between hot
      and cold sections.
-  
+
      Basic block partitioning may result in some jumps that appear to
-     be optimizable (or blocks that appear to be mergeable), but which really 
-     must be left untouched (they are required to make it safely across 
-     partition boundaries).  See the comments at the top of 
+     be optimizable (or blocks that appear to be mergeable), but which really
+     must be left untouched (they are required to make it safely across
+     partition boundaries).  See the comments at the top of
      bb-reorder.c:partition_hot_cold_basic_blocks for complete details.  */
 
   if (BB_PARTITION (a) != BB_PARTITION (b))
@@ -691,20 +667,10 @@ merge_blocks_move_predecessor_nojumps (basic_block a, basic_block b)
   gcc_assert (BARRIER_P (barrier));
   delete_insn (barrier);
 
-  /* Move block and loop notes out of the chain so that we do not
-     disturb their order.
-
-     ??? A better solution would be to squeeze out all the non-nested notes
-     and adjust the block trees appropriately.   Even better would be to have
-     a tighter connection between block trees and rtl so that this is not
-     necessary.  */
-  only_notes = squeeze_notes (&BB_HEAD (a), &BB_END (a));
-  gcc_assert (!only_notes);
-
   /* Scramble the insn chain.  */
   if (BB_END (a) != PREV_INSN (BB_HEAD (b)))
     reorder_insns_nobb (BB_HEAD (a), BB_END (a), PREV_INSN (BB_HEAD (b)));
-  a->flags |= BB_DIRTY;
+  df_set_bb_dirty (a);
 
   if (dump_file)
     fprintf (dump_file, "Moved block %d before %d and merged.\n",
@@ -728,16 +694,15 @@ merge_blocks_move_successor_nojumps (basic_block a, basic_block b)
 {
   rtx barrier, real_b_end;
   rtx label, table;
-  bool only_notes;
 
   /* If we are partitioning hot/cold basic blocks, we don't want to
      mess up unconditional or indirect jumps that cross between hot
-     and cold sections. 
-  
+     and cold sections.
+
      Basic block partitioning may result in some jumps that appear to
-     be optimizable (or blocks that appear to be mergeable), but which really 
-     must be left untouched (they are required to make it safely across 
-     partition boundaries).  See the comments at the top of 
+     be optimizable (or blocks that appear to be mergeable), but which really
+     must be left untouched (they are required to make it safely across
+     partition boundaries).  See the comments at the top of
      bb-reorder.c:partition_hot_cold_basic_blocks for complete details.  */
 
   if (BB_PARTITION (a) != BB_PARTITION (b))
@@ -758,16 +723,6 @@ merge_blocks_move_successor_nojumps (basic_block a, basic_block b)
   if (barrier && BARRIER_P (barrier))
     delete_insn (barrier);
 
-  /* Move block and loop notes out of the chain so that we do not
-     disturb their order.
-
-     ??? A better solution would be to squeeze out all the non-nested notes
-     and adjust the block trees appropriately.   Even better would be to have
-     a tighter connection between block trees and rtl so that this is not
-     necessary.  */
-  only_notes = squeeze_notes (&BB_HEAD (b), &BB_END (b));
-  gcc_assert (!only_notes);
-  
 
   /* Scramble the insn chain.  */
   reorder_insns_nobb (BB_HEAD (b), BB_END (b), BB_END (a));
@@ -802,18 +757,16 @@ merge_blocks_move (edge e, basic_block b, basic_block c, int mode)
 
   /* If we are partitioning hot/cold basic blocks, we don't want to
      mess up unconditional or indirect jumps that cross between hot
-     and cold sections. 
-  
+     and cold sections.
+
      Basic block partitioning may result in some jumps that appear to
-     be optimizable (or blocks that appear to be mergeable), but which really 
-     must be left untouched (they are required to make it safely across 
-     partition boundaries).  See the comments at the top of 
+     be optimizable (or blocks that appear to be mergeable), but which really
+     must be left untouched (they are required to make it safely across
+     partition boundaries).  See the comments at the top of
      bb-reorder.c:partition_hot_cold_basic_blocks for complete details.  */
 
   if (BB_PARTITION (b) != BB_PARTITION (c))
     return NULL;
-      
-    
 
   /* If B has a fallthru edge to C, no need to move anything.  */
   if (e->flags & EDGE_FALLTHRU)
@@ -839,7 +792,7 @@ merge_blocks_move (edge e, basic_block b, basic_block c, int mode)
       edge_iterator ei;
 
       /* Avoid overactive code motion, as the forwarder blocks should be
-         eliminated by edge redirection instead.  One exception might have
+        eliminated by edge redirection instead.  One exception might have
         been if B is a forwarder block and C has no fallthru edge, but
         that should be cleaned up by bb-reorder instead.  */
       if (FORWARDER_BLOCK_P (b) || FORWARDER_BLOCK_P (c))
@@ -871,7 +824,7 @@ merge_blocks_move (edge e, basic_block b, basic_block c, int mode)
       if (! c_has_outgoing_fallthru)
        {
          merge_blocks_move_successor_nojumps (b, c);
-          return next == ENTRY_BLOCK_PTR ? next->next_bb : next;
+         return next == ENTRY_BLOCK_PTR ? next->next_bb : next;
        }
 
       /* If B does not have an incoming fallthru, then it can be moved
@@ -928,7 +881,7 @@ merge_memattrs (rtx x, rtx y)
        MEM_ATTRS (y) = 0;
       else if (! MEM_ATTRS (y))
        MEM_ATTRS (x) = 0;
-      else 
+      else
        {
          rtx mem_size;
 
@@ -937,7 +890,7 @@ merge_memattrs (rtx x, rtx y)
              set_mem_alias_set (x, 0);
              set_mem_alias_set (y, 0);
            }
-         
+
          if (! mem_expr_equal_p (MEM_EXPR (x), MEM_EXPR (y)))
            {
              set_mem_expr (x, 0);
@@ -950,7 +903,7 @@ merge_memattrs (rtx x, rtx y)
              set_mem_offset (x, 0);
              set_mem_offset (y, 0);
            }
-        
+
          if (!MEM_SIZE (x))
            mem_size = NULL_RTX;
          else if (!MEM_SIZE (y))
@@ -965,7 +918,7 @@ merge_memattrs (rtx x, rtx y)
          set_mem_align (y, MEM_ALIGN (x));
        }
     }
-  
+
   fmt = GET_RTX_FORMAT (code);
   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
     {
@@ -992,7 +945,7 @@ merge_memattrs (rtx x, rtx y)
 /* Return true if I1 and I2 are equivalent and thus can be crossjumped.  */
 
 static bool
-insns_match_p (int mode ATTRIBUTE_UNUSED, rtx i1, rtx i2)
+old_insns_match_p (int mode ATTRIBUTE_UNUSED, rtx i1, rtx i2)
 {
   rtx p1, p2;
 
@@ -1018,7 +971,7 @@ insns_match_p (int mode ATTRIBUTE_UNUSED, rtx i1, rtx i2)
 
   if (CALL_P (i1)
       && (!rtx_equal_p (CALL_INSN_FUNCTION_USAGE (i1),
-                       CALL_INSN_FUNCTION_USAGE (i2))
+                       CALL_INSN_FUNCTION_USAGE (i2))
          || SIBLING_CALL_P (i1) != SIBLING_CALL_P (i2)))
     return false;
 
@@ -1030,8 +983,8 @@ insns_match_p (int mode ATTRIBUTE_UNUSED, rtx i1, rtx i2)
   if ((mode & CLEANUP_POST_REGSTACK) && stack_regs_mentioned (i1))
     {
       /* If register stack conversion has already been done, then
-         death notes must also be compared before it is certain that
-         the two instruction streams match.  */
+        death notes must also be compared before it is certain that
+        the two instruction streams match.  */
 
       rtx note;
       HARD_REG_SET i1_regset, i2_regset;
@@ -1047,12 +1000,8 @@ insns_match_p (int mode ATTRIBUTE_UNUSED, rtx i1, rtx i2)
        if (REG_NOTE_KIND (note) == REG_DEAD && STACK_REG_P (XEXP (note, 0)))
          SET_HARD_REG_BIT (i2_regset, REGNO (XEXP (note, 0)));
 
-      GO_IF_HARD_REG_EQUAL (i1_regset, i2_regset, done);
-
-      return false;
-
-    done:
-      ;
+      if (!hard_reg_set_equal_p (i1_regset, i2_regset))
+       return false;
     }
 #endif
 
@@ -1060,40 +1009,6 @@ insns_match_p (int mode ATTRIBUTE_UNUSED, rtx i1, rtx i2)
       ? rtx_renumbered_equal_p (p1, p2) : rtx_equal_p (p1, p2))
     return true;
 
-  /* Do not do EQUIV substitution after reload.  First, we're undoing the
-     work of reload_cse.  Second, we may be undoing the work of the post-
-     reload splitting pass.  */
-  /* ??? Possibly add a new phase switch variable that can be used by
-     targets to disallow the troublesome insns after splitting.  */
-  if (!reload_completed)
-    {
-      /* The following code helps take care of G++ cleanups.  */
-      rtx equiv1 = find_reg_equal_equiv_note (i1);
-      rtx equiv2 = find_reg_equal_equiv_note (i2);
-
-      if (equiv1 && equiv2
-         /* If the equivalences are not to a constant, they may
-            reference pseudos that no longer exist, so we can't
-            use them.  */
-         && (! reload_completed
-             || (CONSTANT_P (XEXP (equiv1, 0))
-                 && rtx_equal_p (XEXP (equiv1, 0), XEXP (equiv2, 0)))))
-       {
-         rtx s1 = single_set (i1);
-         rtx s2 = single_set (i2);
-         if (s1 != 0 && s2 != 0
-             && rtx_renumbered_equal_p (SET_DEST (s1), SET_DEST (s2)))
-           {
-             validate_change (i1, &SET_SRC (s1), XEXP (equiv1, 0), 1);
-             validate_change (i2, &SET_SRC (s2), XEXP (equiv2, 0), 1);
-             if (! rtx_renumbered_equal_p (p1, p2))
-               cancel_changes (0);
-             else if (apply_change_group ())
-               return true;
-           }
-       }
-    }
-
   return false;
 }
 \f
@@ -1146,7 +1061,7 @@ flow_find_cross_jump (int mode ATTRIBUTE_UNUSED, basic_block bb1,
       if (i1 == BB_HEAD (bb1) || i2 == BB_HEAD (bb2))
        break;
 
-      if (!insns_match_p (mode, i1, i2))
+      if (!old_insns_match_p (mode, i1, i2))
        break;
 
       merge_memattrs (i1, i2);
@@ -1256,7 +1171,7 @@ outgoing_edges_match (int mode, basic_block bb1, basic_block bb2)
       f2 = FALLTHRU_EDGE (bb2);
 
       /* Get around possible forwarders on fallthru edges.  Other cases
-         should be optimized out already.  */
+        should be optimized out already.  */
       if (FORWARDER_BLOCK_P (f1->dest))
        f1 = single_succ_edge (f1->dest);
 
@@ -1311,9 +1226,8 @@ outgoing_edges_match (int mode, basic_block bb1, basic_block bb2)
         we require the existing branches to have probabilities that are
         roughly similar.  */
       if (match
-         && !optimize_size
-         && maybe_hot_bb_p (bb1)
-         && maybe_hot_bb_p (bb2))
+         && optimize_bb_for_speed_p (bb1)
+         && optimize_bb_for_speed_p (bb2))
        {
          int prob2;
 
@@ -1401,7 +1315,7 @@ outgoing_edges_match (int mode, basic_block bb1, basic_block bb2)
                  rr.update_label_nuses = false;
                  for_each_rtx (&BB_END (bb1), replace_label, &rr);
 
-                 match = insns_match_p (mode, BB_END (bb1), BB_END (bb2));
+                 match = old_insns_match_p (mode, BB_END (bb1), BB_END (bb2));
                  if (dump_file && match)
                    fprintf (dump_file,
                             "Tablejumps in bb %i and %i match.\n",
@@ -1423,7 +1337,7 @@ outgoing_edges_match (int mode, basic_block bb1, basic_block bb2)
 
   /* First ensure that the instructions match.  There may be many outgoing
      edges so this test is generally cheaper.  */
-  if (!insns_match_p (mode, BB_END (bb1), BB_END (bb2)))
+  if (!old_insns_match_p (mode, BB_END (bb1), BB_END (bb2)))
     return false;
 
   /* Search the outgoing edges, ensure that the counts do match, find possible
@@ -1435,7 +1349,7 @@ outgoing_edges_match (int mode, basic_block bb1, basic_block bb2)
   FOR_EACH_EDGE (e1, ei, bb1->succs)
     {
       e2 = EDGE_SUCC (bb2, ei.index);
-      
+
       if (e1->flags & EDGE_EH)
        nehedges1++;
 
@@ -1477,11 +1391,43 @@ outgoing_edges_match (int mode, basic_block bb1, basic_block bb2)
       return false;
   }
 
-  /* We don't need to match the rest of edges as above checks should be enough
-     to ensure that they are equivalent.  */
+  /* The same checks as in try_crossjump_to_edge. It is required for RTL
+     version of sequence abstraction.  */
+  FOR_EACH_EDGE (e1, ei, bb2->succs)
+    {
+      edge e2;
+      edge_iterator ei;
+      basic_block d1 = e1->dest;
+
+      if (FORWARDER_BLOCK_P (d1))
+        d1 = EDGE_SUCC (d1, 0)->dest;
+
+      FOR_EACH_EDGE (e2, ei, bb1->succs)
+        {
+          basic_block d2 = e2->dest;
+          if (FORWARDER_BLOCK_P (d2))
+            d2 = EDGE_SUCC (d2, 0)->dest;
+          if (d1 == d2)
+            break;
+        }
+
+      if (!e2)
+        return false;
+    }
+
   return true;
 }
 
+/* Returns true if BB basic block has a preserve label.  */
+
+static bool
+block_has_preserve_label (basic_block bb)
+{
+  return (bb
+          && block_label (bb)
+          && LABEL_PRESERVE_P (block_label (bb)));
+}
+
 /* E1 and E2 are edges with the same destination block.  Search their
    predecessors for common code.  If found, redirect control flow from
    (maybe the middle of) E1->SRC to (maybe the middle of) E2->SRC.  */
@@ -1499,15 +1445,15 @@ try_crossjump_to_edge (int mode, edge e1, edge e2)
   newpos1 = newpos2 = NULL_RTX;
 
   /* If we have partitioned hot/cold basic blocks, it is a bad idea
-     to try this optimization. 
+     to try this optimization.
 
      Basic block partitioning may result in some jumps that appear to
-     be optimizable (or blocks that appear to be mergeable), but which really 
-     must be left untouched (they are required to make it safely across 
-     partition boundaries).  See the comments at the top of 
+     be optimizable (or blocks that appear to be mergeable), but which really
+     must be left untouched (they are required to make it safely across
+     partition boundaries).  See the comments at the top of
      bb-reorder.c:partition_hot_cold_basic_blocks for complete details.  */
 
-  if (flag_reorder_blocks_and_partition && no_new_pseudos)
+  if (flag_reorder_blocks_and_partition && reload_completed)
     return false;
 
   /* Search backward through forwarder blocks.  We don't need to worry
@@ -1557,6 +1503,11 @@ try_crossjump_to_edge (int mode, edge e1, edge e2)
       && (newpos1 != BB_HEAD (src1)))
     return false;
 
+  /* Avoid deleting preserve label when redirecting ABNORMAL edges.  */
+  if (block_has_preserve_label (e1->dest)
+      && (e1->flags & EDGE_ABNORMAL))
+    return false;
+
   /* Here we know that the insns in the end of SRC1 which are common with SRC2
      will be deleted.
      If we have tablejumps in the end of SRC1 and SRC2
@@ -1588,11 +1539,23 @@ try_crossjump_to_edge (int mode, edge e1, edge e2)
        }
     }
 
-  /* Avoid splitting if possible.  */
-  if (newpos2 == BB_HEAD (src2))
+  /* Avoid splitting if possible.  We must always split when SRC2 has
+     EH predecessor edges, or we may end up with basic blocks with both
+     normal and EH predecessor edges.  */
+  if (newpos2 == BB_HEAD (src2)
+      && !(EDGE_PRED (src2, 0)->flags & EDGE_EH))
     redirect_to = src2;
   else
     {
+      if (newpos2 == BB_HEAD (src2))
+       {
+         /* Skip possible basic block header.  */
+         if (LABEL_P (newpos2))
+           newpos2 = NEXT_INSN (newpos2);
+         if (NOTE_P (newpos2))
+           newpos2 = NEXT_INSN (newpos2);
+       }
+
       if (dump_file)
        fprintf (dump_file, "Splitting bb %i before %i insns\n",
                 src2->index, nmatch);
@@ -1604,10 +1567,8 @@ try_crossjump_to_edge (int mode, edge e1, edge e2)
             "Cross jumping from bb %i to bb %i; %i common insns\n",
             src1->index, src2->index, nmatch);
 
-  redirect_to->count += src1->count;
-  redirect_to->frequency += src1->frequency;
-  /* We may have some registers visible trought the block.  */
-  redirect_to->flags |= BB_DIRTY;
+  /* We may have some registers visible through the block.  */
+  df_set_bb_dirty (redirect_to);
 
   /* Recompute the frequencies and counts of outgoing edges.  */
   FOR_EACH_EDGE (s, ei, redirect_to->succs)
@@ -1631,8 +1592,8 @@ try_crossjump_to_edge (int mode, edge e1, edge e2)
       s->count += s2->count;
 
       /* Take care to update possible forwarder blocks.  We verified
-         that there is no more than one in the chain, so we can't run
-         into infinite loop.  */
+        that there is no more than one in the chain, so we can't run
+        into infinite loop.  */
       if (FORWARDER_BLOCK_P (s->dest))
        {
          single_succ_edge (s->dest)->count += s2->count;
@@ -1662,6 +1623,14 @@ try_crossjump_to_edge (int mode, edge e1, edge e2)
             / (redirect_to->frequency + src1->frequency));
     }
 
+  /* Adjust count and frequency for the block.  An earlier jump
+     threading pass may have left the profile in an inconsistent
+     state (see update_bb_profile_for_threading) so we must be
+     prepared for overflows.  */
+  redirect_to->count += src1->count;
+  redirect_to->frequency += src1->frequency;
+  if (redirect_to->frequency > BB_FREQ_MAX)
+    redirect_to->frequency = BB_FREQ_MAX;
   update_br_prob_note (redirect_to);
 
   /* Edit SRC1 to go to REDIRECT_TO at NEWPOS1.  */
@@ -1669,8 +1638,7 @@ try_crossjump_to_edge (int mode, edge e1, edge e2)
   /* Skip possible basic block header.  */
   if (LABEL_P (newpos1))
     newpos1 = NEXT_INSN (newpos1);
-
-  if (NOTE_P (newpos1))
+  if (NOTE_INSN_BASIC_BLOCK_P (newpos1))
     newpos1 = NEXT_INSN (newpos1);
 
   redirect_from = split_block (src1, PREV_INSN (newpos1))->src;
@@ -1705,23 +1673,23 @@ try_crossjump_bb (int mode, basic_block bb)
 
   /* Don't crossjump if this block ends in a computed jump,
      unless we are optimizing for size.  */
-  if (!optimize_size
+  if (optimize_bb_for_size_p (bb)
       && bb != EXIT_BLOCK_PTR
       && computed_jump_p (BB_END (bb)))
     return false;
 
   /* If we are partitioning hot/cold basic blocks, we don't want to
      mess up unconditional or indirect jumps that cross between hot
-     and cold sections. 
-  
+     and cold sections.
+
      Basic block partitioning may result in some jumps that appear to
-     be optimizable (or blocks that appear to be mergeable), but which really 
-     must be left untouched (they are required to make it safely across 
-     partition boundaries).  See the comments at the top of 
+     be optimizable (or blocks that appear to be mergeable), but which really
+     must be left untouched (they are required to make it safely across
+     partition boundaries).  See the comments at the top of
      bb-reorder.c:partition_hot_cold_basic_blocks for complete details.  */
 
-  if (BB_PARTITION (EDGE_PRED (bb, 0)->src) != 
-                                        BB_PARTITION (EDGE_PRED (bb, 1)->src)
+  if (BB_PARTITION (EDGE_PRED (bb, 0)->src) !=
+                                       BB_PARTITION (EDGE_PRED (bb, 1)->src)
       || (EDGE_PRED (bb, 0)->flags & EDGE_CROSSING))
     return false;
 
@@ -1737,7 +1705,10 @@ try_crossjump_bb (int mode, basic_block bb)
   FOR_EACH_EDGE (e, ei, bb->preds)
     {
       if (e->flags & EDGE_FALLTHRU)
-        fallthru = e;
+       {
+         fallthru = e;
+         break;
+       }
     }
 
   changed = false;
@@ -1746,7 +1717,8 @@ try_crossjump_bb (int mode, basic_block bb)
       e = EDGE_PRED (ev, ix);
       ix++;
 
-      /* As noted above, first try with the fallthru predecessor.  */
+      /* As noted above, first try with the fallthru predecessor (or, a
+        fallthru predecessor if we are in cfglayout mode).  */
       if (fallthru)
        {
          /* Don't combine the fallthru edge into anything else.
@@ -1756,8 +1728,8 @@ try_crossjump_bb (int mode, basic_block bb)
          /* If nothing changed since the last attempt, there is nothing
             we can do.  */
          if (!first_pass
-             && (!(e->src->flags & BB_DIRTY)
-                 && !(fallthru->src->flags & BB_DIRTY)))
+             && (!(df_get_bb_dirty (e->src))
+                 && !(df_get_bb_dirty (fallthru->src))))
            continue;
 
          if (try_crossjump_to_edge (mode, e, fallthru))
@@ -1806,8 +1778,8 @@ try_crossjump_bb (int mode, basic_block bb)
          /* If nothing changed since the last attempt, there is nothing
             we can do.  */
          if (!first_pass
-             && (!(e->src->flags & BB_DIRTY)
-                 && !(e2->src->flags & BB_DIRTY)))
+             && (!(df_get_bb_dirty (e->src))
+                 && !(df_get_bb_dirty (e2->src))))
            continue;
 
          if (try_crossjump_to_edge (mode, e, e2))
@@ -1820,6 +1792,9 @@ try_crossjump_bb (int mode, basic_block bb)
        }
     }
 
+  if (changed)
+    crossjumps_occured = true;
+
   return changed;
 }
 
@@ -1834,15 +1809,14 @@ try_optimize_cfg (int mode)
   int iterations = 0;
   basic_block bb, b, next;
 
-  if (mode & CLEANUP_CROSSJUMP)
-    add_noreturn_fake_exit_edges ();
+  if (mode & (CLEANUP_CROSSJUMP | CLEANUP_THREADING))
+    clear_bb_flags ();
+
+  crossjumps_occured = false;
 
   FOR_EACH_BB (bb)
     update_forwarder_flag (bb);
 
-  if (mode & (CLEANUP_UPDATE_LIFE | CLEANUP_CROSSJUMP | CLEANUP_THREADING))
-    clear_bb_flags ();
-
   if (! targetm.cannot_modify_jumps_p ())
     {
       first_pass = true;
@@ -1865,8 +1839,12 @@ try_optimize_cfg (int mode)
              edge s;
              bool changed_here = false;
 
-             /* Delete trivially dead basic blocks.  */
-             while (EDGE_COUNT (b->preds) == 0)
+             /* Delete trivially dead basic blocks.  This is either
+                blocks with no predecessors, or empty blocks with no
+                successors.  Empty blocks may result from expanding
+                __builtin_unreachable ().  */
+             if (EDGE_COUNT (b->preds) == 0
+                 || (EDGE_COUNT (b->succs) == 0 && BB_HEAD (b) == BB_END (b)))
                {
                  c = b->prev_bb;
                  if (dump_file)
@@ -1876,7 +1854,9 @@ try_optimize_cfg (int mode)
                  delete_basic_block (b);
                  if (!(mode & CLEANUP_CFGLAYOUT))
                    changed = true;
-                 b = c;
+                 /* Avoid trying to remove ENTRY_BLOCK_PTR.  */
+                 b = (c == ENTRY_BLOCK_PTR ? c->next_bb : c);
+                 continue;
                }
 
              /* Remove code labels no longer used.  */
@@ -1897,15 +1877,17 @@ try_optimize_cfg (int mode)
                {
                  rtx label = BB_HEAD (b);
 
-                 delete_insn_chain (label, label);
-                 /* In the case label is undeletable, move it after the
+                 delete_insn_chain (label, label, false);
+                 /* If the case label is undeletable, move it after the
                     BASIC_BLOCK note.  */
-                 if (NOTE_LINE_NUMBER (BB_HEAD (b)) == NOTE_INSN_DELETED_LABEL)
+                 if (NOTE_KIND (BB_HEAD (b)) == NOTE_INSN_DELETED_LABEL)
                    {
                      rtx bb_note = NEXT_INSN (BB_HEAD (b));
 
                      reorder_insns_nobb (label, label, bb_note);
                      BB_HEAD (b) = bb_note;
+                     if (BB_END (b) == bb_note)
+                       BB_END (b) = label;
                    }
                  if (dump_file)
                    fprintf (dump_file, "Deleted label in block %i.\n",
@@ -1921,7 +1903,7 @@ try_optimize_cfg (int mode)
                  /* Note that forwarder_block_p true ensures that
                     there is a successor for this block.  */
                  && (single_succ_edge (b)->flags & EDGE_FALLTHRU)
-                 && n_basic_blocks > 1)
+                 && n_basic_blocks > NUM_FIXED_BLOCKS + 1)
                {
                  if (dump_file)
                    fprintf (dump_file,
@@ -1948,7 +1930,7 @@ try_optimize_cfg (int mode)
                     does not fit merge_blocks interface and is kept here in
                     hope that it will become useless once more of compiler
                     is transformed to use cfg_layout mode.  */
-                    
+
                  if ((mode & CLEANUP_CFGLAYOUT)
                      && can_merge_blocks_p (b, c))
                    {
@@ -2026,10 +2008,8 @@ try_optimize_cfg (int mode)
       while (changed);
     }
 
-  if (mode & CLEANUP_CROSSJUMP)
-    remove_fake_exit_edges ();
-
-  clear_aux_for_blocks ();
+  FOR_ALL_BB (b)
+    b->flags &= ~(BB_FORWARDER_BLOCK | BB_NONTHREADABLE_BLOCK);
 
   return changed_overall;
 }
@@ -2062,30 +2042,46 @@ delete_unreachable_blocks (void)
   return changed;
 }
 
-/* Merges sequential blocks if possible.  */
-
-bool
-merge_seq_blocks (void)
+/* Delete any jump tables never referenced.  We can't delete them at the
+   time of removing tablejump insn as they are referenced by the preceding
+   insns computing the destination, so we delay deleting and garbagecollect
+   them once life information is computed.  */
+void
+delete_dead_jumptables (void)
 {
   basic_block bb;
-  bool changed = false;
 
-  for (bb = ENTRY_BLOCK_PTR->next_bb; bb != EXIT_BLOCK_PTR; )
+  /* A dead jump table does not belong to any basic block.  Scan insns
+     between two adjacent basic blocks.  */
+  FOR_EACH_BB (bb)
     {
-      if (single_succ_p (bb)
-         && can_merge_blocks_p (bb, single_succ (bb)))
+      rtx insn, next;
+
+      for (insn = NEXT_INSN (BB_END (bb));
+          insn && !NOTE_INSN_BASIC_BLOCK_P (insn);
+          insn = next)
        {
-         /* Merge the blocks and retry.  */
-         merge_blocks (bb, single_succ (bb));
-         changed = true;
-         continue;
-       }
+         next = NEXT_INSN (insn);
+         if (LABEL_P (insn)
+             && LABEL_NUSES (insn) == LABEL_PRESERVE_P (insn)
+             && JUMP_P (next)
+             && (GET_CODE (PATTERN (next)) == ADDR_VEC
+                 || GET_CODE (PATTERN (next)) == ADDR_DIFF_VEC))
+           {
+             rtx label = insn, jump = next;
 
-      bb = bb->next_bb;
-    }
+             if (dump_file)
+               fprintf (dump_file, "Dead jumptable %i removed\n",
+                        INSN_UID (insn));
 
-  return changed;
+             next = NEXT_INSN (next);
+             delete_insn (jump);
+             delete_insn (label);
+           }
+       }
+    }
 }
+
 \f
 /* Tidy the CFG by deleting unreachable code and whatnot.  */
 
@@ -2094,66 +2090,95 @@ cleanup_cfg (int mode)
 {
   bool changed = false;
 
+  /* Set the cfglayout mode flag here.  We could update all the callers
+     but that is just inconvenient, especially given that we eventually
+     want to have cfglayout mode as the default.  */
+  if (current_ir_type () == IR_RTL_CFGLAYOUT)
+    mode |= CLEANUP_CFGLAYOUT;
+
   timevar_push (TV_CLEANUP_CFG);
   if (delete_unreachable_blocks ())
     {
       changed = true;
       /* We've possibly created trivially dead code.  Cleanup it right
         now to introduce more opportunities for try_optimize_cfg.  */
-      if (!(mode & (CLEANUP_NO_INSN_DEL | CLEANUP_UPDATE_LIFE))
+      if (!(mode & (CLEANUP_NO_INSN_DEL))
          && !reload_completed)
-       delete_trivially_dead_insns (get_insns(), max_reg_num ());
+       delete_trivially_dead_insns (get_insns (), max_reg_num ());
     }
 
   compact_blocks ();
 
+  /* To tail-merge blocks ending in the same noreturn function (e.g.
+     a call to abort) we have to insert fake edges to exit.  Do this
+     here once.  The fake edges do not interfere with any other CFG
+     cleanups.  */
+  if (mode & CLEANUP_CROSSJUMP)
+    add_noreturn_fake_exit_edges ();
+
+  if (!dbg_cnt (cfg_cleanup))
+    return changed;
+
   while (try_optimize_cfg (mode))
     {
       delete_unreachable_blocks (), changed = true;
-      if (mode & CLEANUP_UPDATE_LIFE)
-       {
-         /* Cleaning up CFG introduces more opportunities for dead code
-            removal that in turn may introduce more opportunities for
-            cleaning up the CFG.  */
-         if (!update_life_info_in_dirty_blocks (UPDATE_LIFE_GLOBAL_RM_NOTES,
-                                                PROP_DEATH_NOTES
-                                                | PROP_SCAN_DEAD_CODE
-                                                | PROP_KILL_DEAD_CODE
-                                                | ((mode & CLEANUP_LOG_LINKS)
-                                                   ? PROP_LOG_LINKS : 0)))
-           break;
-       }
-      else if (!(mode & CLEANUP_NO_INSN_DEL)
-              && (mode & CLEANUP_EXPENSIVE)
-              && !reload_completed)
+      if (!(mode & CLEANUP_NO_INSN_DEL))
        {
-         if (!delete_trivially_dead_insns (get_insns(), max_reg_num ()))
+         /* Try to remove some trivially dead insns when doing an expensive
+            cleanup.  But delete_trivially_dead_insns doesn't work after
+            reload (it only handles pseudos) and run_fast_dce is too costly
+            to run in every iteration.
+
+            For effective cross jumping, we really want to run a fast DCE to
+            clean up any dead conditions, or they get in the way of performing
+            useful tail merges.
+
+            Other transformations in cleanup_cfg are not so sensitive to dead
+            code, so delete_trivially_dead_insns or even doing nothing at all
+            is good enough.  */
+         if ((mode & CLEANUP_EXPENSIVE) && !reload_completed
+             && !delete_trivially_dead_insns (get_insns (), max_reg_num ()))
            break;
+         else if ((mode & CLEANUP_CROSSJUMP)
+                  && crossjumps_occured)
+           run_fast_dce ();
        }
       else
        break;
-      delete_dead_jumptables ();
     }
 
+  if (mode & CLEANUP_CROSSJUMP)
+    remove_fake_exit_edges ();
+
+  /* Don't call delete_dead_jumptables in cfglayout mode, because
+     that function assumes that jump tables are in the insns stream.
+     But we also don't _have_ to delete dead jumptables in cfglayout
+     mode because we shouldn't even be looking at things that are
+     not in a basic block.  Dead jumptables are cleaned up when
+     going out of cfglayout mode.  */
+  if (!(mode & CLEANUP_CFGLAYOUT))
+    delete_dead_jumptables ();
+
   timevar_pop (TV_CLEANUP_CFG);
 
   return changed;
 }
 \f
-static void
+static unsigned int
 rest_of_handle_jump (void)
 {
-  delete_unreachable_blocks ();
-
-  if (cfun->tail_call_emit)
+  if (crtl->tail_call_emit)
     fixup_tail_calls ();
+  return 0;
 }
 
-struct tree_opt_pass pass_jump =
+struct rtl_opt_pass pass_jump =
 {
+ {
+  RTL_PASS,
   "sibling",                            /* name */
-  NULL,                                 /* gate */   
-  rest_of_handle_jump,                 /* execute */       
+  NULL,                                 /* gate */
+  rest_of_handle_jump,                 /* execute */
   NULL,                                 /* sub */
   NULL,                                 /* next */
   0,                                    /* static_pass_number */
@@ -2162,48 +2187,30 @@ struct tree_opt_pass pass_jump =
   0,                                    /* properties_provided */
   0,                                    /* properties_destroyed */
   TODO_ggc_collect,                     /* todo_flags_start */
-  TODO_dump_func |
   TODO_verify_flow,                     /* todo_flags_finish */
-  'i'                                   /* letter */
+ }
 };
 
 
-static void
+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)
-    dump_flow_info (dump_file);
-  cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0) | CLEANUP_PRE_LOOP
-               | (flag_thread_jumps ? CLEANUP_THREADING : 0));
-
-  create_loop_notes ();
-
-  purge_line_number_notes ();
-
-  if (optimize)
-    cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
-
-  /* Jump optimization, and the removal of NULL pointer checks, may
-     have reduced the number of instructions substantially.  CSE, and
-     future passes, allocate arrays whose dimensions involve the
-     maximum instruction UID, so if we can reduce the maximum UID
-     we'll save big on memory.  */
-  renumber_insns (dump_file);
+    dump_flow_info (dump_file, dump_flags);
+  cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0)
+              | (flag_thread_jumps ? CLEANUP_THREADING : 0));
+  return 0;
 }
 
 
-struct tree_opt_pass pass_jump2 =
+struct rtl_opt_pass pass_jump2 =
 {
+ {
+  RTL_PASS,
   "jump",                               /* name */
-  NULL,                                 /* gate */   
-  rest_of_handle_jump2,                        /* execute */       
+  NULL,                                 /* gate */
+  rest_of_handle_jump2,                        /* execute */
   NULL,                                 /* sub */
   NULL,                                 /* next */
   0,                                    /* static_pass_number */
@@ -2212,8 +2219,8 @@ struct tree_opt_pass pass_jump2 =
   0,                                    /* properties_provided */
   0,                                    /* properties_destroyed */
   TODO_ggc_collect,                     /* todo_flags_start */
-  TODO_dump_func,                       /* todo_flags_finish */
-  'j'                                   /* letter */
+  TODO_dump_func | TODO_verify_rtl_sharing,/* todo_flags_finish */
+ }
 };