OSDN Git Service

* basic-block.h (find_sub_basic_block): Declare.
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 23 Jul 2001 14:08:12 +0000 (14:08 +0000)
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 23 Jul 2001 14:08:12 +0000 (14:08 +0000)
* flow.c (make_edges): New arguments MIN and MAX;
(find_sub_basic_blocks): Revamp to use make_edges
and purge_dead_edges.
(find_basic_blocks): Update call of find_sub_basic_block.

* recog.c (split_all_insns): Always expect CFG to be consistent;
call find_sub_basic_blocks in case something has changed.
* toplev.c (rest_of_compilation): Always call split_all_insns once CFG
has been built.

* basic-block.h (delete_noop_moves): Declare.
* combine.c (combine_instructions): Call it.
(recog_for_combine): Tolerate noop moves
(distribute_notes): Force refresh when register dies at noop move.
* flow.c (delete_noop_moves): Use BB structure; delete JUMP insns
too.
(life_analysis): Update delete_noop_moves call.
(set_noop_p): Move too ...
* rtlanal.c (noop_move_p): ... here.
* rtl.h (noop_move_p): Declare.

* basic-block.h (purge_all_dead_edges, purge_dead_edges): New functions.
* toplev.c (rest_of_compilation): Conditionally call purge_all_dead_edges
after combine.
* gcse.c (cprop_cc0_jump, cprop_insn): New argument "basic_block".
(cprop_jump): Likewise; call purge_dead_edges if substitution suceeded.

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

gcc/ChangeLog
gcc/basic-block.h
gcc/combine.c
gcc/flow.c
gcc/gcse.c
gcc/recog.c
gcc/rtl.h
gcc/rtlanal.c
gcc/toplev.c

index b400b34..5de1093 100644 (file)
@@ -1,3 +1,33 @@
+Mon Jul 23 16:03:19 CEST 2001  Jan Hubicka  <jh@suse.cz>
+
+       * basic-block.h (find_sub_basic_block): Declare.
+       * flow.c (make_edges): New arguments MIN and MAX;
+       (find_sub_basic_blocks): Revamp to use make_edges
+       and purge_dead_edges.
+       (find_basic_blocks): Update call of find_sub_basic_block.
+
+       * recog.c (split_all_insns): Always expect CFG to be consistent;
+       call find_sub_basic_blocks in case something has changed.
+       * toplev.c (rest_of_compilation): Always call split_all_insns once CFG
+       has been built.
+
+       * basic-block.h (delete_noop_moves): Declare.
+       * combine.c (combine_instructions): Call it.
+       (recog_for_combine): Tolerate noop moves
+       (distribute_notes): Force refresh when register dies at noop move.
+       * flow.c (delete_noop_moves): Use BB structure; delete JUMP insns
+       too.
+       (life_analysis): Update delete_noop_moves call.
+       (set_noop_p): Move too ...
+       * rtlanal.c (noop_move_p): ... here.
+       * rtl.h (noop_move_p): Declare.
+
+       * basic-block.h (purge_all_dead_edges, purge_dead_edges): New functions.
+       * toplev.c (rest_of_compilation): Conditionally call purge_all_dead_edges
+       after combine.
+       * gcse.c (cprop_cc0_jump, cprop_insn): New argument "basic_block".
+       (cprop_jump): Likewise; call purge_dead_edges if substitution suceeded.
+
 2001-07-23  Hans-Peter Nilsson  <hp@bitrange.com>
 
        * reload.c (push_reload): Fix typo in comment.
index 6a6039e..b6e8c11 100644 (file)
@@ -597,10 +597,14 @@ extern void debug_regset          PARAMS ((regset));
 extern void allocate_reg_life_data      PARAMS ((void));
 extern void allocate_bb_life_data      PARAMS ((void));
 extern void find_unreachable_blocks    PARAMS ((void));
+extern void delete_noop_moves          PARAMS ((rtx));
 extern basic_block redirect_edge_and_branch_force PARAMS ((edge, basic_block));
 extern bool redirect_edge_and_branch   PARAMS ((edge, basic_block));
 extern rtx block_label                 PARAMS ((basic_block));
 extern bool forwarder_block_p          PARAMS ((basic_block));
