basic-block.h (cached_make_edge, [...]): New.
authorJan Hubicka <jh@suse.cz>
Tue, 11 Sep 2001 09:39:11 +0000 (11:39 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Tue, 11 Sep 2001 09:39:11 +0000 (09:39 +0000)
* basic-block.h (cached_make_edge, make_single_succ): New.
(make_edge): Remove first parameter.
* bb-reroder.c (fixup_reorder_chain): Use make_single_succ_edge.
* cfg.c (cached_make_edge): Rename from make_edge; return newly
created edge; use obstack allocation.
(make_edge, make_single_succ_edge): New.
(first_removed_edge): New static variable.
(init_flow): Initialize first_removed_edge and n_edges.
(clear_edges): Use remove_edge.
(flow_delete_block): Likewise.
(remove_edge): Add removed edges to the removed edges list.
(split_block, redirect_edge_and_branch_force, split_edge):
Use make_edge.
* cfganal.c (flow_call_edges_add): Updaet make_edge call.
(add_noreturn_fake_exit_edges): Likewise.
(connect_infinite_loops_to_exit): Liekwise.
* cfgbuild.c (make_label_edge, make_edges, find_sub_basic_blocks):
Use cached_make_edge.
* cfgcleanup.c (try_crossjump_to_edge): Use make_single_succ_edge.
* profile.c (branch_prob): Update make_edge call.
* ssa-dce.c (ssa_eliminate_dead_code): Likewise.

From-SVN: r45540

gcc/ChangeLog
gcc/basic-block.h
gcc/bb-reorder.c
gcc/cfg.c
gcc/cfganal.c
gcc/cfgbuild.c
gcc/cfgcleanup.c
gcc/profile.c
gcc/ssa-dce.c

index 7b9891e3f06300ea94e3b677baefea8dfd8f036e..266154bcdc7e2b021fe6c58a5a07d416dfebbbbb 100644 (file)
@@ -1,3 +1,27 @@
+Tue Sep 11 11:37:52 CEST 2001  Jan Hubicka  <jh@suse.cz>
+
+       * basic-block.h (cached_make_edge, make_single_succ): New.
+       (make_edge): Remove first parameter.
+       * bb-reroder.c (fixup_reorder_chain): Use make_single_succ_edge.
+       * cfg.c (cached_make_edge): Rename from make_edge; return newly
+       created edge; use obstack allocation.
+       (make_edge, make_single_succ_edge): New.
+       (first_removed_edge): New static variable.
+       (init_flow): Initialize first_removed_edge and n_edges.
+       (clear_edges): Use remove_edge.
+       (flow_delete_block): Likewise.
+       (remove_edge): Add removed edges to the removed edges list.
+       (split_block, redirect_edge_and_branch_force, split_edge):
+       Use make_edge.
+       * cfganal.c (flow_call_edges_add): Updaet make_edge call.
+       (add_noreturn_fake_exit_edges): Likewise.
+       (connect_infinite_loops_to_exit): Liekwise.
+       * cfgbuild.c (make_label_edge, make_edges, find_sub_basic_blocks):
+       Use cached_make_edge.
+       * cfgcleanup.c (try_crossjump_to_edge): Use make_single_succ_edge.
+       * profile.c (branch_prob): Update make_edge call.
+       * ssa-dce.c (ssa_eliminate_dead_code): Likewise.
+
 2001-09-11  Richard Henderson  <rth@redhat.com>
 
        * config/alpha/alpha.c: Tidy formatting.
index 13241e8ffe656f794abeb1b3471bcea2a84f3315..1a49c5f1a7d706b2dd824fe40650d5c5b773eb96 100644 (file)
@@ -305,7 +305,11 @@ extern void connect_infinite_loops_to_exit PARAMS ((void));
 extern int flow_call_edges_add         PARAMS ((sbitmap));
 extern rtx flow_delete_insn            PARAMS ((rtx));
 extern void flow_delete_insn_chain     PARAMS ((rtx, rtx));
-extern void make_edge                  PARAMS ((sbitmap *, basic_block,
+extern edge cached_make_edge           PARAMS ((sbitmap *, basic_block,
+                                                basic_block, int));
+extern edge make_edge                  PARAMS ((basic_block,
+                                                basic_block, int));
+extern edge make_single_succ_edge      PARAMS ((basic_block,
                                                 basic_block, int));
 extern void remove_edge                        PARAMS ((edge));
 extern void redirect_edge_succ         PARAMS ((edge, basic_block));
index 3102132eb3e7a219040ea9fc4b8bc91ff36bfaaf..c048ac872ab01e803f0d1cc396ebb981d416d497 100644 (file)
@@ -737,10 +737,8 @@ fixup_reorder_chain ()
       RBI (bb)->next = nb;
 
       /* Link to new block.  */
-      make_edge (NULL, nb, e_fall->dest, 0);
+      make_single_succ_edge (nb, e_fall->dest, 0);
       redirect_edge_succ (e_fall, nb);
-      nb->succ->count = e_fall->count;
-      nb->succ->probability = REG_BR_PROB_BASE;
 
       /* Don't process this new block.  */
       bb = nb;
index 3f11a55982fb05b5d67d616a06c102d75d9be6ad..ff7e1bf7a14b8e4d64b36b2615117991195ede57 100644 (file)
--- a/gcc/cfg.c
+++ b/gcc/cfg.c
@@ -34,7 +34,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
         compute_bb_for_insn, update_bb_for_insn, set_block_for_insn,
         set_block_for_new_insns
      - Edge manipulation
-        make_edge, remove_edge
+        make_edge, make_single_succ_edge, cached_make_edge, remove_edge
         - Low level edge redirection (without updating instruction chain)
             redirect_edge_succ, redirect_edge_succ_nodup, redirect_edge_pred
         - High level edge redirection (with updating and optimizing instruction
@@ -80,6 +80,10 @@ int n_basic_blocks;
 
 int n_edges;
 
+/* First edge in the deleted edges chain.  */
+
+edge first_deleted_edge;
+
 /* The basic block array.  */
 
 varray_type basic_block_info;
@@ -151,6 +155,9 @@ init_flow ()
 {
   static int initialized;
 
+  first_deleted_edge = 0;
+  n_edges = 0;
+
   if (!initialized)
     {
       gcc_obstack_init (&flow_obstack);
@@ -170,32 +177,20 @@ void
 clear_edges ()
 {
   int i;
-  edge n, e;
 
   for (i = 0; i < n_basic_blocks; ++i)
     {
       basic_block bb = BASIC_BLOCK (i);
 
-      for (e = bb->succ; e; e = n)
-       {
-         n = e->succ_next;
-         free (e);
-       }
-
-      bb->succ = 0;
-      bb->pred = 0;
+      while (bb->succ)
+       remove_edge (bb->succ);
     }
 
-  for (e = ENTRY_BLOCK_PTR->succ; e; e = n)
-    {
-      n = e->succ_next;
-      free (e);
-    }
+  while (ENTRY_BLOCK_PTR->succ)
+    remove_edge (ENTRY_BLOCK_PTR->succ);
 
-  ENTRY_BLOCK_PTR->succ = 0;
-  EXIT_BLOCK_PTR->pred = 0;
-
-  n_edges = 0;
+  if (n_edges)
+    abort ();
 }
 \f
 /* Return true if NOTE is not one of the ones that must be kept paired,
@@ -458,26 +453,10 @@ flow_delete_block (b)
   /* Remove the edges into and out of this block.  Note that there may
      indeed be edges in, if we are removing an unreachable loop.  */
   {
-    edge e, next, *q;
-
-    for (e = b->pred; e; e = next)
-      {
-       for (q = &e->src->succ; *q != e; q = &(*q)->succ_next)
-         continue;
-       *q = e->succ_next;
-       next = e->pred_next;
-       n_edges--;
-       free (e);
-      }
-    for (e = b->succ; e; e = next)
-      {
-       for (q = &e->dest->pred; *q != e; q = &(*q)->pred_next)
-         continue;
-       *q = e->pred_next;
-       next = e->succ_next;
-       n_edges--;
-       free (e);
-      }
+    while (b->pred != NULL)
+      remove_edge (b->pred);
+    while (b->succ != NULL)
+      remove_edge (b->succ);
 
     b->pred = NULL;
     b->succ = NULL;
@@ -589,8 +568,10 @@ set_block_for_new_insns (insn, bb)
     }
 }
 \f
-void
-make_edge (edge_cache, src, dst, flags)
+/* Create an edge connecting SRC and DST with FLAGS optionally using
+   edge cache CACHE.  Return the new edge, NULL if already exist. */
+edge
+cached_make_edge (edge_cache, src, dst, flags)
      sbitmap *edge_cache;
      basic_block src, dst;
      int flags;
@@ -614,7 +595,7 @@ make_edge (edge_cache, src, dst, flags)
 
       /* The edge exists; early exit if no work to do.  */
       if (flags == 0)
-       return;
+       return NULL;
 
       /* FALLTHRU */
     case 0:
@@ -622,12 +603,21 @@ make_edge (edge_cache, src, dst, flags)
        if (e->dest == dst)
          {
            e->flags |= flags;
-           return;
+           return NULL;
          }
       break;
     }
 
-  e = (edge) xcalloc (1, sizeof (*e));
+  if (first_deleted_edge)
+    {
+      e = first_deleted_edge;
+      first_deleted_edge = e->succ_next;
+    }
+  else
+    {
+      e = (edge) obstack_alloc (&flow_obstack, sizeof (*e));
+      memset (e, 0, sizeof (*e));
+    }
   n_edges++;
 
   e->succ_next = src->succ;
@@ -641,6 +631,34 @@ make_edge (edge_cache, src, dst, flags)
 
   if (use_edge_cache)
     SET_BIT (edge_cache[src->index], dst->index);
+
+  return e;
+}
+
+/* Create an edge connecting SRC and DEST with flags FLAGS.  Return newly
+   created edge or NULL if already exist.  */
+
+edge
+make_edge (src, dest, flags)
+     basic_block src, dest;
+     int flags;
+{
+  return cached_make_edge (NULL, src, dest, flags);
+}
+
+/* Create an edge connecting SRC to DEST and set probability by knowling
+   that it is the single edge leaving SRC.  */
+
+edge
+make_single_succ_edge (src, dest, flags)
+     basic_block src, dest;
+     int flags;
+{
+  edge e = make_edge (src, dest, flags);
+
+  e->probability = REG_BR_PROB_BASE;
+  e->count = src->count;
+  return e;
 }
 
 /* This function will remove an edge from the flow graph.  */
@@ -676,7 +694,9 @@ remove_edge (e)
     dest->pred = e->pred_next;
 
   n_edges--;
-  free (e);
+  memset (e, 0, sizeof (*e));
+  e->succ_next = first_deleted_edge;
+  first_deleted_edge = e;
 }
 
 /* Redirect an edge's successor from one block to another.  */
@@ -766,8 +786,6 @@ split_block (bb, insn)
 
   /* Create the new structures.  */
   new_bb = (basic_block) obstack_alloc (&flow_obstack, sizeof (*new_bb));
-  new_edge = (edge) xcalloc (1, sizeof (*new_edge));
-  n_edges++;
 
   memset (new_bb, 0, sizeof (*new_bb));
 
@@ -776,22 +794,18 @@ split_block (bb, insn)
   bb->end = insn;
 
   new_bb->succ = bb->succ;
-  bb->succ = new_edge;
-  new_bb->pred = new_edge;
+  bb->succ = NULL;
+  new_bb->pred = NULL;
   new_bb->count = bb->count;
   new_bb->frequency = bb->frequency;
   new_bb->loop_depth = bb->loop_depth;
 
-  new_edge->src = bb;
-  new_edge->dest = new_bb;
-  new_edge->flags = EDGE_FALLTHRU;
-  new_edge->probability = REG_BR_PROB_BASE;
-  new_edge->count = bb->count;
-
   /* Redirect the src of the successor edges of bb to point to new_bb.  */
   for (e = new_bb->succ; e; e = e->succ_next)
     e->src = new_bb;
 
+  new_edge = make_single_succ_edge (bb, new_bb, EDGE_FALLTHRU);
+
   /* Place the new block just after the block being split.  */
   VARRAY_GROW (basic_block_info, ++n_basic_blocks);
 
@@ -1262,22 +1276,16 @@ redirect_edge_and_branch_force (e, target)
 
   /* Create the new structures.  */
   new_bb = (basic_block) obstack_alloc (&flow_obstack, sizeof (*new_bb));
-  new_edge = (edge) xcalloc (1, sizeof (*new_edge));
-  n_edges++;
 
   memset (new_bb, 0, sizeof (*new_bb));
 
   new_bb->end = new_bb->head = last_loop_beg_note (e->src->end);
   new_bb->succ = NULL;
-  new_bb->pred = new_edge;
+  new_bb->pred = NULL;
   new_bb->count = e->count;
   new_bb->frequency = EDGE_FREQUENCY (e);
   new_bb->loop_depth = e->dest->loop_depth;
 
-  new_edge->flags = EDGE_FALLTHRU;
-  new_edge->probability = e->probability;
-  new_edge->count = e->count;
-
   if (target->global_live_at_start)
     {
       new_bb->global_live_at_start = OBSTACK_ALLOC_REG_SET (&flow_obstack);
@@ -1288,11 +1296,9 @@ redirect_edge_and_branch_force (e, target)
     }
 
   /* Wire edge in.  */
-  new_edge->src = e->src;
-  new_edge->dest = new_bb;
-  new_edge->succ_next = e->src->succ;
-  e->src->succ = new_edge;
-  new_edge->pred_next = NULL;
+  new_edge = make_edge (e->src, new_bb, EDGE_FALLTHRU);
+  new_edge->probability = e->probability;
+  new_edge->count = e->count;
 
   /* Redirect old edge.  */
   redirect_edge_succ (e, target);
@@ -1487,8 +1493,6 @@ split_edge (edge_in)
 
   /* Create the new structures.  */
   bb = (basic_block) obstack_alloc (&flow_obstack, sizeof (*bb));
-  edge_out = (edge) xcalloc (1, sizeof (*edge_out));
-  n_edges++;
 
   memset (bb, 0, sizeof (*bb));
 
@@ -1502,21 +1506,13 @@ split_edge (edge_in)
     }
 
   /* Wire them up.  */
-  bb->succ = edge_out;
+  bb->succ = NULL;
   bb->count = edge_in->count;
   bb->frequency = EDGE_FREQUENCY (edge_in);
 
   edge_in->flags &= ~EDGE_CRITICAL;
 
-  edge_out->pred_next = old_succ->pred;
-  edge_out->succ_next = NULL;
-  edge_out->src = bb;
-  edge_out->dest = old_succ;
-  edge_out->flags = EDGE_FALLTHRU;
-  edge_out->probability = REG_BR_PROB_BASE;
-  edge_out->count = edge_in->count;
-
-  old_succ->pred = edge_out;
+  edge_out = make_single_succ_edge (bb, old_succ, EDGE_FALLTHRU);
 
   /* Tricky case -- if there existed a fallthru into the successor
      (and we're not it) we must add a new unconditional jump around
index 96a20b8f3c3e7adee2fb2dd477c3806b69ed622b..5711794801fd6fb51234f239e41266c40b494b03 100644 (file)
@@ -348,7 +348,7 @@ flow_call_edges_add (blocks)
              if (e)
                blocks_split++;
 
-             make_edge (NULL, bb, EXIT_BLOCK_PTR, EDGE_FAKE);
+             make_edge (bb, EXIT_BLOCK_PTR, EDGE_FAKE);
            }
          if (insn == bb->head)
            break;
@@ -762,7 +762,7 @@ add_noreturn_fake_exit_edges ()
 
   for (x = 0; x < n_basic_blocks; x++)
     if (BASIC_BLOCK (x)->succ == NULL)
-      make_edge (NULL, BASIC_BLOCK (x), EXIT_BLOCK_PTR, EDGE_FAKE);
+      make_single_succ_edge (BASIC_BLOCK (x), EXIT_BLOCK_PTR, EDGE_FAKE);
 }
 
 /* This function adds a fake edge between any infinite loops to the
@@ -794,7 +794,7 @@ connect_infinite_loops_to_exit ()
       unvisited_block = flow_dfs_compute_reverse_execute (&dfs_ds);
       if (!unvisited_block)
        break;
-      make_edge (NULL, unvisited_block, EXIT_BLOCK_PTR, EDGE_FAKE);
+      make_edge (unvisited_block, EXIT_BLOCK_PTR, EDGE_FAKE);
       flow_dfs_compute_reverse_add_bb (&dfs_ds, unvisited_block);
     }
 
index 2f62b067ff57107af1120070632d7efbdc59e6df..ea1c7327b343d50b2a77a317d72c74e18d931eef 100644 (file)
@@ -186,7 +186,7 @@ make_label_edge (edge_cache, src, label, flags)
   if (INSN_UID (label) == 0)
     return;
 
-  make_edge (edge_cache, src, BLOCK_FOR_INSN (label), flags);
+  cached_make_edge (edge_cache, src, BLOCK_FOR_INSN (label), flags);
 }
 
 /* Create the edges generated by INSN in REGION.  */
@@ -246,7 +246,7 @@ make_edges (label_value_list, min, max, update_p)
     }
 
   /* 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);
+  cached_make_edge (edge_cache, ENTRY_BLOCK_PTR, BASIC_BLOCK (0), EDGE_FALLTHRU);
 
   for (i = min; i <= max; ++i)
     {
@@ -257,7 +257,7 @@ make_edges (label_value_list, min, max, update_p)
 
       if (GET_CODE (bb->head) == CODE_LABEL
          && LABEL_ALTERNATE_NAME (bb->head))
-       make_edge (NULL, ENTRY_BLOCK_PTR, bb, 0);
+       cached_make_edge (NULL, ENTRY_BLOCK_PTR, bb, 0);
 
       /* Examine the last instruction of the block, and discover the
         ways we can leave the block.  */
