OSDN Git Service

* gcc.c (LIBGCC_SPEC): If REAL_LIBGCC_SPEC is defined, and
[pf3gnuchains/gcc-fork.git] / gcc / cfg.c
index ba4dd81..ff3f367 100644 (file)
--- a/gcc/cfg.c
+++ b/gcc/cfg.c
@@ -1,6 +1,6 @@
 /* Control flow graph manipulation code for GNU compiler.
    Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -111,6 +111,7 @@ struct basic_block_def entry_exit_blocks[2]
     EXIT_BLOCK_PTR,            /* next_bb */
     0,                         /* loop_depth */
     NULL,                       /* loop_father */
+    { NULL, NULL },            /* dom */
     0,                         /* count */
     0,                         /* frequency */
     0,                         /* flags */
@@ -133,6 +134,7 @@ struct basic_block_def entry_exit_blocks[2]
     NULL,                      /* next_bb */
     0,                         /* loop_depth */
     NULL,                       /* loop_father */
+    { NULL, NULL },            /* dom */
     0,                         /* count */
     0,                         /* frequency */
     0,                         /* flags */
@@ -155,7 +157,7 @@ init_flow (void)
   if (!initialized)
     {
       gcc_obstack_init (&flow_obstack);
-      flow_firstobj = (char *) obstack_alloc (&flow_obstack, 0);
+      flow_firstobj = obstack_alloc (&flow_obstack, 0);
       initialized = 1;
     }
   else
@@ -163,7 +165,7 @@ init_flow (void)
       free_alloc_pool (bb_pool);
       free_alloc_pool (edge_pool);
       obstack_free (&flow_obstack, flow_firstobj);
-      flow_firstobj = (char *) obstack_alloc (&flow_obstack, 0);
+      flow_firstobj = obstack_alloc (&flow_obstack, 0);
     }
   bb_pool = create_alloc_pool ("Basic block pool",
                               sizeof (struct basic_block_def), 100);
@@ -332,7 +334,7 @@ cached_make_edge (sbitmap *edge_cache, basic_block src, basic_block dst, int fla
       if (flags == 0)
        return NULL;
 
-      /* FALLTHRU */
+      /* Fall through.  */
     case 0:
       for (e = src->succ; e; e = e->succ_next)
        if (e->dest == dst)
@@ -491,48 +493,49 @@ dump_flow_info (FILE *file)
   static const char * const reg_class_names[] = REG_CLASS_NAMES;
 
   fprintf (file, "%d registers.\n", max_regno);
-  for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
-    if (REG_N_REFS (i))
-      {
-       enum reg_class class, altclass;
-
-       fprintf (file, "\nRegister %d used %d times across %d insns",
-                i, REG_N_REFS (i), REG_LIVE_LENGTH (i));
-       if (REG_BASIC_BLOCK (i) >= 0)
-         fprintf (file, " in block %d", REG_BASIC_BLOCK (i));
-       if (REG_N_SETS (i))
-         fprintf (file, "; set %d time%s", REG_N_SETS (i),
-                  (REG_N_SETS (i) == 1) ? "" : "s");
-       if (regno_reg_rtx[i] != NULL && REG_USERVAR_P (regno_reg_rtx[i]))
-         fprintf (file, "; user var");
-       if (REG_N_DEATHS (i) != 1)
-         fprintf (file, "; dies in %d places", REG_N_DEATHS (i));
-       if (REG_N_CALLS_CROSSED (i) == 1)
-         fprintf (file, "; crosses 1 call");
-       else if (REG_N_CALLS_CROSSED (i))
-         fprintf (file, "; crosses %d calls", REG_N_CALLS_CROSSED (i));
-       if (regno_reg_rtx[i] != NULL
-           && PSEUDO_REGNO_BYTES (i) != UNITS_PER_WORD)
-         fprintf (file, "; %d bytes", PSEUDO_REGNO_BYTES (i));
-
-       class = reg_preferred_class (i);
-       altclass = reg_alternate_class (i);
-       if (class != GENERAL_REGS || altclass != ALL_REGS)
-         {
-           if (altclass == ALL_REGS || class == ALL_REGS)
-             fprintf (file, "; pref %s", reg_class_names[(int) class]);
-           else if (altclass == NO_REGS)
-             fprintf (file, "; %s or none", reg_class_names[(int) class]);
-           else
-             fprintf (file, "; pref %s, else %s",
-                      reg_class_names[(int) class],
-                      reg_class_names[(int) altclass]);
-         }
+  if (reg_n_info)
+    for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
+      if (REG_N_REFS (i))
+       {
+         enum reg_class class, altclass;
+
+         fprintf (file, "\nRegister %d used %d times across %d insns",
+                  i, REG_N_REFS (i), REG_LIVE_LENGTH (i));
+         if (REG_BASIC_BLOCK (i) >= 0)
+           fprintf (file, " in block %d", REG_BASIC_BLOCK (i));
+         if (REG_N_SETS (i))
+           fprintf (file, "; set %d time%s", REG_N_SETS (i),
+                    (REG_N_SETS (i) == 1) ? "" : "s");
+         if (regno_reg_rtx[i] != NULL && REG_USERVAR_P (regno_reg_rtx[i]))
+           fprintf (file, "; user var");
+         if (REG_N_DEATHS (i) != 1)
+           fprintf (file, "; dies in %d places", REG_N_DEATHS (i));
+         if (REG_N_CALLS_CROSSED (i) == 1)
+           fprintf (file, "; crosses 1 call");
+         else if (REG_N_CALLS_CROSSED (i))
+           fprintf (file, "; crosses %d calls", REG_N_CALLS_CROSSED (i));
+         if (regno_reg_rtx[i] != NULL
+             && PSEUDO_REGNO_BYTES (i) != UNITS_PER_WORD)
+           fprintf (file, "; %d bytes", PSEUDO_REGNO_BYTES (i));
+
+         class = reg_preferred_class (i);
+         altclass = reg_alternate_class (i);
+         if (class != GENERAL_REGS || altclass != ALL_REGS)
+           {
+             if (altclass == ALL_REGS || class == ALL_REGS)
+               fprintf (file, "; pref %s", reg_class_names[(int) class]);
+             else if (altclass == NO_REGS)
+               fprintf (file, "; %s or none", reg_class_names[(int) class]);
+             else
+               fprintf (file, "; pref %s, else %s",
+                        reg_class_names[(int) class],
+                        reg_class_names[(int) altclass]);
+           }
 
-       if (regno_reg_rtx[i] != NULL && REG_POINTER (regno_reg_rtx[i]))
-         fprintf (file, "; pointer");
-       fprintf (file, ".\n");
-      }
+         if (regno_reg_rtx[i] != NULL && REG_POINTER (regno_reg_rtx[i]))
+           fprintf (file, "; pointer");
+         fprintf (file, ".\n");
+       }
 
   fprintf (file, "\n%d basic blocks, %d edges.\n", n_basic_blocks, n_edges);
   FOR_EACH_BB (bb)
@@ -542,7 +545,7 @@ dump_flow_info (FILE *file)
       gcov_type lsum;
 
       fprintf (file, "\nBasic block %d: first insn %d, last %d, ",
-              bb->index, INSN_UID (bb->head), INSN_UID (bb->end));
+              bb->index, INSN_UID (BB_HEAD (bb)), INSN_UID (BB_END (bb)));
       fprintf (file, "prev %d, next %d, ",
               bb->prev_bb->index, bb->next_bb->index);
       fprintf (file, "loop_depth %d, count ", bb->loop_depth);