+extern void purge_all_dead_edges       PARAMS ((void));
+extern void purge_dead_edges           PARAMS ((basic_block));
+extern void find_sub_basic_blocks      PARAMS ((basic_block));
 
 
 /* This function is always defined so it can be called from the
index 724e9ef..633d0ac 100644 (file)
@@ -713,6 +713,8 @@ combine_instructions (f, nregs)
        }
     }
 
+  delete_noop_moves (f);
+
   if (need_refresh)
     {
       compute_bb_for_insn (get_max_uid ());
@@ -9598,8 +9600,12 @@ recog_for_combine (pnewpat, insn, pnotes)
   old_notes = REG_NOTES (insn);
   REG_NOTES (insn) = 0;
 
-  /* Is the result of combination a valid instruction?  */
-  insn_code_number = recog (pat, insn, &num_clobbers_to_add);
+  /* Is the result of combination a valid instruction?
+     Recognize all noop sets, these will be killed by followup pass.  */
+  if (GET_CODE (pat) == SET && set_noop_p (pat))
+    insn_code_number = INT_MAX;
+  else
+    insn_code_number = recog (pat, insn, &num_clobbers_to_add);
 
   /* If it isn't, there is the possibility that we previously had an insn
      that clobbered some register as a side effect, but the combined
@@ -9624,7 +9630,11 @@ recog_for_combine (pnewpat, insn, pnotes)
       if (pos == 1)
        pat = XVECEXP (pat, 0, 0);
 
-      insn_code_number = recog (pat, insn, &num_clobbers_to_add);
+      /* Recognize all noop sets, these will be killed by followup pass.  */
+      if (GET_CODE (pat) == SET && set_noop_p (pat))
+       insn_code_number = INT_MAX;
+      else
+        insn_code_number = recog (pat, insn, &num_clobbers_to_add);
     }
 
   REG_NOTES (insn) = old_notes;
@@ -12325,10 +12335,16 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
                 is still a REG_DEAD note, but we have hit the beginning
                 of the block.  If the existing life info says the reg
                 was dead, there's nothing left to do.  Otherwise, we'll
