OSDN Git Service

2003-02-12 Phil Edwards <pme@gcc.gnu.org>
[pf3gnuchains/gcc-fork.git] / gcc / cfgbuild.c
index d531877..d5d1b20 100644 (file)
@@ -1,6 +1,6 @@
 /* Control flow graph building code for GNU compiler.
    Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -34,6 +34,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 \f
 #include "config.h"
 #include "system.h"
+#include "coretypes.h"
+#include "tm.h"
 #include "tree.h"
 #include "rtl.h"
 #include "hard-reg-set.h"
@@ -45,7 +47,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "except.h"
 #include "toplev.h"
 #include "timevar.h"
-#include "obstack.h"
 
 static int count_basic_blocks          PARAMS ((rtx));
 static void find_basic_blocks_1                PARAMS ((rtx));
@@ -57,13 +58,11 @@ static void make_label_edge         PARAMS ((sbitmap *, basic_block,
 static void make_eh_edge               PARAMS ((sbitmap *, basic_block, rtx));
 static void find_bb_boundaries         PARAMS ((basic_block));
 static void compute_outgoing_frequencies PARAMS ((basic_block));
-static bool inside_basic_block_p       PARAMS ((rtx));
-static bool control_flow_insn_p                PARAMS ((rtx));
 \f
 /* Return true if insn is something that should be contained inside basic
    block.  */
 
-static bool
+bool
 inside_basic_block_p (insn)
      rtx insn;
 {
@@ -96,7 +95,7 @@ inside_basic_block_p (insn)
 /* Return true if INSN may cause control flow transfer, so it should be last in
    the basic block.  */
 
-static bool
+bool
 control_flow_insn_p (insn)
      rtx insn;
 {
@@ -104,35 +103,35 @@ control_flow_insn_p (insn)
 
   switch (GET_CODE (insn))
     {
-      case NOTE:
-      case CODE_LABEL:
-       return false;
-
-      case JUMP_INSN:
-       /* Jump insn always causes control transfer except for tablejumps.  */
-       return (GET_CODE (PATTERN (insn)) != ADDR_VEC
-               && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC);
-
-      case CALL_INSN:
-       /* Call insn may return to the nonlocal goto handler.  */
-       return ((nonlocal_goto_handler_labels
-                && (0 == (note = find_reg_note (insn, REG_EH_REGION,
-                                                NULL_RTX))
-                    || INTVAL (XEXP (note, 0)) >= 0))
-               /* Or may trap.  */
-               || can_throw_internal (insn));
-
-      case INSN:
-       return (flag_non_call_exceptions && can_throw_internal (insn));
-
-      case BARRIER:
-       /* It is nonsence to reach barrier when looking for the
-          end of basic block, but before dead code is eliminated
-          this may happen.  */
-       return false;
-
-      default:
-       abort ();
+    case NOTE:
+    case CODE_LABEL:
+      return false;
+
+    case JUMP_INSN:
+      /* Jump insn always causes control transfer except for tablejumps.  */
+      return (GET_CODE (PATTERN (insn)) != ADDR_VEC
+             && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC);
+
+    case CALL_INSN:
+      /* Call insn may return to the nonlocal goto handler.  */
+      return ((nonlocal_goto_handler_labels
+              && (0 == (note = find_reg_note (insn, REG_EH_REGION,
+                                              NULL_RTX))
+                  || INTVAL (XEXP (note, 0)) >= 0))
+             /* Or may trap.  */
+             || can_throw_internal (insn));
+
+    case INSN:
+      return (flag_non_call_exceptions && can_throw_internal (insn));
+
+    case BARRIER:
+      /* It is nonsence to reach barrier when looking for the
+         end of basic block, but before dead code is eliminated
+         this may happen.  */
+      return false;
+
+    default:
+      abort ();
     }
 }
 
@@ -148,7 +147,7 @@ count_basic_blocks (f)
 
   for (insn = f; insn; insn = NEXT_INSN (insn))
     {
-      /* Code labels and barriers causes curent basic block to be
+      /* Code labels and barriers causes current basic block to be
          terminated at previous real insn.  */
       if ((GET_CODE (insn) == CODE_LABEL || GET_CODE (insn) == BARRIER)
          && saw_insn)
@@ -207,9 +206,9 @@ find_label_refs (f, lvl)
              rtx lab = XEXP (note, 0), next;
 
              if ((next = next_nonnote_insn (lab)) != NULL
-                      && GET_CODE (next) == JUMP_INSN
-                      && (GET_CODE (PATTERN (next)) == ADDR_VEC
-                          || GET_CODE (PATTERN (next)) == ADDR_DIFF_VEC))
+                 && GET_CODE (next) == JUMP_INSN
+                 && (GET_CODE (PATTERN (next)) == ADDR_VEC
+                     || GET_CODE (PATTERN (next)) == ADDR_DIFF_VEC))
                ;
              else if (GET_CODE (lab) == NOTE)
                ;
@@ -293,7 +292,7 @@ make_edges (label_value_list, min, max, update_p)
   /* Heavy use of computed goto in machine-generated code can lead to
      nearly fully-connected CFGs.  In that case we spend a significant
      amount of time searching the edge lists for duplicates.  */
-  if (forced_labels || label_value_list)
+  if (forced_labels || label_value_list || cfun->max_jumptable_ents > 100)
     {
       edge_cache = sbitmap_vector_alloc (last_basic_block, last_basic_block);
       sbitmap_vector_zero (edge_cache, last_basic_block);
@@ -305,10 +304,12 @@ make_edges (label_value_list, min, max, update_p)
 
            for (e = bb->succ; e ; e = e->succ_next)
              if (e->dest != EXIT_BLOCK_PTR)
-               SET_BIT (edge_cache[bb->sindex], e->dest->sindex);
+               SET_BIT (edge_cache[bb->index], e->dest->index);
          }
     }
 