@@ -330,7 +330,7 @@ make_edges (label_value_list, min, max, update_p)
 
          /* Returns create an exit out.  */
          else if (returnjump_p (insn))
-           make_edge (edge_cache, bb, EXIT_BLOCK_PTR, 0);
+           cached_make_edge (edge_cache, bb, EXIT_BLOCK_PTR, 0);
 
          /* Otherwise, we have a plain conditional or unconditional jump.  */
          else
@@ -347,7 +347,7 @@ make_edges (label_value_list, min, max, update_p)
         wouldn't have created the sibling call in the first place.  */
 
       if (code == CALL_INSN && SIBLING_CALL_P (insn))
-       make_edge (edge_cache, bb, EXIT_BLOCK_PTR,
+       cached_make_edge (edge_cache, bb, EXIT_BLOCK_PTR,
                   EDGE_ABNORMAL | EDGE_ABNORMAL_CALL);
 
       /* If this is a CALL_INSN, then mark it as reaching the active EH
@@ -383,14 +383,14 @@ make_edges (label_value_list, min, max, update_p)
       /* Find out if we can drop through to the next block.  */
       insn = next_nonnote_insn (insn);
       if (!insn || (i + 1 == n_basic_blocks && force_fallthru))
-       make_edge (edge_cache, bb, EXIT_BLOCK_PTR, EDGE_FALLTHRU);
+       cached_make_edge (edge_cache, bb, EXIT_BLOCK_PTR, EDGE_FALLTHRU);
       else if (i + 1 < n_basic_blocks)
        {
          rtx tmp = BLOCK_HEAD (i + 1);
          if (GET_CODE (tmp) == NOTE)
            tmp = next_nonnote_insn (tmp);
          if (force_fallthru || insn == tmp)
-           make_edge (edge_cache, bb, BASIC_BLOCK (i + 1), EDGE_FALLTHRU);
+           cached_make_edge (edge_cache, bb, BASIC_BLOCK (i + 1), EDGE_FALLTHRU);
        }
     }
 