-                need to do a global life update after combine.  */
-             if (REG_NOTE_KIND (note) == REG_DEAD && place == 0
-                 && REGNO_REG_SET_P (bb->global_live_at_start,
-                                     REGNO (XEXP (note, 0))))
+                need to do a global life update after combine.  
+              
+                Similary we need to update in case insn is an dead set
+                we are about to remove soon.
+              */
+             if (REG_NOTE_KIND (note) == REG_DEAD
+                 && ((place && noop_move_p (place))
+                     || (place == 0
+                         && REGNO_REG_SET_P (bb->global_live_at_start,
+                                              REGNO (XEXP (note, 0))))))
                {
                  SET_BIT (refresh_blocks, this_basic_block);
                  need_refresh = 1;
index 8d795a7..ac5cee5 100644 (file)
@@ -374,7 +374,7 @@ static int flow_find_cross_jump             PARAMS ((int, basic_block, basic_block,
 static int count_basic_blocks          PARAMS ((rtx));
 static void find_basic_blocks_1                PARAMS ((rtx));
 static rtx find_label_refs             PARAMS ((rtx, rtx));
-static void make_edges                 PARAMS ((rtx));
+static void make_edges                 PARAMS ((rtx, int, int));
 static void make_label_edge            PARAMS ((sbitmap *, basic_block,
                                                 rtx, int));
 static void make_eh_edge               PARAMS ((sbitmap *, basic_block, rtx));
@@ -401,8 +401,6 @@ static void tidy_fallthru_edges             PARAMS ((void));
 static int verify_wide_reg_1           PARAMS ((rtx *, void *));
 static void verify_wide_reg            PARAMS ((int, rtx, rtx));
 static void verify_local_live_at_start PARAMS ((regset, basic_block));
-static int noop_move_p                 PARAMS ((rtx));
-static void delete_noop_moves          PARAMS ((rtx));
 static void notice_stack_pointer_modification_1 PARAMS ((rtx, rtx, void *));
 static void notice_stack_pointer_modification PARAMS ((rtx));
 static void mark_reg                   PARAMS ((rtx, void *));
@@ -483,7 +481,6 @@ static void flow_loop_tree_node_add PARAMS ((struct loop *, struct loop *));
 static void flow_loops_tree_build      PARAMS ((struct loops *));
 static int flow_loop_level_compute     PARAMS ((struct loop *, int));
 static int flow_loops_level_compute    PARAMS ((struct loops *));
-static void find_sub_basic_blocks      PARAMS ((basic_block));
 \f
 /* Find basic blocks of the current function.
    F is the first insn of the function and NREGS the number of register
@@ -543,7 +540,7 @@ find_basic_blocks (f, nregs, file)
   compute_bb_for_insn (max_uid);
 
   /* Discover the edges of our cfg.  */
-  make_edges (label_value_list);
+  make_edges (label_value_list, 0, n_basic_blocks - 1);
 
   /* Do very simple cleanup now, for the benefit of code that runs between
      here and cleanup_cfg, e.g. thread_prologue_and_epilogue_insns.  */
@@ -705,39 +702,30 @@ find_label_refs (f, lvl)
 
 /* Assume that someone emitted code with control flow instructions to the
    basic block.  Update the data structure.  */
-static void
+void
 find_sub_basic_blocks (bb)
      basic_block bb;
 {
-  rtx first_insn = bb->head, insn;
+  rtx insn = bb->head;
   rtx end = bb->end;
-  edge succ_list = bb->succ;
   rtx jump_insn = NULL_RTX;
   int created = 0;
   int barrier = 0;
   edge falltru = 0;
-  basic_block first_bb = bb, last_bb;
-  int i;
+  basic_block first_bb = bb;
+
+  if (insn == bb->end)
+    return;
 
-  if (GET_CODE (first_insn) == LABEL_REF)
-    first_insn = NEXT_INSN (first_insn);
-  first_insn = NEXT_INSN (first_insn);
-  bb->succ = NULL;
+  if (GET_CODE (insn) == CODE_LABEL)
+    insn = NEXT_INSN (insn);
 
-  insn = first_insn;
   /* Scan insn chain and try to find new basic block boundaries.  */
-  while (insn != end)
+  while (1)
     {
       enum rtx_code code = GET_CODE (insn);
       switch (code)
        {
-       case JUMP_INSN:
-         /* We need some special care for those expressions.  */
-         if (GET_CODE (PATTERN (insn)) == ADDR_VEC
-             || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
-           abort();
-         jump_insn = insn;
-         break;
        case BARRIER:
          if (!jump_insn)
            abort ();
@@ -749,8 +737,7 @@ find_sub_basic_blocks (bb)
          if (jump_insn)
            bb->end = jump_insn;
          bb = falltru->dest;
-         if (barrier)
-           remove_edge (falltru);
+         remove_edge (falltru);
          barrier = 0;
          jump_insn = 0;
          created = 1;
@@ -758,6 +745,7 @@ find_sub_basic_blocks (bb)
            make_edge (NULL, ENTRY_BLOCK_PTR, bb, 0);
          break;
        case INSN:
+       case JUMP_INSN:
          /* In case we've previously split insn on the JUMP_INSN, move the
             block header to proper place.  */
          if (jump_insn)
@@ -765,42 +753,39 @@ find_sub_basic_blocks (bb)
              falltru = split_block (bb, PREV_INSN (insn));
              bb->end = jump_insn;
              bb = falltru->dest;
-             if (barrier)
-               abort ();
+             remove_edge (falltru);
              jump_insn = 0;
            }
+         /* We need some special care for those expressions.  */
+         if (GET_CODE (insn) == JUMP_INSN)
+           {
+             if (GET_CODE (PATTERN (insn)) == ADDR_VEC
+                 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
+               abort();
+             jump_insn = insn;
+           }
+         break;
        default:
          break;
        }
+      if (insn == end)
+       break;
       insn = NEXT_INSN (insn);
     }
-  /* Last basic block must end in the original BB end.  */
-  if (jump_insn)
-    abort ();
 
-  /* Wire in the original edges for last basic block.  */
-  if (created)
-    {
-      bb->succ = succ_list;
-      while (succ_list)
-       succ_list->src = bb, succ_list = succ_list->succ_next;
-    }
-  else
-    bb->succ = succ_list;
+  /* In case we've got barrier at the end of new insn stream, put it
+     outside basic block.  */
+  if (GET_CODE (bb->end) == BARRIER)
+    bb->end = PREV_INSN (bb->end);
+
+  /* We've possibly replaced the conditional jump by conditional jump
+     followed by cleanup at fallthru edge, so the outgoing edges may
+     be dead.  */
+  purge_dead_edges (bb);
 
   /* Now re-scan and wire in all edges.  This expect simple (conditional)
      jumps at the end of each new basic blocks.  */
-  last_bb = bb;
-  for (i = first_bb->index; i < last_bb->index; i++)
-    {
-      bb = BASIC_BLOCK (i);
-      if (GET_CODE (bb->end) == JUMP_INSN)
-       {
-         mark_jump_label (PATTERN (bb->end), bb->end, 0);
-         make_label_edge (NULL, bb, JUMP_LABEL (bb->end), 0);
-       }
-      insn = NEXT_INSN (insn);
-    }
+  make_edges (NULL, first_bb->index, bb->index - 1);
 }
 
 /* Find all basic blocks of the function whose first insn is F.
@@ -1166,7 +1151,7 @@ clear_edges ()
   n_edges = 0;
 }
 
-/* Identify the edges between basic blocks.
+/* Identify the edges between basic blocks MIN to MAX.
 
    NONLOCAL_LABEL_LIST is a list of non-local labels in the function.  Blocks
    that are otherwise unreachable may be reachable with a non-local goto.
@@ -1175,8 +1160,9 @@ clear_edges ()
    the list of exception regions active at the end of the basic block.  */
 
 static void
-make_edges (label_value_list)
+make_edges (label_value_list, min, max)
      rtx label_value_list;
+     int min, max;
 {
   int i;
   sbitmap *edge_cache = NULL;
@@ -1196,7 +1182,7 @@ make_edges (label_value_list)
   /* By nature of the way these get numbered, block 0 is always the entry.  */
   make_edge (edge_cache, ENTRY_BLOCK_PTR, BASIC_BLOCK (0), EDGE_FALLTHRU);
 
-  for (i = 0; i < n_basic_blocks; ++i)
+  for (i = min; i <= max; ++i)
     {
       basic_block bb = BASIC_BLOCK (i);
       rtx insn, x;
@@ -4317,58 +4303,28 @@ free_basic_block_vars (keep_head_end_p)
     }
 }
 
-/* Return nonzero if an insn consists only of SETs, each of which only sets a
-   value to itself.  */
-
-static int
-noop_move_p (insn)
-     rtx insn;
-{
-  rtx pat = PATTERN (insn);
-
-  /* Insns carrying these notes are useful later on.  */
-  if (find_reg_note (insn, REG_EQUAL, NULL_RTX))
-    return 0;
-
-  if (GET_CODE (pat) == SET && set_noop_p (pat))
-    return 1;
-
-  if (GET_CODE (pat) == PARALLEL)
-    {
-      int i;
-      /* If nothing but SETs of registers to themselves,
-        this insn can also be deleted.  */
-      for (i = 0; i < XVECLEN (pat, 0); i++)
-       {
-         rtx tem = XVECEXP (pat, 0, i);
-
-         if (GET_CODE (tem) == USE
-             || GET_CODE (tem) == CLOBBER)
-           continue;
-
-         if (GET_CODE (tem) != SET || ! set_noop_p (tem))
-           return 0;
-       }
-
-      return 1;
-    }
-  return 0;
-}
-
 /* Delete any insns that copy a register to itself.  */
 
-static void
+void
 delete_noop_moves (f)
-     rtx f;
+     rtx f ATTRIBUTE_UNUSED;
 {
-  rtx insn;
-  for (insn = f; insn; insn = NEXT_INSN (insn))
+  int i;
+  rtx insn, next;
+  basic_block bb;
+
+  for (i = 0; i < n_basic_blocks; i++)
     {
-      if (GET_CODE (insn) == INSN && noop_move_p (insn))
+      bb = BASIC_BLOCK (i);
+      for (insn = bb->head; insn != NEXT_INSN (bb->end); insn = next)
        {
-         PUT_CODE (insn, NOTE);
-         NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
-         NOTE_SOURCE_FILE (insn) = 0;
+         next = NEXT_INSN (insn);
+         if (INSN_P (insn) && noop_move_p (insn))
+           {
+             if (insn == bb->end)
+               bb->end = PREV_INSN (insn);
+             flow_delete_insn (insn);
+           }
        }
     }
 }
@@ -9814,3 +9770,69 @@ init_flow ()
       flow_firstobj = (char *) obstack_alloc (&flow_obstack, 0);
     }
 }
+
+/* Assume that the preceeding pass has possibly eliminated jump instructions
+   or converted the unconditional jumps.  Eliminate the edges from CFG.  */
+
+void
+purge_dead_edges (bb)
+     basic_block bb;
+{
+  edge e, next;
+  rtx insn = bb->end;
+  if (GET_CODE (insn) == JUMP_INSN && !simplejump_p (insn))
+    return;
+  if (GET_CODE (insn) == JUMP_INSN)
+    {
+      for (e = bb->succ; e; e = next)
+       {
+         next = e->succ_next;
+         if (e->dest == EXIT_BLOCK_PTR || e->dest->head != JUMP_LABEL (insn))
+           remove_edge (e);
+       }
+      if (bb->succ && bb->succ->succ_next)
+       abort ();
+      if (!bb->succ)
+       return;
+      bb->succ->probability = REG_BR_PROB_BASE;
+      bb->succ->count = bb->count;
+
+      if (rtl_dump_file)
+       fprintf (rtl_dump_file, "Purged edges from bb %i\n", bb->index);
+      return;
+    }
+  /* If we don't see a jump insn, we don't know exactly why the block would
+     have been broken at this point.  Look for a simple, non-fallthru edge,
+     as these are only created by conditional branches.  If we find such an
+     edge we know that there used to be a jump here and can then safely
+     remove all non-fallthru edges.  */
+  for (e = bb->succ; e && (e->flags & (EDGE_COMPLEX | EDGE_FALLTHRU));
+       e = e->succ_next);
+  if (!e)
+    return;
+  for (e = bb->succ; e; e = next)
+    {
+      next = e->succ_next;
+      if (!(e->flags & EDGE_FALLTHRU))
+       remove_edge (e);
+    }
+  if (!bb->succ || bb->succ->succ_next)
+    abort ();
+  bb->succ->probability = REG_BR_PROB_BASE;
+  bb->succ->count = bb->count;
+
+  if (rtl_dump_file)
+    fprintf (rtl_dump_file, "Purged non-fallthru edges from bb %i\n",
+            bb->index);
+  return;
+}
+
+/* Search all basic blocks for potentionally dead edges and purge them.  */
+
+void
+purge_all_dead_edges ()
+{
+  int i;
+  for (i = 0; i < n_basic_blocks; i++)
+    purge_dead_edges (BASIC_BLOCK (i));
+}
index d9f106c..7592204 100644 (file)
@@ -605,14 +605,14 @@ static void compute_cprop_data    PARAMS ((void));
 static void find_used_regs     PARAMS ((rtx *, void *));
 static int try_replace_reg     PARAMS ((rtx, rtx, rtx));
 static struct expr *find_avail_set PARAMS ((int, rtx));
-static int cprop_jump          PARAMS ((rtx, rtx, rtx));
+static int cprop_jump          PARAMS ((basic_block, rtx, rtx, rtx));
 #ifdef HAVE_cc0
-static int cprop_cc0_jump      PARAMS ((rtx, struct reg_use *, rtx));
+static int cprop_cc0_jump      PARAMS ((basic_block, rtx, struct reg_use *, rtx));
 #endif
 static void mems_conflict_for_gcse_p PARAMS ((rtx, rtx, void *));
 static int load_killed_in_block_p    PARAMS ((basic_block, int, rtx, int));
 static void canon_list_insert        PARAMS ((rtx, rtx, void *));
-static int cprop_insn          PARAMS ((rtx, int));
+static int cprop_insn          PARAMS ((basic_block, rtx, int));
 static int cprop               PARAMS ((int));
 static int one_cprop_pass      PARAMS ((int, int));
 static void alloc_pre_mem      PARAMS ((int, int));
@@ -4015,10 +4015,11 @@ find_avail_set (regno, insn)
    nonzero if a change was made.  We know INSN has just a SET.  */
 
 static int
-cprop_jump (insn, from, src)
+cprop_jump (bb, insn, from, src)
      rtx insn;
      rtx from;
      rtx src;
+     basic_block bb;
 {
   rtx set = PATTERN (insn);
   rtx new = simplify_replace_rtx (SET_SRC (set), from, src);
@@ -4059,6 +4060,7 @@ cprop_jump (insn, from, src)
       print_rtl (gcse_file, src);
       fprintf (gcse_file, "\n");
     }
+  purge_dead_edges (bb);
 
   return 1;
 }
@@ -4072,7 +4074,8 @@ cprop_jump (insn, from, src)
    Returns nonzero if a change was made.  */
 
 static int
-cprop_cc0_jump (insn, reg_used, src)
+cprop_cc0_jump (bb, insn, reg_used, src)
+     basic_block bb;
      rtx insn;
      struct reg_use *reg_used;
      rtx src;
@@ -4083,7 +4086,7 @@ cprop_cc0_jump (insn, reg_used, src)
   rtx new_src = simplify_replace_rtx (SET_SRC (PATTERN (insn)),
                                      reg_used->reg_rtx, src);
 
-  if (! cprop_jump (jump, cc0_rtx, new_src))
+  if (! cprop_jump (bb, jump, cc0_rtx, new_src))
     return 0;
 
   /* If we succeeded, delete the cc0 setter.  */
@@ -4099,7 +4102,8 @@ cprop_cc0_jump (insn, reg_used, src)
    The result is non-zero if a change was made.  */
 
 static int
-cprop_insn (insn, alter_jumps)
+cprop_insn (bb, insn, alter_jumps)
+     basic_block bb;
      rtx insn;
      int alter_jumps;
 {
@@ -4183,7 +4187,7 @@ cprop_insn (insn, alter_jumps)
                   && GET_CODE (insn) == JUMP_INSN
                   && condjump_p (insn)
                   && ! simplejump_p (insn))
-           changed |= cprop_jump (insn, reg_used->reg_rtx, src);
+           changed |= cprop_jump (bb, insn, reg_used->reg_rtx, src);
 
 #ifdef HAVE_cc0
          /* Similar code for machines that use a pair of CC0 setter and
@@ -4252,7 +4256,7 @@ cprop (alter_jumps)
           insn = NEXT_INSN (insn))
        if (INSN_P (insn))
          {
-           changed |= cprop_insn (insn, alter_jumps);
+           changed |= cprop_insn (BASIC_BLOCK (bb), insn, alter_jumps);
 
            /* Keep track of everything modified by this insn.  */
            /* ??? Need to be careful w.r.t. mods done to INSN.  Don't
index ef30528..b4b9b9d 100644 (file)
@@ -2725,22 +2725,6 @@ split_all_insns (upd_life)
   int changed;
   int i;
 
-  if (!upd_life)
-    {
-      rtx next, insn;
-
-      for (insn = get_insns (); insn ; insn = next)
-       {
-         rtx last;
-
-         /* Can't use `next_real_insn' because that might go across
-            CODE_LABELS and short-out basic blocks.  */
-         next = NEXT_INSN (insn);
-         last = split_insn (insn);
-       }
-      return;
-    }
-
   blocks = sbitmap_alloc (n_basic_blocks);
   sbitmap_zero (blocks);
   changed = 0;