@@ -636,7 +639,7 @@ dump_edge_info (FILE *file, edge e, int do_succ)
     {
       static const char * const bitnames[] = {
        "fallthru", "ab", "abcall", "eh", "fake", "dfs_back",
-       "can_fallthru", "irreducible", "sibcall"
+       "can_fallthru", "irreducible", "sibcall", "loop_exit"
       };
       int comma = 0;
       int i, flags = e->flags;
@@ -697,7 +700,7 @@ alloc_aux_for_blocks (int size)
   /* Check whether AUX data are still allocated.  */
   else if (first_block_aux_obj)
     abort ();
-  first_block_aux_obj = (char *) obstack_alloc (&block_aux_obstack, 0);
+  first_block_aux_obj = obstack_alloc (&block_aux_obstack, 0);
   if (size)
     {
       basic_block bb;
@@ -763,7 +766,7 @@ alloc_aux_for_edges (int size)
   else if (first_edge_aux_obj)
     abort ();
 
-  first_edge_aux_obj = (char *) obstack_alloc (&edge_aux_obstack, 0);
+  first_edge_aux_obj = obstack_alloc (&edge_aux_obstack, 0);
   if (size)
     {
       basic_block bb;
@@ -807,182 +810,16 @@ free_aux_for_edges (void)
   clear_aux_for_edges ();
 }
 
-/* Verify the CFG consistency.
-
-   Currently it does following checks edge and basic block list correctness
-   and calls into IL dependent checking then.  */
-void
-verify_flow_info (void)
-{
-  size_t *edge_checksum;
-  int num_bb_notes, err = 0;
-  basic_block bb, last_bb_seen;
-  basic_block *last_visited;
-
-  last_visited = (basic_block *) xcalloc (last_basic_block + 2,
-                                         sizeof (basic_block));
-  edge_checksum = (size_t *) xcalloc (last_basic_block + 2, sizeof (size_t));
-
-  /* Check bb chain & numbers.  */
-  last_bb_seen = ENTRY_BLOCK_PTR;
-  FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR->next_bb, NULL, next_bb)
-    {
-      if (bb != EXIT_BLOCK_PTR
-         && bb != BASIC_BLOCK (bb->index))
-       {
-         error ("bb %d on wrong place", bb->index);
-         err = 1;
-       }
-
-      if (bb->prev_bb != last_bb_seen)
-       {
-         error ("prev_bb of %d should be %d, not %d",
-                bb->index, last_bb_seen->index, bb->prev_bb->index);
-         err = 1;
-       }
-
-      last_bb_seen = bb;
-    }
-
-  /* Now check the basic blocks (boundaries etc.) */
-  FOR_EACH_BB_REVERSE (bb)
-    {
-      int n_fallthru = 0;
-      edge e;
-
-      if (bb->count < 0)
-       {
-         error ("verify_flow_info: Wrong count of block %i %i",
-                bb->index, (int)bb->count);
-         err = 1;
-       }
-      if (bb->frequency < 0)
-       {
-         error ("verify_flow_info: Wrong frequency of block %i %i",
-                bb->index, bb->frequency);
-         err = 1;
-       }
-      for (e = bb->succ; e; e = e->succ_next)
-       {
-         if (last_visited [e->dest->index + 2] == bb)
-           {
-             error ("verify_flow_info: Duplicate edge %i->%i",
-                    e->src->index, e->dest->index);
-             err = 1;
-           }
-         if (e->probability < 0 || e->probability > REG_BR_PROB_BASE)
-           {
-             error ("verify_flow_info: Wrong probability of edge %i->%i %i",
-                    e->src->index, e->dest->index, e->probability);
-             err = 1;
-           }
-         if (e->count < 0)
-           {
-             error ("verify_flow_info: Wrong count of edge %i->%i %i",
-                    e->src->index, e->dest->index, (int)e->count);
-             err = 1;
-           }
-
-         last_visited [e->dest->index + 2] = bb;
-
-         if (e->flags & EDGE_FALLTHRU)
-           n_fallthru++;
-
-         if (e->src != bb)
-           {
-             error ("verify_flow_info: Basic block %d succ edge is corrupted",
-                    bb->index);
-             fprintf (stderr, "Predecessor: ");
-             dump_edge_info (stderr, e, 0);
-             fprintf (stderr, "\nSuccessor: ");
-             dump_edge_info (stderr, e, 1);
-             fprintf (stderr, "\n");
-             err = 1;
-           }
-
-         edge_checksum[e->dest->index + 2] += (size_t) e;
-       }
-      if (n_fallthru > 1)
-       {
-         error ("Wrong amount of branch edges after unconditional jump %i", bb->index);
-         err = 1;
-       }
-
-      for (e = bb->pred; e; e = e->pred_next)
-       {
-         if (e->dest != bb)
-           {
-             error ("basic block %d pred edge is corrupted", bb->index);
-             fputs ("Predecessor: ", stderr);
-             dump_edge_info (stderr, e, 0);
-             fputs ("\nSuccessor: ", stderr);
-             dump_edge_info (stderr, e, 1);
-             fputc ('\n', stderr);
-             err = 1;
-           }
-         edge_checksum[e->dest->index + 2] -= (size_t) e;
-       }
-    }
-
-  /* Complete edge checksumming for ENTRY and EXIT.  */
-  {
-    edge e;
-
-    for (e = ENTRY_BLOCK_PTR->succ; e ; e = e->succ_next)
-      edge_checksum[e->dest->index + 2] += (size_t) e;
-
-    for (e = EXIT_BLOCK_PTR->pred; e ; e = e->pred_next)
-      edge_checksum[e->dest->index + 2] -= (size_t) e;
-  }
-
-  FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
-    if (edge_checksum[bb->index + 2])
-      {
-       error ("basic block %i edge lists are corrupted", bb->index);
-       err = 1;
-      }
-
-  num_bb_notes = 0;
-  last_bb_seen = ENTRY_BLOCK_PTR;
-
-  /* Clean up.  */
-  free (last_visited);
-  free (edge_checksum);
-  err |= cfg_hooks->cfgh_verify_flow_info ();
-  if (err)
-    internal_error ("verify_flow_info failed");
-}
-
-/* Print out one basic block with live information at start and end.  */
-
-void
-dump_bb (basic_block bb, FILE *outf)
-{
-  edge e;
-
-  fprintf (outf, ";; Basic block %d, loop depth %d, count ",
-          bb->index, bb->loop_depth);
-  fprintf (outf, HOST_WIDEST_INT_PRINT_DEC, (HOST_WIDEST_INT) bb->count);
-  putc ('\n', outf);
-
-  cfg_hooks->dump_bb (bb, outf);
-
-  fputs (";; Successors: ", outf);
-  for (e = bb->succ; e; e = e->succ_next)
-    dump_edge_info (outf, e, 1);
-  putc ('\n', outf);
-}
-
 void
 debug_bb (basic_block bb)
 {
-  dump_bb (bb, stderr);
+  dump_bb (bb, stderr, 0);
 }
 
 basic_block
 debug_bb_n (int n)
 {
   basic_block bb = BASIC_BLOCK (n);
-  dump_bb (bb, stderr);
+  dump_bb (bb, stderr, 0);
   return bb;
 }