+  /* By nature of the way these get numbered, ENTRY_BLOCK_PTR->next_bb block
+     is always the entry.  */
   if (min == ENTRY_BLOCK_PTR->next_bb)
     cached_make_edge (edge_cache, ENTRY_BLOCK_PTR, min,
                      EDGE_FALLTHRU);
@@ -319,7 +320,7 @@ make_edges (label_value_list, min, max, update_p)
       enum rtx_code code;
       int force_fallthru = 0;
 
-      if (GET_CODE (bb->head) == CODE_LABEL && LABEL_ALTERNATE_NAME (bb->head))
+      if (GET_CODE (bb->head) == CODE_LABEL && LABEL_ALT_ENTRY_P (bb->head))
        cached_make_edge (NULL, ENTRY_BLOCK_PTR, bb, 0);
 
       /* Examine the last instruction of the block, and discover the
@@ -443,7 +444,6 @@ 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 || (bb->next_bb == EXIT_BLOCK_PTR && force_fallthru))
        cached_make_edge (edge_cache, bb, EXIT_BLOCK_PTR, EDGE_FALLTHRU);
       else if (bb->next_bb != EXIT_BLOCK_PTR)
@@ -452,8 +452,7 @@ make_edges (label_value_list, min, max, update_p)
          if (GET_CODE (tmp) == NOTE)
            tmp = next_nonnote_insn (tmp);
          if (force_fallthru || insn == tmp)
-           cached_make_edge (edge_cache, bb, bb->next_bb,
-                             EDGE_FALLTHRU);
+           cached_make_edge (edge_cache, bb, bb->next_bb, EDGE_FALLTHRU);
        }
     }
 
@@ -493,7 +492,7 @@ find_basic_blocks_1 (f)
       if ((GET_CODE (insn) == CODE_LABEL || GET_CODE (insn) == BARRIER)
          && head)
        {
-         prev = create_basic_block_structure (last_basic_block++, head, end, bb_note, prev);
+         prev = create_basic_block_structure (head, end, bb_note, prev);
          head = end = NULL_RTX;
          bb_note = NULL_RTX;
        }
@@ -507,7 +506,7 @@ find_basic_blocks_1 (f)
 
       if (head && control_flow_insn_p (insn))
        {
-         prev = create_basic_block_structure (last_basic_block++, head, end, bb_note, prev);
+         prev = create_basic_block_structure (head, end, bb_note, prev);
          head = end = NULL_RTX;
          bb_note = NULL_RTX;
        }
@@ -589,11 +588,11 @@ find_basic_blocks_1 (f)
     }
 
   if (head != NULL_RTX)
-    create_basic_block_structure (last_basic_block++, head, end, bb_note, prev);
+    create_basic_block_structure (head, end, bb_note, prev);
   else if (bb_note)
     delete_insn (bb_note);
 
-  if (last_basic_block != num_basic_blocks)
+  if (last_basic_block != n_basic_blocks)
     abort ();
 
   label_value_list = lvl;
@@ -612,11 +611,9 @@ find_basic_blocks (f, nregs, file)
      int nregs ATTRIBUTE_UNUSED;
      FILE *file ATTRIBUTE_UNUSED;
 {
-  int max_uid;
   basic_block bb;
-  timevar_push (TV_CFG);
 
-  basic_block_for_insn = 0;
+  timevar_push (TV_CFG);
 
   /* Flush out existing data.  */
   if (basic_block_info != NULL)