@@ -2775,12 +2759,21 @@ split_all_insns (upd_life)
        abort ();
     }
 
-  if (changed && upd_life)
+  if (changed)
     {
       compute_bb_for_insn (get_max_uid ());
+      for (i = 0; i < n_basic_blocks; i++)
+       find_sub_basic_blocks (BASIC_BLOCK (i));
+    }
+
+  if (changed && upd_life)
+    {
       count_or_remove_death_notes (blocks, 1);
       update_life_info (blocks, UPDATE_LIFE_LOCAL, PROP_DEATH_NOTES);
     }
+#ifdef ENABLE_CHECKING
+  verify_flow_info ();
+#endif
 
   sbitmap_free (blocks);
 }
index e9227b1..278e9d0 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1387,6 +1387,7 @@ extern int reg_set_p                      PARAMS ((rtx, rtx));
 extern rtx single_set_2                        PARAMS ((rtx, rtx));
 extern int multiple_sets               PARAMS ((rtx));
 extern int set_noop_p                  PARAMS ((rtx));
+extern int noop_move_p                 PARAMS ((rtx));
 extern rtx find_last_value             PARAMS ((rtx, rtx *, rtx, int));
 extern int refers_to_regno_p           PARAMS ((unsigned int, unsigned int,
                                                 rtx, rtx *));
