OSDN Git Service

* config/s390/s390.c: Follow spelling convention.
[pf3gnuchains/gcc-fork.git] / gcc / cfganal.c
index 15031f6..35ce07d 100644 (file)
@@ -28,7 +28,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "insn-config.h"
 #include "recog.h"
 #include "toplev.h"
-#include "obstack.h"
 #include "tm_p.h"
 
 /* Store the data structures necessary for depth-first search.  */
@@ -258,29 +257,16 @@ flow_call_edges_add (blocks)
 {
   int i;
   int blocks_split = 0;
-  int bb_num = 0;
-  basic_block *bbs, bb;
+  int last_bb = last_basic_block;
   bool check_last_block = false;
 
-  /* Map bb indices into basic block pointers since split_block
-     will renumber the basic blocks.  */
-
-  bbs = xmalloc (n_basic_blocks * sizeof (*bbs));
+  if (n_basic_blocks == 0)
+    return 0;
 
   if (! blocks)
-    {
-      FOR_EACH_BB (bb)
-       bbs[bb_num++] = bb;
-
-      check_last_block = true;
-    }
+    check_last_block = true;
   else
-    EXECUTE_IF_SET_IN_SBITMAP (blocks, 0, i,
-                              {
-                                bbs[bb_num++] = BASIC_BLOCK (i);
-                                if (i == n_basic_blocks - 1)
-                                  check_last_block = true;
-                              });
+    check_last_block = TEST_BIT (blocks, EXIT_BLOCK_PTR->prev_bb->index);
 
   /* In the last basic block, before epilogue generation, there will be
      a fallthru edge to EXIT.  Special care is required if the last insn
@@ -321,12 +307,18 @@ flow_call_edges_add (blocks)
      calls since there is no way that we can determine if they will
      return or not...  */
 
-  for (i = 0; i < bb_num; i++)
+  for (i = 0; i < last_bb; i++)
     {
-      basic_block bb = bbs[i];
+      basic_block bb = BASIC_BLOCK (i);
       rtx insn;
       rtx prev_insn;
 
+      if (!bb)
+       continue;
+
+      if (blocks && !TEST_BIT (blocks, i))
+       continue;
+
       for (insn = bb->end; ; insn = prev_insn)
        {
          prev_insn = PREV_INSN (insn);
@@ -374,7 +366,6 @@ flow_call_edges_add (blocks)
   if (blocks_split)
     verify_flow_info ();
 
-  free (bbs);
   return blocks_split;
 }
 
@@ -927,7 +918,7 @@ flow_preorder_transversal_compute (pot_order)
       for (e = bb->succ; e; e = e->succ_next)
        max_successors++;
 
-      dfst[i].node
+      dfst[bb->index].node
        = (max_successors
           ? (struct dfst_node **) xcalloc (max_successors,
                                            sizeof (struct dfst_node *))
@@ -1111,3 +1102,54 @@ flow_dfs_compute_reverse_finish (data)
   free (data->stack);
   sbitmap_free (data->visited_blocks);
 }
+
+/* Performs dfs search from BB over vertices satisfying PREDICATE;
+   if REVERSE, go against direction of edges.  Returns number of blocks
+   found and their list in RSLT.  RSLT can contain at most RSLT_MAX items.  */
+int
+dfs_enumerate_from (bb, reverse, predicate, rslt, rslt_max, data)
+     basic_block bb;
+     int reverse;
+     bool (*predicate) (basic_block, void *);
+     basic_block *rslt;
+     int rslt_max;
+     void *data;
+{
+  basic_block *st, lbb;
+  int sp = 0, tv = 0;
+
+  st = xcalloc (rslt_max, sizeof (basic_block));
+  rslt[tv++] = st[sp++] = bb;
+  bb->flags |= BB_VISITED;
+  while (sp)
+    {
+      edge e;
+      lbb = st[--sp];
+      if (reverse)
+        {
+          for (e = lbb->pred; e; e = e->pred_next)
+           if (!(e->src->flags & BB_VISITED) && predicate (e->src, data))
+             {
+               if (tv == rslt_max)
+                 abort ();
+               rslt[tv++] = st[sp++] = e->src;
+               e->src->flags |= BB_VISITED;
+             }
+        }
+      else
+        {
+          for (e = lbb->succ; e; e = e->succ_next)
+           if (!(e->dest->flags & BB_VISITED) && predicate (e->dest, data))
+             {
+               if (tv == rslt_max)
+                 abort ();
+               rslt[tv++] = st[sp++] = e->dest;
+               e->dest->flags |= BB_VISITED;
+             }
+       }
+    }
+  free (st);
+  for (sp = 0; sp < tv; sp++)
+    rslt[sp]->flags &= ~BB_VISITED;
+  return tv;
+}