OSDN Git Service

2003-06-10 Andrew Haley <aph@redhat.com>
[pf3gnuchains/gcc-fork.git] / gcc / cfgbuild.c
index 6b7a9ad..ed8dfb8 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, 2002 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;
 {
@@ -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)
@@ -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);
@@ -321,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
@@ -344,12 +343,8 @@ make_edges (label_value_list, min, max, update_p)
          else if (find_reg_note (insn, REG_NON_LOCAL_GOTO, NULL_RTX))
            ;
 
-         /* ??? Recognize a tablejump and do the right thing.  */
-         else if ((tmp = JUMP_LABEL (insn)) != NULL_RTX
-                  && (tmp = NEXT_INSN (tmp)) != NULL_RTX
-                  && GET_CODE (tmp) == JUMP_INSN
-                  && (GET_CODE (PATTERN (tmp)) == ADDR_VEC
-                      || GET_CODE (PATTERN (tmp)) == ADDR_DIFF_VEC))
+         /* Recognize a tablejump and do the right thing.  */
+         else if (tablejump_p (insn, NULL, &tmp))
            {
              rtvec vec;
              int j;
@@ -411,8 +406,7 @@ make_edges (label_value_list, min, max, update_p)
         worry about EH edges, since we wouldn't have created the sibling call
         in the first place.  */
       if (code == CALL_INSN && SIBLING_CALL_P (insn))
-       cached_make_edge (edge_cache, bb, EXIT_BLOCK_PTR,
-                  EDGE_ABNORMAL | EDGE_ABNORMAL_CALL);
+       cached_make_edge (edge_cache, bb, EXIT_BLOCK_PTR, EDGE_SIBCALL);
 
       /* If this is a CALL_INSN, then mark it as reaching the active EH
         handler for this CALL_INSN.  If we're handling non-call
@@ -444,15 +438,17 @@ 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);
+      insn = NEXT_INSN (insn);
+      while (insn
+            && GET_CODE (insn) == NOTE
+            && NOTE_LINE_NUMBER (insn) != NOTE_INSN_BASIC_BLOCK)
+       insn = NEXT_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)
        {
-         rtx tmp = bb->next_bb->head;
-         if (GET_CODE (tmp) == NOTE)
-           tmp = next_nonnote_insn (tmp);
-         if (force_fallthru || insn == tmp)
+         if (force_fallthru || insn == bb->next_bb->head)
            cached_make_edge (edge_cache, bb, bb->next_bb, EDGE_FALLTHRU);
        }
     }
@@ -647,13 +643,6 @@ find_basic_blocks (f, nregs, file)
 
   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.  */
-
-  compute_bb_for_insn ();
-
   /* Discover the edges of our cfg.  */
   make_edges (label_value_list, ENTRY_BLOCK_PTR->next_bb, EXIT_BLOCK_PTR->prev_bb, 0);
 
@@ -706,7 +695,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);
        }
 
@@ -819,7 +808,7 @@ find_many_sub_basic_blocks (blocks)
        {
          bb->count = 0;
          bb->frequency = 0;
-         for (e = bb->pred; e; e=e->pred_next)
+         for (e = bb->pred; e; e = e->pred_next)
            {
              bb->count += e->count;
              bb->frequency += EDGE_FREQUENCY (e);
@@ -860,7 +849,7 @@ find_sub_basic_blocks (bb)
        {
          b->count = 0;
          b->frequency = 0;
-         for (e = b->pred; e; e=e->pred_next)
+         for (e = b->pred; e; e = e->pred_next)
            {
              b->count += e->count;
              b->frequency += EDGE_FREQUENCY (e);