index 2f9696c..c9152ab 100644 (file)
@@ -1020,6 +1020,45 @@ set_noop_p (set)
   return (GET_CODE (src) == REG && GET_CODE (dst) == REG
          && REGNO (src) == REGNO (dst));
 }
+\f
+/* Return nonzero if an insn consists only of SETs, each of which only sets a
+   value to itself.  */
+
+int
+noop_move_p (insn)
+     rtx insn;
+{
+  rtx pat = PATTERN (insn);
+
+  /* Insns carrying these notes are useful later on.  */
+  if (find_reg_note (insn, REG_EQUAL, NULL_RTX))
+    return 0;
+
+  if (GET_CODE (pat) == SET && set_noop_p (pat))
+    return 1;
+
+  if (GET_CODE (pat) == PARALLEL)
+    {
+      int i;
+      /* If nothing but SETs of registers to themselves,
+        this insn can also be deleted.  */
+      for (i = 0; i < XVECLEN (pat, 0); i++)
+       {
+         rtx tem = XVECEXP (pat, 0, i);
+
+         if (GET_CODE (tem) == USE
+             || GET_CODE (tem) == CLOBBER)
+           continue;
+
+         if (GET_CODE (tem) != SET || ! set_noop_p (tem))
+           return 0;
+       }
+
+      return 1;
+    }
+  return 0;
+}
+\f
 
 /* Return the last thing that X was assigned from before *PINSN.  If VALID_TO
    is not NULL_RTX then verify that the object is not modified up to VALID_TO.
index 13a5d05..613ef0d 100644 (file)
@@ -3265,7 +3265,7 @@ rest_of_compilation (decl)
          timevar_pop (TV_JUMP);
 
          timevar_push (TV_FLOW);
-         find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+         purge_all_dead_edges ();
          cleanup_cfg (CLEANUP_EXPENSIVE);
 
          /* Blimey.  We've got to have the CFG up to date for the call to
@@ -3441,16 +3441,6 @@ rest_of_compilation (decl)
       timevar_pop (TV_RELOAD_CSE_REGS);
     }
 
-  /* If optimizing, then go ahead and split insns now since we are about
-     to recompute flow information anyway.  */
-  if (optimize > 0)
-    {
-      int old_labelnum = max_label_num ();
-
-      split_all_insns (0);
-      rebuild_label_notes_after_reload |= old_labelnum != max_label_num ();
-    }
-
   /* Register allocation and reloading may have turned an indirect jump into
      a direct jump.  If so, we must rebuild the JUMP_LABEL fields of
      jumping instructions.  */
@@ -3470,6 +3460,11 @@ rest_of_compilation (decl)
   open_dump_file (DFI_flow2, decl);
 
   find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+
+  /* If optimizing, then go ahead and split insns now.  */
+  if (optimize > 0)
+    split_all_insns (0);
+
   cleanup_cfg (0);
 
   /* On some machines, the prologue and epilogue code, or parts thereof,