OSDN Git Service

(__objc_send_message_in_list): When setting a new entry in
[pf3gnuchains/gcc-fork.git] / gcc / bb-reorder.c
index 1162418..e13e5f1 100644 (file)
 #include "flags.h"
 #include "output.h"
 #include "function.h"
-#include "except.h"
 #include "toplev.h"
 #include "recog.h"
-#include "insn-flags.h"
 #include "expr.h"
 #include "obstack.h"
 
    For top-level functions, this is temporary_obstack.
    Separate obstacks are made for nested functions.  */
 
-extern struct obstack *function_obstack;
+extern struct obstack flow_obstack;
 
 
 /* Structure to hold information about lexical scopes.  */
@@ -396,15 +394,24 @@ make_reorder_chain_1 (bb, prev)
       taken = probability > REG_BR_PROB_BASE / 2;
 
       /* Find the normal taken edge and the normal fallthru edge.
-         Note that there may in fact be other edges due to
-        asynchronous_exceptions.  */
+
+        Note, conditional jumps with other side effects may not
+        be fully optimized.  In this case it is possible for
+        the conditional jump to branch to the same location as
+        the fallthru path.
+
+        We should probably work to improve optimization of that
+        case; however, it seems silly not to also deal with such
+        problems here if they happen to occur.  */
 
       e_taken = e_fall = NULL;
       for (e = bb->succ; e ; e = e->succ_next)
-       if (e->flags & EDGE_FALLTHRU)
-         e_fall = e;
-       else if (! (e->flags & EDGE_EH))
-         e_taken = e;
+       {
+         if (e->flags & EDGE_FALLTHRU)
+           e_fall = e;
+         if (! (e->flags & EDGE_EH))
+           e_taken = e;
+       }
 
       next = (taken ? e_taken : e_fall)->dest;
     }