@@ -701,7 +701,7 @@ find_sub_basic_blocks (bb)
          remove_edge (falltru);
          jump_insn = 0;
          if (LABEL_ALTERNATE_NAME (insn))
-           make_edge (NULL, ENTRY_BLOCK_PTR, bb, 0);
+           make_edge (ENTRY_BLOCK_PTR, bb, 0);
          break;
        case INSN:
        case JUMP_INSN:
index 00eb80adc7c115264b02ab164327604b50a87953..4413c027f17f5b2af94f7682006511420cd7ac1c 100644 (file)
@@ -941,9 +941,7 @@ try_crossjump_to_edge (mode, e1, e2)
   /* Update CFG.  */
   while (src1->succ)
     remove_edge (src1->succ);
-  make_edge (NULL, src1, redirect_to, 0);
-  src1->succ->probability = REG_BR_PROB_BASE;
-  src1->succ->count = src1->count;
+  make_single_succ_edge (src1, redirect_to, 0);
 
   return true;
 }
index d011021ce1576bc0b833f0426640ab6f647d0a87..81737f98fe0cdc6a78c33c71048b0adc28e7b34c 100644 (file)
@@ -563,7 +563,7 @@ branch_prob ()
                  || insn != NEXT_INSN (bb->head))
                {
                  e = split_block (bb, PREV_INSN (insn));
-                 make_edge (NULL, ENTRY_BLOCK_PTR, e->dest, EDGE_FAKE);
+                 make_edge (ENTRY_BLOCK_PTR, e->dest, EDGE_FAKE);
                  break;
                }
              else
