]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
flow.c (try_simplify_condjump): Avoid duplicated edges.
authorJan Hubicka <jh@suse.cz>
Tue, 24 Jul 2001 23:42:40 +0000 (01:42 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Tue, 24 Jul 2001 23:42:40 +0000 (23:42 +0000)
* flow.c (try_simplify_condjump): Avoid duplicated edges.
(verify_flow_info): Check for duplicated edges; clarify
error reporting.

* flow.c (block_label): Update basic_block_for_insn.
(commit_edge_insertions): Call compute_bb_for_insn.

* flow.c (purge_dead_edges): Handle conditional jumps and conditional
returns too.

* flow.c (redirect_edge_and_branch,
try_optimize_cfg): Use redirect_edge_succ_nodup
(redirect_edge_succ_nodup): New.
* basic_block.h (redirect_edge_succ_nodup): Declare.

* toplev.c (rest_of_compilation): Rebuild CFG before cfg_cleanup
after gcse.

From-SVN: r44320

gcc/ChangeLog
gcc/basic-block.h
gcc/flow.c
gcc/toplev.c

index 30db51bd0d3c8af536283127e3a1cb4f7e051404..010e14cddefdd23f5c0339af4d47fe8318ea6f8c 100644 (file)
@@ -1,3 +1,23 @@
+Wed Jul 25 01:41:27 CEST 2001  Jan Hubicka  <jh@suse.cz>
+
+       * flow.c (try_simplify_condjump): Avoid duplicated edges.
+       (verify_flow_info): Check for duplicated edges; clarify
+       error reporting.
+
+       * flow.c (block_label): Update basic_block_for_insn.
+       (commit_edge_insertions): Call compute_bb_for_insn.
+
+       * flow.c (purge_dead_edges): Handle conditional jumps and conditional
+       returns too.
+
+       * flow.c (redirect_edge_and_branch,
+       try_optimize_cfg): Use redirect_edge_succ_nodup
+       (redirect_edge_succ_nodup): New.
+       * basic_block.h (redirect_edge_succ_nodup): Declare.
+
+       * toplev.c (rest_of_compilation): Rebuild CFG before cfg_cleanup
+       after gcse.
+
 Wed Jul 25 00:32:49 CEST 2001  Jan Hubicka  <jh@suse.cz>
 
        * flow.c (try_forward_edges): Accept fallthru edge; Update comment.
index b6e8c11a16be90ed01a5a13ca0840f3e2020900d..c069ad57edd5857f6586e098775dcb4d9428253b 100644 (file)
@@ -296,6 +296,7 @@ extern void make_edge                       PARAMS ((sbitmap *, basic_block,
                                                 basic_block, int));
 extern void remove_edge                        PARAMS ((edge));
 extern void redirect_edge_succ         PARAMS ((edge, basic_block));
+extern void redirect_edge_succ_nodup   PARAMS ((edge, basic_block));
 extern void redirect_edge_pred         PARAMS ((edge, basic_block));
 extern void create_basic_block         PARAMS ((int, rtx, rtx, rtx));
 extern int flow_delete_block           PARAMS ((basic_block));
index ac1ea5ccee3125600e16ada452b92b36fa92d23e..733eae047bc472adaa867c4d52f9884bd6ac20f3 100644 (file)
@@ -1592,7 +1592,11 @@ block_label (block)
   if (block == EXIT_BLOCK_PTR)
     return NULL_RTX;
   if (GET_CODE (block->head) != CODE_LABEL)
-    block->head = emit_label_before (gen_label_rtx (), block->head);
+    {
+      block->head = emit_label_before (gen_label_rtx (), block->head);
+      if (basic_block_for_insn)
+       set_block_for_insn (block->head, block);
+    }
   return block->head;
 }
 
@@ -1834,22 +1838,7 @@ redirect_edge_and_branch (e, target)
     fprintf (rtl_dump_file, "Edge %i->%i redirected to %i\n",
             e->src->index, e->dest->index, target->index);
   if (e->dest != target)
-    {
-      edge s;
-      /* Check whether the edge is already present.  */
-      for (s = src->succ; s; s=s->succ_next)
-       if (s->dest == target)
-         break;
-      if (s)
-       {
-         s->flags |= e->flags;
-         s->probability += e->probability;
-         s->count += e->count;
-         remove_edge (e);
-       }
-      else
-       redirect_edge_succ (e, target);
-    }
+    redirect_edge_succ_nodup (e, target);
   return true;
 }
 