@@ -549,7 +556,7 @@ fixup_reorder_chain ()
   for (bb = BASIC_BLOCK (0); bb ; bb = RBI (bb)->next)
     {
       edge e_fall, e_taken, e;
-      rtx jump_insn, barrier_insn;
+      rtx jump_insn, barrier_insn, bb_end_insn;
       basic_block nb;
 
       if (bb->succ == NULL)
@@ -564,9 +571,10 @@ fixup_reorder_chain ()
        else if (! (e->flags & EDGE_EH))
          e_taken = e;
 
-      if (GET_CODE (bb->end) == JUMP_INSN)
+      bb_end_insn = bb->end;
+      if (GET_CODE (bb_end_insn) == JUMP_INSN)
        {
-         if (any_uncondjump_p (bb->end))
+         if (any_uncondjump_p (bb_end_insn))
            {
              /* If the destination is still not next, nothing to do.  */
              if (RBI (bb)->index + 1 != RBI (e_taken->dest)->index)
@@ -582,7 +590,7 @@ fixup_reorder_chain ()
                         bb->index, RBI (bb)->index);
              continue;
            }
-         else if (any_condjump_p (bb->end))
+         else if (any_condjump_p (bb_end_insn))
            {
              /* If the old fallthru is still next, nothing to do.  */
              if (RBI (bb)->index + 1 == RBI (e_fall->dest)->index
@@ -596,10 +604,11 @@ fixup_reorder_chain ()
                 edge based on known or assumed probability.  */
              if (RBI (bb)->index + 1 != RBI (e_taken->dest)->index)
                {
-                 rtx note = find_reg_note (bb->end, REG_BR_PROB, 0);
+                 rtx note = find_reg_note (bb_end_insn, REG_BR_PROB, 0);
                  if (note
                      && INTVAL (XEXP (note, 0)) < REG_BR_PROB_BASE / 2
-                     && invert_jump (bb->end, label_for_bb (e_fall->dest), 0))
+                     && invert_jump (bb_end_insn,
+                                     label_for_bb (e_fall->dest), 0))
                    {
                      e_fall->flags &= ~EDGE_FALLTHRU;
                      e_taken->flags |= EDGE_FALLTHRU;
@@ -609,14 +618,15 @@ fixup_reorder_chain ()
 
              /* Otherwise we can try to invert the jump.  This will 
                 basically never fail, however, keep up the pretense.  */
-             else if (invert_jump (bb->end, label_for_bb (e_fall->dest), 0))
+             else if (invert_jump (bb_end_insn,
+                                   label_for_bb (e_fall->dest), 0))
                {
                  e_fall->flags &= ~EDGE_FALLTHRU;
                  e_taken->flags |= EDGE_FALLTHRU;
                  continue;
                }
            }
-         else if (returnjump_p (bb->end))
+         else if (returnjump_p (bb_end_insn))
            continue;
          else
            {
@@ -629,8 +639,10 @@ fixup_reorder_chain ()
                 tablejump, the fallthru block should not have moved.  */
              if (RBI (bb)->index + 1 == RBI (e_fall->dest)->index)
                continue;
-#endif
+             bb_end_insn = skip_insns_after_block (bb);
+#else
              abort ();
+#endif
            }
        }
       else
@@ -653,7 +665,7 @@ fixup_reorder_chain ()
            {
              e_fall->flags &= ~EDGE_FALLTHRU;
 
-             jump_insn = emit_jump_to_block_after (e_fall->dest, bb->end);
+             jump_insn = emit_jump_to_block_after (e_fall->dest, bb_end_insn);
              bb->end = jump_insn;
              barrier_insn = emit_barrier_after (jump_insn);
              RBI (bb)->eff_end = barrier_insn;
@@ -664,15 +676,15 @@ fixup_reorder_chain ()
       /* We got here if we need to add a new jump insn in a new block
         across the edge e_fall.  */
 
-      jump_insn = emit_jump_to_block_after (e_fall->dest, bb->end);
+      jump_insn = emit_jump_to_block_after (e_fall->dest, bb_end_insn);
       barrier_insn = emit_barrier_after (jump_insn);
 
       VARRAY_GROW (basic_block_info, ++n_basic_blocks);
       create_basic_block (n_basic_blocks - 1, jump_insn, jump_insn, NULL);
 
       nb = BASIC_BLOCK (n_basic_blocks - 1);
-      nb->global_live_at_start = OBSTACK_ALLOC_REG_SET (function_obstack);
-      nb->global_live_at_end = OBSTACK_ALLOC_REG_SET (function_obstack);
+      nb->global_live_at_start = OBSTACK_ALLOC_REG_SET (&flow_obstack);
+      nb->global_live_at_end = OBSTACK_ALLOC_REG_SET (&flow_obstack);
       nb->local_set = 0;
 
       COPY_REG_SET (nb->global_live_at_start, bb->global_live_at_start);
@@ -777,8 +789,7 @@ get_next_bb_note (x)
 {
   while (x)
     {
-      if (GET_CODE (x) == NOTE
-         && NOTE_LINE_NUMBER (x) == NOTE_INSN_BASIC_BLOCK)
+      if (NOTE_INSN_BASIC_BLOCK_P (x))
        return x;
       x = NEXT_INSN (x);
     }
@@ -792,8 +803,7 @@ get_prev_bb_note (x)
 {
   while (x)
     {
-      if (GET_CODE (x) == NOTE
-         && NOTE_LINE_NUMBER (x) == NOTE_INSN_BASIC_BLOCK)
+      if (NOTE_INSN_BASIC_BLOCK_P (x))
        return x;
       x = PREV_INSN (x);
     }
@@ -964,7 +974,7 @@ build_scope_forest (forest)
   rtx x;
   int level, bbi, i;
   basic_block curr_bb;
-  scope root, curr_scope;
+  scope root, curr_scope = 0;
 
   forest->num_trees = 0;
   forest->trees = NULL;
@@ -1050,8 +1060,7 @@ remove_scope_notes ()
   for (x = get_insns (); x; x = next)
     {
       next = NEXT_INSN (x);
-      if (GET_CODE (x) == NOTE
-         && NOTE_LINE_NUMBER (x) == NOTE_INSN_BASIC_BLOCK)
+      if (NOTE_INSN_BASIC_BLOCK_P (x))
        currbb = NOTE_BASIC_BLOCK (x);
 
       if (GET_CODE (x) == NOTE
@@ -1318,7 +1327,7 @@ dump_scope_forest_1 (s, indent)
 
   fprintf (stderr, "%*s", indent, "");
   fprintf (stderr, "{ level %d (block %p)\n", s->level,
-          NOTE_BLOCK (s->note_beg));
+          (PTR) NOTE_BLOCK (s->note_beg));
 
   fprintf (stderr, "%*s%s", indent, "", "bbs:");
   for (i = 0; i < s->num_bbs; i++)
@@ -1344,18 +1353,11 @@ reorder_basic_blocks ()
   if (n_basic_blocks <= 1)
     return;
 
-  /* We do not currently handle correct re-placement of EH notes.  */
-  for (i = 0; i < n_basic_blocks; i++)
-    {
-      edge e;
-      for (e = BASIC_BLOCK (i)->succ; e ; e = e->succ_next)
-        if (e->flags & EDGE_EH)
-         return;
-    }
-
   for (i = 0; i < n_basic_blocks; i++)
     BASIC_BLOCK (i)->aux = xcalloc (1, sizeof (struct reorder_block_def));
 
+  EXIT_BLOCK_PTR->aux = xcalloc (1, sizeof (struct reorder_block_def));
+
   build_scope_forest (&forest);
   remove_scope_notes ();
 
@@ -1374,6 +1376,8 @@ reorder_basic_blocks ()
   for (i = 0; i < n_basic_blocks; i++)
     free (BASIC_BLOCK (i)->aux);
 
+  free (EXIT_BLOCK_PTR->aux);
+
 #ifdef ENABLE_CHECKING
   verify_flow_info ();
 #endif