]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
basic-block.h (BB_VISITED): Removed.
authorZdenek Dvorak <dvorakz@suse.cz>
Mon, 14 Mar 2005 15:19:56 +0000 (16:19 +0100)
committerZdenek Dvorak <rakdver@gcc.gnu.org>
Mon, 14 Mar 2005 15:19:56 +0000 (15:19 +0000)
* basic-block.h (BB_VISITED): Removed.
* cfganal.c (dfs_enumerate_from): Do not use BB_VISITED flag.

From-SVN: r96434

gcc/ChangeLog
gcc/basic-block.h
gcc/cfganal.c

index 6fb6f6d80e94bf9a06ac86bc68453e50bd23f2a6..abce9f293cdb81be1c6e7ff5f77b863be8186c1c 100644 (file)
@@ -1,3 +1,8 @@
+2005-03-14  Zdenek Dvorak  <dvorakz@suse.cz>
+
+       * basic-block.h (BB_VISITED): Removed.
+       * cfganal.c (dfs_enumerate_from): Do not use BB_VISITED flag.
+
 2005-03-14  Falk Hueffner  <falk@debian.org>
 
        PR bootstrap/20424
index 0821dc5327e920e95178c74ef1acadaf2063126b..bc5f448319c71c526135fca20f427644d0927645 100644 (file)
@@ -287,43 +287,41 @@ typedef struct reorder_block_def
 
 /* Masks for basic_block.flags.
 
-   BB_VISITED should not be used by passes, it is used internally by
-   dfs_enumerate_from.
-
    BB_HOT_PARTITION and BB_COLD_PARTITION should be preserved throughout
    the compilation, so they are never cleared.
 
    All other flags may be cleared by clear_bb_flags().  It is generally
    a bad idea to rely on any flags being up-to-date.  */
 
-/* Set if insns in BB have are modified.  Used for updating liveness info.  */
-#define BB_DIRTY               1
+enum
+{
 
-/* Only set on blocks that have just been created by create_bb.  */
-#define BB_NEW                 2
+  /* Set if insns in BB have are modified.  Used for updating liveness info.  */
+  BB_DIRTY = 1,
 
-/* Set by find_unreachable_blocks.  Do not rely on this being set in any
-   pass.  */
-#define BB_REACHABLE           4
+  /* Only set on blocks that have just been created by create_bb.  */
+  BB_NEW = 2,
 
-/* Used by dfs_enumerate_from to keep track of visited basic blocks.  */
-#define BB_VISITED             8
+  /* Set by find_unreachable_blocks.  Do not rely on this being set in any
+     pass.  */
+  BB_REACHABLE = 4,
 
-/* Set for blocks in an irreducible loop by loop analysis.  */
-#define BB_IRREDUCIBLE_LOOP    16
+  /* Set for blocks in an irreducible loop by loop analysis.  */
+  BB_IRREDUCIBLE_LOOP = 8,
 
-/* Set on blocks that may actually not be single-entry single-exit block.  */
-#define BB_SUPERBLOCK          32
+  /* Set on blocks that may actually not be single-entry single-exit block.  */
+  BB_SUPERBLOCK = 16,
 
-/* Set on basic blocks that the scheduler should not touch.  This is used
-   by SMS to prevent other schedulers from messing with the loop schedule.  */
-#define BB_DISABLE_SCHEDULE    64
+  /* Set on basic blocks that the scheduler should not touch.  This is used
+     by SMS to prevent other schedulers from messing with the loop schedule.  */
+  BB_DISABLE_SCHEDULE = 32,
 
-/* Set on blocks that should be put in a hot section.  */
-#define BB_HOT_PARTITION       128
+  /* Set on blocks that should be put in a hot section.  */
+  BB_HOT_PARTITION = 64,
 
-/* Set on blocks that should be put in a cold section.  */
-#define BB_COLD_PARTITION      256
+  /* Set on blocks that should be put in a cold section.  */
+  BB_COLD_PARTITION = 128
+};
 
 /* Dummy flag for convenience in the hot/cold partitioning code.  */
 #define BB_UNPARTITIONED       0
index 7cecd984a02ab5ff0546d8de454323b4827aab5a..5afbabc19e001bcad5ef4497cc9bb6341c8d87ba 100644 (file)
@@ -900,10 +900,45 @@ dfs_enumerate_from (basic_block bb, int reverse,
 {
   basic_block *st, lbb;
   int sp = 0, tv = 0;
+  unsigned size;
+
+  /* A bitmap to keep track of visited blocks.  Allocating it each time
+     this function is called is not possible, since dfs_enumerate_from
+     is often used on small (almost) disjoint parts of cfg (bodies of
+     loops), and allocating a large sbitmap would lead to quadratic
+     behavior.  */
+  static sbitmap visited;
+  static unsigned v_size;
+
+#define MARK_VISITED(BB) (SET_BIT (visited, (BB)->index + 2))
+#define UNMARK_VISITED(BB) (RESET_BIT (visited, (BB)->index + 2))
+#define VISITED_P(BB) (TEST_BIT (visited, (BB)->index + 2))
+
+  /* Resize the VISITED sbitmap if necessary.  */
+  size = last_basic_block + 2;
+  if (size < 10)
+    size = 10;
+
+  if (!visited)
+    {
+
+      visited = sbitmap_alloc (size);
+      sbitmap_zero (visited);
+      v_size = size;
+    }
+  else if (v_size < size)
+    {
+      /* Ensure that we increase the size of the sbitmap exponentially.  */
+      if (2 * v_size > size)
+       size = 2 * v_size;
+
+      visited = sbitmap_resize (visited, size, 0);
+      v_size = size;
+    }
 
   st = xcalloc (rslt_max, sizeof (basic_block));
   rslt[tv++] = st[sp++] = bb;
-  bb->flags |= BB_VISITED;
+  MARK_VISITED (bb);
   while (sp)
     {
       edge e;
@@ -912,28 +947,31 @@ dfs_enumerate_from (basic_block bb, int reverse,
       if (reverse)
         {
          FOR_EACH_EDGE (e, ei, lbb->preds)
-           if (!(e->src->flags & BB_VISITED) && predicate (e->src, data))
+           if (!VISITED_P (e->src) && predicate (e->src, data))
              {
                gcc_assert (tv != rslt_max);
                rslt[tv++] = st[sp++] = e->src;
-               e->src->flags |= BB_VISITED;
+               MARK_VISITED (e->src);
              }
         }
       else
         {
          FOR_EACH_EDGE (e, ei, lbb->succs)
-           if (!(e->dest->flags & BB_VISITED) && predicate (e->dest, data))
+           if (!VISITED_P (e->dest) && predicate (e->dest, data))
              {
                gcc_assert (tv != rslt_max);
                rslt[tv++] = st[sp++] = e->dest;
-               e->dest->flags |= BB_VISITED;
+               MARK_VISITED (e->dest);
              }
        }
     }
   free (st);
   for (sp = 0; sp < tv; sp++)
-    rslt[sp]->flags &= ~BB_VISITED;
+    UNMARK_VISITED (rslt[sp]);
   return tv;
+#undef MARK_VISITED
+#undef UNMARK_VISITED
+#undef VISITED_P
 }