@@ -2293,6 +2282,7 @@ commit_edge_insertions ()
 {
   int i;
   basic_block bb;
+  compute_bb_for_insn (get_max_uid ());
 
 #ifdef ENABLE_CHECKING
   verify_flow_info ();
@@ -3076,8 +3066,8 @@ try_simplify_condjump (cbranch_block)
   /* Success.  Update the CFG to match.  Note that after this point
      the edge variable names appear backwards; the redirection is done
      this way to preserve edge profile data.  */
-  redirect_edge_succ (cbranch_jump_edge, cbranch_dest_block);
-  redirect_edge_succ (cbranch_fallthru_edge, jump_dest_block);
+  redirect_edge_succ_nodup (cbranch_jump_edge, cbranch_dest_block);
+  redirect_edge_succ_nodup (cbranch_fallthru_edge, jump_dest_block);
   cbranch_jump_edge->flags |= EDGE_FALLTHRU;
   cbranch_fallthru_edge->flags &= ~EDGE_FALLTHRU;
   
@@ -3820,7 +3810,7 @@ try_optimize_cfg (mode)
                fprintf (rtl_dump_file, "Deleting fallthru block %i.\n",
                         b->index);
              c = BASIC_BLOCK (b->index ? b->index - 1 : 1);
-             redirect_edge_succ (b->pred, b->succ->dest);
+             redirect_edge_succ_nodup (b->pred, b->succ->dest);
              flow_delete_block (b);
              changed = true;
              b = c;
@@ -7979,11 +7969,13 @@ verify_flow_info ()
   const int max_uid = get_max_uid ();
   const rtx rtx_first = get_insns ();
   rtx last_head = get_last_insn ();
-  basic_block *bb_info;
+  basic_block *bb_info, *last_visited;
   rtx x;
   int i, last_bb_num_seen, num_bb_notes, err = 0;
 
   bb_info = (basic_block *) xcalloc (max_uid, sizeof (basic_block));
+  last_visited = (basic_block *) xcalloc (n_basic_blocks + 2,
+                                         sizeof (basic_block));
 
   for (i = n_basic_blocks - 1; i >= 0; i--)
     {
@@ -8040,6 +8032,14 @@ verify_flow_info ()
       e = bb->succ;
       while (e)
        {
+         if (last_visited [e->dest->index + 2] == bb)
+           {
+             error ("verify_flow_info: Duplicate edge %i->%i",
+                    e->src->index, e->dest->index);
+             err = 1;
+           }
+         last_visited [e->dest->index + 2] = bb;
+
          if ((e->flags & EDGE_FALLTHRU)
              && e->src != ENTRY_BLOCK_PTR
              && e->dest != EXIT_BLOCK_PTR
@@ -8166,8 +8166,7 @@ verify_flow_info ()
          basic_block bb = NOTE_BASIC_BLOCK (x);
          num_bb_notes++;
          if (bb->index != last_bb_num_seen + 1)
-           /* Basic blocks not numbered consecutively.  */
-           abort ();
+           internal_error ("Basic blocks not numbered consecutively.");
               
          last_bb_num_seen = bb->index;
        }
@@ -8213,10 +8212,11 @@ verify_flow_info ()
        num_bb_notes, n_basic_blocks);
 
   if (err)
-    abort ();
+    internal_error ("verify_flow_info failed.");
 
   /* Clean up.  */
   free (bb_info);
+  free (last_visited);
 }
 \f
 /* Functions to access an edge list with a vector representation.
@@ -8629,6 +8629,29 @@ redirect_edge_succ (e, new_succ)
   e->dest = new_succ;
 }
 
+/* Like previous but avoid possible dupplicate edge.  */
+
+void
+redirect_edge_succ_nodup (e, new_succ)
+     edge e;
+     basic_block new_succ;
+{
+  edge s;
+  /* Check whether the edge is already present.  */
+  for (s = e->src->succ; s; s = s->succ_next)
+    if (s->dest == new_succ && s != e)
+      break;
+  if (s)
+    {
+      s->flags |= e->flags;
+      s->probability += e->probability;
+      s->count += e->count;
+      remove_edge (e);
+    }
+  else
+    redirect_edge_succ (e, new_succ);
+}
+
 /* Redirect an edge's predecessor from one block to another.  */
 
 void
@@ -9794,21 +9817,56 @@ purge_dead_edges (bb)
     return;
   if (GET_CODE (insn) == JUMP_INSN)
     {
+      int removed = 0;
+      rtx note;
+      edge b,f;
+      /* We do care only about conditional jumps and simplejumps.  */
+      if (!any_condjump_p (insn)
+         && !returnjump_p (insn)
+         && !simplejump_p (insn))
+       return;
       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);
+
+         /* Check purposes we can have edge.  */
+         if ((e->flags & EDGE_FALLTHRU)
+             && any_condjump_p (insn))
+           continue;
+         if (e->dest != EXIT_BLOCK_PTR
+             && e->dest->head == JUMP_LABEL (insn))
+           continue;
+         if (e->dest == EXIT_BLOCK_PTR
+             && returnjump_p (insn))
+           continue;
+         removed = 1;
+         remove_edge (e);
        }
-      if (bb->succ && bb->succ->succ_next)
-       abort ();
-      if (!bb->succ)
+      if (!bb->succ || !removed)
        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);
+      if (!optimize)
+       return;
+
+      /* Redistribute probabilities.  */
+      if (!bb->succ->succ_next)
+       {
+         bb->succ->probability = REG_BR_PROB_BASE;
+         bb->succ->count = bb->count;
+        }
+      else
+       {
+         note = find_reg_note (insn, REG_BR_PROB, NULL);
+         if (!note)
+           return;
+         b = BRANCH_EDGE (bb);
+         f = FALLTHRU_EDGE (bb);
+         b->probability = INTVAL (XEXP (note, 0));
+         f->probability = REG_BR_PROB_BASE - b->probability;
+         b->count = bb->count * b->probability / REG_BR_PROB_BASE;
+         f->count = bb->count * f->probability / REG_BR_PROB_BASE;
+       }
       return;
     }
   /* If we don't see a jump insn, we don't know exactly why the block would
index a7bd5e36daf33fe0eea8a04a90f4535264461a50..02bb24ab6a7758b67c80041b92e449e1e9c751a2 100644 (file)
@@ -3060,6 +3060,8 @@ rest_of_compilation (decl)
          tem = tem2 = 0;
          timevar_push (TV_JUMP);
          rebuild_jump_labels (insns);
+         delete_trivially_dead_insns (insns, max_reg_num (), 0);
+         find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
          cleanup_cfg (CLEANUP_EXPENSIVE);
          timevar_pop (TV_JUMP);