@@ -572,7 +572,7 @@ branch_prob ()
                     be the very first instruction of function.  */
                  if (!i)
                    abort ();
-                 make_edge (NULL, ENTRY_BLOCK_PTR, bb, EDGE_FAKE);
+                 make_edge (ENTRY_BLOCK_PTR, bb, EDGE_FAKE);
                }
            }
        }
@@ -599,14 +599,14 @@ branch_prob ()
          if (rtl_dump_file)
            fprintf (rtl_dump_file, "Adding fake exit edge to bb %i\n",
                     bb->index);
-          make_edge (NULL, bb, EXIT_BLOCK_PTR, EDGE_FAKE);
+          make_edge (bb, EXIT_BLOCK_PTR, EDGE_FAKE);
        }
       if (need_entry_edge && !have_entry_edge)
        {
          if (rtl_dump_file)
            fprintf (rtl_dump_file, "Adding fake entry edge to bb %i\n",
                     bb->index);
-          make_edge (NULL, ENTRY_BLOCK_PTR, bb, EDGE_FAKE);
+          make_edge (ENTRY_BLOCK_PTR, bb, EDGE_FAKE);
        }
     }
 
index de763219aa71becae71eb47710ab5a36b48798ae..797a01ca68a88032e29e377e9068a85bf037853b 100644 (file)
@@ -707,7 +707,7 @@ ssa_eliminate_dead_code ()
 
        /* Create an edge from this block to the post dominator.  
           What about the PHI nodes at the target?  */
-       make_edge (NULL, bb, pdom_bb, 0);
+       make_edge (bb, pdom_bb, 0);
 
        /* Third, transform this insn into an unconditional
           jump to the label for the immediate postdominator.  */