@@ -626,13 +623,13 @@ find_basic_blocks (f, nregs, file)
       /* Clear bb->aux on all extant basic blocks.  We'll use this as a
         tag for reuse during create_basic_block, just in case some pass
         copies around basic block notes improperly.  */
-      FOR_ALL_BB (bb)
+      FOR_EACH_BB (bb)
        bb->aux = NULL;
 
       VARRAY_FREE (basic_block_info);
     }
 
-  num_basic_blocks = count_basic_blocks (f);
+  n_basic_blocks = count_basic_blocks (f);
   last_basic_block = 0;
   ENTRY_BLOCK_PTR->next_bb = EXIT_BLOCK_PTR;
   EXIT_BLOCK_PTR->prev_bb = ENTRY_BLOCK_PTR;
@@ -645,24 +642,10 @@ find_basic_blocks (f, nregs, file)
      instructions at all until close to the end of compilation when we
      actually lay them out.  */
 
-  VARRAY_BB_INIT (basic_block_info, num_basic_blocks, "basic_block_info");
+  VARRAY_BB_INIT (basic_block_info, n_basic_blocks, "basic_block_info");
 
   find_basic_blocks_1 (f);
 
-  /* Record the block to which an insn belongs.  */
-  /* ??? This should be done another way, by which (perhaps) a label is
-     tagged directly with the basic block that it starts.  It is used for
-     more than that currently, but IMO that is the only valid use.  */
-
-  max_uid = get_max_uid ();
-#ifdef AUTO_INC_DEC
-  /* Leave space for insns life_analysis makes in some cases for auto-inc.
-     These cases are rare, so we don't need too much space.  */
-  max_uid += max_uid / 10;
-#endif
-
-  compute_bb_for_insn (max_uid);
-
   /* Discover the edges of our cfg.  */
   make_edges (label_value_list, ENTRY_BLOCK_PTR->next_bb, EXIT_BLOCK_PTR->prev_bb, 0);
 
@@ -715,7 +698,7 @@ find_bb_boundaries (bb)
          bb = fallthru->dest;
          remove_edge (fallthru);
          flow_transfer_insn = NULL_RTX;
-         if (LABEL_ALTERNATE_NAME (insn))
+         if (LABEL_ALT_ENTRY_P (insn))
            make_edge (ENTRY_BLOCK_PTR, bb, 0);
        }
 
@@ -795,15 +778,15 @@ find_many_sub_basic_blocks (blocks)
 {
   basic_block bb, min, max;
 
-  FOR_ALL_BB (bb)
+  FOR_EACH_BB (bb)
     SET_STATE (bb,
-              TEST_BIT (blocks, bb->sindex) ? BLOCK_TO_SPLIT : BLOCK_ORIGINAL);
+              TEST_BIT (blocks, bb->index) ? BLOCK_TO_SPLIT : BLOCK_ORIGINAL);
 
-  FOR_ALL_BB (bb)
+  FOR_EACH_BB (bb)
     if (STATE (bb) == BLOCK_TO_SPLIT)
       find_bb_boundaries (bb);
 
-  FOR_ALL_BB (bb)
+  FOR_EACH_BB (bb)
     if (STATE (bb) != BLOCK_ORIGINAL)
       break;
 
@@ -838,7 +821,7 @@ find_many_sub_basic_blocks (blocks)
       compute_outgoing_frequencies (bb);
     }
 
-  FOR_ALL_BB (bb)
+  FOR_EACH_BB (bb)
     SET_STATE (bb, 0);
 }
 
@@ -846,7 +829,7 @@ find_many_sub_basic_blocks (blocks)
 
 void
 find_sub_basic_blocks (bb)
-    basic_block bb;
+     basic_block bb;
 {
   basic_block min, max, b;
   basic_block next = bb->next_bb;