OSDN Git Service

Fix required by libjava/libltdl import.
[pf3gnuchains/gcc-fork.git] / gcc / cfgbuild.c
index 12dd200..5805e58 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,27 +47,21 @@ 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));
-static rtx find_label_refs             PARAMS ((rtx, rtx));
-static void make_edges                 PARAMS ((rtx, basic_block,
-                                                basic_block, int));
-static void make_label_edge            PARAMS ((sbitmap *, basic_block,
-                                                rtx, int));
-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));
+
+static int count_basic_blocks (rtx);
+static void find_basic_blocks_1 (rtx);
+static rtx find_label_refs (rtx, rtx);
+static void make_edges (rtx, basic_block, basic_block, int);
+static void make_label_edge (sbitmap *, basic_block, rtx, int);
+static void make_eh_edge (sbitmap *, basic_block, rtx);
+static void find_bb_boundaries (basic_block);
+static void compute_outgoing_frequencies (basic_block);
 \f
 /* Return true if insn is something that should be contained inside basic
    block.  */
 
-static bool
-inside_basic_block_p (insn)
-     rtx insn;
+bool
+inside_basic_block_p (rtx insn)
 {
   switch (GET_CODE (insn))
     {
@@ -96,9 +92,8 @@ 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
-control_flow_insn_p (insn)
-     rtx insn;
+bool
+control_flow_insn_p (rtx insn)
 {
   rtx note;
 
@@ -126,7 +121,7 @@ control_flow_insn_p (insn)
       return (flag_non_call_exceptions && can_throw_internal (insn));
 
     case BARRIER:
-      /* It is nonsence to reach barrier when looking for the
+      /* It is nonsense to reach barrier when looking for the
          end of basic block, but before dead code is eliminated
          this may happen.  */
       return false;
@@ -139,8 +134,7 @@ control_flow_insn_p (insn)
 /* Count the basic blocks of the function.  */
 
 static int
-count_basic_blocks (f)
-     rtx f;
+count_basic_blocks (rtx f)
 {
   int count = 0;
   bool saw_insn = false;
@@ -148,7 +142,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)
@@ -181,9 +175,7 @@ count_basic_blocks (f)
    This is used to scan the alternatives of a call placeholder.  */
 
 static rtx
-find_label_refs (f, lvl)
-     rtx f;
-     rtx lvl;
+find_label_refs (rtx f, rtx lvl)
 {
   rtx insn;
 
@@ -230,11 +222,7 @@ find_label_refs (f, lvl)
 /* Create an edge from a basic block to a label.  */
 
 static void
-make_label_edge (edge_cache, src, label, flags)
-     sbitmap *edge_cache;
-     basic_block src;
-     rtx label;
-     int flags;
+make_label_edge (sbitmap *edge_cache, basic_block src, rtx label, int flags)
 {
   if (GET_CODE (label) != CODE_LABEL)
     abort ();
@@ -253,10 +241,7 @@ make_label_edge (edge_cache, src, label, flags)
 /* Create the edges generated by INSN in REGION.  */
 
 static void
-make_eh_edge (edge_cache, src, insn)
-     sbitmap *edge_cache;
-     basic_block src;
-     rtx insn;
+make_eh_edge (sbitmap *edge_cache, basic_block src, rtx insn)
 {
   int is_call = GET_CODE (insn) == CALL_INSN ? EDGE_ABNORMAL_CALL : 0;
   rtx handlers, i;
@@ -279,10 +264,7 @@ make_eh_edge (edge_cache, src, insn)
    the list of exception regions active at the end of the basic block.  */
 
 static void
-make_edges (label_value_list, min, max, update_p)
-     rtx label_value_list;
-     basic_block min, max;
-     int update_p;
+make_edges (rtx label_value_list, basic_block min, basic_block max, int update_p)
 {
   basic_block bb;
   sbitmap *edge_cache = NULL;
@@ -293,7 +275,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,13 +303,14 @@ 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_ALT_ENTRY_P (bb->head))
+      if (GET_CODE (BB_HEAD (bb)) == CODE_LABEL
+         && LABEL_ALT_ENTRY_P (BB_HEAD (bb)))
        cached_make_edge (NULL, ENTRY_BLOCK_PTR, bb, 0);
 
       /* Examine the last instruction of the block, and discover the
         ways we can leave the block.  */
 
-      insn = bb->end;
+      insn = BB_END (bb);
       code = GET_CODE (insn);
 
       /* A branch.  */
@@ -344,12 +327,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;
@@ -412,7 +391,7 @@ make_edges (label_value_list, min, max, update_p)
         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);
+                         EDGE_SIBCALL | EDGE_ABNORMAL);
 
       /* 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 +423,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_HEAD (bb->next_bb))
            cached_make_edge (edge_cache, bb, bb->next_bb, EDGE_FALLTHRU);
        }
     }
@@ -467,8 +448,7 @@ make_edges (label_value_list, min, max, update_p)
    will be used in make_edges for use with computed gotos.  */
 
 static void
-find_basic_blocks_1 (f)
-     rtx f;
+find_basic_blocks_1 (rtx f)
 {
   rtx insn, next;
   rtx bb_note = NULL_RTX;
@@ -607,10 +587,8 @@ find_basic_blocks_1 (f)
    numbers in use.  */
 
 void
-find_basic_blocks (f, nregs, file)
-     rtx f;
-     int nregs ATTRIBUTE_UNUSED;
-     FILE *file ATTRIBUTE_UNUSED;
+find_basic_blocks (rtx f, int nregs ATTRIBUTE_UNUSED,
+                  FILE *file ATTRIBUTE_UNUSED)
 {
   basic_block bb;
 
@@ -625,7 +603,7 @@ find_basic_blocks (f, nregs, file)
         tag for reuse during create_basic_block, just in case some pass
         copies around basic block notes improperly.  */
       FOR_EACH_BB (bb)
-       bb->aux = NULL;
+       bb->aux = NULL;
 
       VARRAY_FREE (basic_block_info);
     }
@@ -670,15 +648,14 @@ enum state {BLOCK_NEW = 0, BLOCK_ORIGINAL, BLOCK_TO_SPLIT};
    and create new basic blocks in the progress.  */
 
 static void
-find_bb_boundaries (bb)
-     basic_block bb;
+find_bb_boundaries (basic_block bb)
 {
-  rtx insn = bb->head;
-  rtx end = bb->end;
+  rtx insn = BB_HEAD (bb);
+  rtx end = BB_END (bb);
   rtx flow_transfer_insn = NULL_RTX;
   edge fallthru = NULL;
 
-  if (insn == bb->end)
+  if (insn == BB_END (bb))
     return;
 
   if (GET_CODE (insn) == CODE_LABEL)
@@ -694,7 +671,7 @@ find_bb_boundaries (bb)
        {
          fallthru = split_block (bb, PREV_INSN (insn));
          if (flow_transfer_insn)
-           bb->end = flow_transfer_insn;
+           BB_END (bb) = flow_transfer_insn;
 
          bb = fallthru->dest;
          remove_edge (fallthru);
@@ -708,7 +685,7 @@ find_bb_boundaries (bb)
       if (flow_transfer_insn && inside_basic_block_p (insn))
        {
          fallthru = split_block (bb, PREV_INSN (insn));
-         bb->end = flow_transfer_insn;
+         BB_END (bb) = flow_transfer_insn;
          bb = fallthru->dest;
          remove_edge (fallthru);
          flow_transfer_insn = NULL_RTX;
@@ -725,7 +702,7 @@ find_bb_boundaries (bb)
      return and barrier, or possibly other sequence not behaving like
      ordinary jump, we need to take care and move basic block boundary.  */
   if (flow_transfer_insn)
-    bb->end = flow_transfer_insn;
+    BB_END (bb) = flow_transfer_insn;
 
   /* We've possibly replaced the conditional jump by conditional jump
      followed by cleanup at fallthru edge, so the outgoing edges may
@@ -737,22 +714,19 @@ find_bb_boundaries (bb)
     and probabilities of outgoing edges.  */
 
 static void
-compute_outgoing_frequencies (b)
-     basic_block b;
+compute_outgoing_frequencies (basic_block b)
 {
   edge e, f;
 
   if (b->succ && b->succ->succ_next && !b->succ->succ_next->succ_next)
     {
-      rtx note = find_reg_note (b->end, REG_BR_PROB, NULL);
+      rtx note = find_reg_note (BB_END (b), REG_BR_PROB, NULL);
       int probability;
 
       if (!note)
        return;
 
-      probability = INTVAL (XEXP (find_reg_note (b->end,
-                                                REG_BR_PROB, NULL),
-                                 0));
+      probability = INTVAL (XEXP (note, 0));
       e = BRANCH_EDGE (b);
       e->probability = probability;
       e->count = ((b->count * probability + REG_BR_PROB_BASE / 2)
@@ -774,8 +748,7 @@ compute_outgoing_frequencies (b)
    basic block.  Update the data structure.  */
 
 void
-find_many_sub_basic_blocks (blocks)
-     sbitmap blocks;
+find_many_sub_basic_blocks (sbitmap blocks)
 {
   basic_block bb, min, max;
 
@@ -812,7 +785,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);
@@ -829,8 +802,7 @@ find_many_sub_basic_blocks (blocks)
 /* Like above but for single basic block only.  */
 
 void
-find_sub_basic_blocks (bb)
-     basic_block bb;
+find_sub_basic_blocks (basic_block bb)
 {
   basic_block min, max, b;
   basic_block next = bb->next_bb;
@@ -853,7 +825,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);