OSDN Git Service

* Makefile.am (gfor_helper_src): Split selected_kind.f90.
[pf3gnuchains/gcc-fork.git] / gcc / cfgcleanup.c
index 3cde9b2..91412cf 100644 (file)
@@ -19,7 +19,7 @@ along with GCC; see the file COPYING.  If not, write to the Free
 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 02111-1307, USA.  */
 
-/* This file contains optimizer of the control flow.  The main entrypoint is
+/* This file contains optimizer of the control flow.  The main entry point is
    cleanup_cfg.  Following optimizations are performed:
 
    - Unreachable blocks removal
@@ -49,7 +49,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "tm_p.h"
 #include "target.h"
 #include "regs.h"
-#include "expr.h"
+#include "cfglayout.h"
+#include "emit-rtl.h"
 
 /* cleanup_cfg maintains following flags for each basic block.  */
 
@@ -77,7 +78,6 @@ static bool outgoing_edges_match (int, basic_block, basic_block);
 static int flow_find_cross_jump (int, basic_block, basic_block, rtx *, rtx *);
 static bool insns_match_p (int, rtx, rtx);
 
-static bool tail_recursion_label_p (rtx);
 static void merge_blocks_move_predecessor_nojumps (basic_block, basic_block);
 static void merge_blocks_move_successor_nojumps (basic_block, basic_block);
 static bool try_optimize_cfg (int);
@@ -122,8 +122,6 @@ try_simplify_condjump (basic_block cbranch_block)
   basic_block jump_block, jump_dest_block, cbranch_dest_block;
   edge cbranch_jump_edge, cbranch_fallthru_edge;
   rtx cbranch_insn;
-  rtx insn, next;
-  rtx end;
 
   /* Verify that there are exactly two successors.  */
   if (!cbranch_block->succ
@@ -150,11 +148,27 @@ try_simplify_condjump (basic_block cbranch_block)
     return false;
   jump_dest_block = jump_block->succ->dest;
 
+  /* If we are partitioning hot/cold basic blocks, we don't want to
+     mess up unconditional or indirect jumps that cross between hot
+     and cold sections. 
+
+     Basic block partitioning may result in some jumps that appear to
+     be optimizable (or blocks that appear to be mergeable), but which really 
+     must be left untouched (they are required to make it safely across 
+     partition boundaries).  See the comments at the top of 
+     bb-reorder.c:partition_hot_cold_basic_blocks for complete details.  */
+
+  if (flag_reorder_blocks_and_partition
+      && (BB_PARTITION (jump_block) != BB_PARTITION (jump_dest_block)
+         || (cbranch_jump_edge->flags & EDGE_CROSSING)))
+    return false;
+
   /* The conditional branch must target the block after the
      unconditional branch.  */
   cbranch_dest_block = cbranch_jump_edge->dest;
 
-  if (!can_fallthru (jump_block, cbranch_dest_block))
+  if (cbranch_dest_block == EXIT_BLOCK_PTR
+      || !can_fallthru (jump_block, cbranch_dest_block))
     return false;
 
   /* Invert the conditional branch.  */
@@ -176,29 +190,10 @@ try_simplify_condjump (basic_block cbranch_block)
   cbranch_fallthru_edge->flags &= ~EDGE_FALLTHRU;
   update_br_prob_note (cbranch_block);
 
-  end = BB_END (jump_block);
-  /* Deleting a block may produce unreachable code warning even when we are
-     not deleting anything live.  Suppress it by moving all the line number
-     notes out of the block.  */
-  for (insn = BB_HEAD (jump_block); insn != NEXT_INSN (BB_END (jump_block));
-       insn = next)
-    {
-      next = NEXT_INSN (insn);
-      if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) > 0)
-       {
-         if (insn == BB_END (jump_block))
-           {
-             BB_END (jump_block) = PREV_INSN (insn);
-             if (insn == end)
-               break;
-           }
-         reorder_insns_nobb (insn, insn, end);
-         end = insn;
-       }
-    }
   /* Delete the block with the unconditional jump, and clean up the mess.  */
   delete_basic_block (jump_block);
   tidy_fallthru_edge (cbranch_jump_edge);
+  update_forwarder_flag (cbranch_block);
 
   return true;
 }
@@ -428,6 +423,20 @@ try_forward_edges (int mode, basic_block b)
   bool changed = false;
   edge e, next, *threaded_edges = NULL;
 
+  /* If we are partitioning hot/cold basic blocks, we don't want to
+     mess up unconditional or indirect jumps that cross between hot
+     and cold sections. 
+  
+     Basic block partitioning may result in some jumps that appear to
+     be optimizable (or blocks that appear to be mergeable), but which really m
+     ust be left untouched (they are required to make it safely across 
+     partition boundaries).  See the comments at the top of 
+     bb-reorder.c:partition_hot_cold_basic_blocks for complete details.  */
+
+  if (flag_reorder_blocks_and_partition
+      && find_reg_note (BB_END (b), REG_CROSSING_JUMP, NULL_RTX))
+    return false;
+
   for (e = b->succ; e; e = next)
     {
       basic_block target, first;
@@ -449,6 +458,21 @@ try_forward_edges (int mode, basic_block b)
       target = first = e->dest;
       counter = 0;
 
+      /* If we are partitioning hot/cold basic_blocks, we don't want to mess
+        up jumps that cross between hot/cold sections.
+
+        Basic block partitioning may result in some jumps that appear
+        to be optimizable (or blocks that appear to be mergeable), but which 
+        really must be left untouched (they are required to make it safely 
+        across partition boundaries).  See the comments at the top of
+        bb-reorder.c:partition_hot_cold_basic_blocks for complete
+        details.  */
+
+      if (flag_reorder_blocks_and_partition
+         && first != EXIT_BLOCK_PTR
+         && find_reg_note (BB_END (first), REG_CROSSING_JUMP, NULL_RTX))
+       return false;
+
       while (counter < n_basic_blocks)
        {
          basic_block new_target = NULL;
@@ -456,6 +480,7 @@ try_forward_edges (int mode, basic_block b)
          may_thread |= target->flags & BB_DIRTY;
 
          if (FORWARDER_BLOCK_P (target)
+             && !(target->succ->flags & EDGE_CROSSING)
              && target->succ->dest != EXIT_BLOCK_PTR)
            {
              /* Bypass trivial infinite loops.  */
@@ -517,16 +542,16 @@ try_forward_edges (int mode, basic_block b)
              rtx insn = (target->succ->flags & EDGE_FALLTHRU
                          ? BB_HEAD (target) : prev_nonnote_insn (BB_END (target)));
 
-             if (GET_CODE (insn) != NOTE)
+             if (!NOTE_P (insn))
                insn = NEXT_INSN (insn);
 
-             for (; insn && GET_CODE (insn) != CODE_LABEL && !INSN_P (insn);
+             for (; insn && !LABEL_P (insn) && !INSN_P (insn);
                   insn = NEXT_INSN (insn))
-               if (GET_CODE (insn) == NOTE
+               if (NOTE_P (insn)
                    && NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG)
                  break;
 
-             if (GET_CODE (insn) == NOTE)
+             if (NOTE_P (insn))
                break;
 
              /* Do not clean up branches to just past the end of a loop
@@ -534,7 +559,7 @@ try_forward_edges (int mode, basic_block b)
                 recognition of some patterns.  */
 
              insn = PREV_INSN (BB_HEAD (target));
-             if (insn && GET_CODE (insn) == NOTE
+             if (insn && NOTE_P (insn)
                    && NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END)
                break;
            }
@@ -652,19 +677,6 @@ try_forward_edges (int mode, basic_block b)
   return changed;
 }
 \f
-/* Return true if LABEL is used for tail recursion.  */
-
-static bool
-tail_recursion_label_p (rtx label)
-{
-  rtx x;
-
-  for (x = tail_recursion_label_list; x; x = XEXP (x, 1))
-    if (label == XEXP (x, 0))
-      return true;
-
-  return false;
-}
 
 /* Blocks A and B are to be merged into a single block.  A has no incoming
    fallthru edge, so it can be moved before B without adding or modifying
@@ -675,8 +687,23 @@ merge_blocks_move_predecessor_nojumps (basic_block a, basic_block b)
 {
   rtx barrier;
 
+  /* If we are partitioning hot/cold basic blocks, we don't want to
+     mess up unconditional or indirect jumps that cross between hot
+     and cold sections.
+  
+     Basic block partitioning may result in some jumps that appear to
+     be optimizable (or blocks that appear to be mergeable), but which really 
+     must be left untouched (they are required to make it safely across 
+     partition boundaries).  See the comments at the top of 
+     bb-reorder.c:partition_hot_cold_basic_blocks for complete details.  */
+
+  if (flag_reorder_blocks_and_partition
+      && (BB_PARTITION (a) != BB_PARTITION (b)
+         || find_reg_note (BB_END (a), REG_CROSSING_JUMP, NULL_RTX)))
+    return;
+
   barrier = next_nonnote_insn (BB_END (a));
-  if (GET_CODE (barrier) != BARRIER)
+  if (!BARRIER_P (barrier))
     abort ();
   delete_insn (barrier);
 
@@ -718,6 +745,21 @@ merge_blocks_move_successor_nojumps (basic_block a, basic_block b)
   rtx barrier, real_b_end;
   rtx label, table;
 
+  /* If we are partitioning hot/cold basic blocks, we don't want to
+     mess up unconditional or indirect jumps that cross between hot
+     and cold sections. 
+  
+     Basic block partitioning may result in some jumps that appear to
+     be optimizable (or blocks that appear to be mergeable), but which really 
+     must be left untouched (they are required to make it safely across 
+     partition boundaries).  See the comments at the top of 
+     bb-reorder.c:partition_hot_cold_basic_blocks for complete details.  */
+
+  if (flag_reorder_blocks_and_partition
+      && (find_reg_note (BB_END (a), REG_CROSSING_JUMP, NULL_RTX)
+         || BB_PARTITION (a) != BB_PARTITION (b)))
+    return;
+
   real_b_end = BB_END (b);
 
   /* If there is a jump table following block B temporarily add the jump table
@@ -730,7 +772,7 @@ merge_blocks_move_successor_nojumps (basic_block a, basic_block b)
 
   /* There had better have been a barrier there.  Delete it.  */
   barrier = NEXT_INSN (BB_END (b));
-  if (barrier && GET_CODE (barrier) == BARRIER)
+  if (barrier && BARRIER_P (barrier))
     delete_insn (barrier);
 
   /* Move block and loop notes out of the chain so that we do not
@@ -773,14 +815,24 @@ static basic_block
 merge_blocks_move (edge e, basic_block b, basic_block c, int mode)
 {
   basic_block next;
-  /* If C has a tail recursion label, do not merge.  There is no
-     edge recorded from the call_placeholder back to this label, as
-     that would make optimize_sibling_and_tail_recursive_calls more
-     complex for no gain.  */
-  if ((mode & CLEANUP_PRE_SIBCALL)
-      && GET_CODE (BB_HEAD (c)) == CODE_LABEL
-      && tail_recursion_label_p (BB_HEAD (c)))
+
+  /* If we are partitioning hot/cold basic blocks, we don't want to
+     mess up unconditional or indirect jumps that cross between hot
+     and cold sections. 
+  
+     Basic block partitioning may result in some jumps that appear to
+     be optimizable (or blocks that appear to be mergeable), but which really 
+     must be left untouched (they are required to make it safely across 
+     partition boundaries).  See the comments at the top of 
+     bb-reorder.c:partition_hot_cold_basic_blocks for complete details.  */
+
+  if (flag_reorder_blocks_and_partition
+      && (find_reg_note (BB_END (b), REG_CROSSING_JUMP, NULL_RTX)
+         || find_reg_note (BB_END (c), REG_CROSSING_JUMP, NULL_RTX)
+         || BB_PARTITION (b) != BB_PARTITION (c)))
     return NULL;
+      
+    
 
   /* If B has a fallthru edge to C, no need to move anything.  */
   if (e->flags & EDGE_FALLTHRU)
@@ -973,7 +1025,7 @@ insns_match_p (int mode ATTRIBUTE_UNUSED, rtx i1, rtx i2)
      ??? We take the simple route for now and assume that if they're
      equal, they were constructed identically.  */
 
-  if (GET_CODE (i1) == CALL_INSN
+  if (CALL_P (i1)
       && (!rtx_equal_p (CALL_INSN_FUNCTION_USAGE (i1),
                        CALL_INSN_FUNCTION_USAGE (i2))
          || SIBLING_CALL_P (i1) != SIBLING_CALL_P (i2)))
@@ -1151,13 +1203,13 @@ flow_find_cross_jump (int mode ATTRIBUTE_UNUSED, basic_block bb1,
       while (last1 != BB_HEAD (bb1) && !INSN_P (PREV_INSN (last1)))
        last1 = PREV_INSN (last1);
 
-      if (last1 != BB_HEAD (bb1) && GET_CODE (PREV_INSN (last1)) == CODE_LABEL)
+      if (last1 != BB_HEAD (bb1) && LABEL_P (PREV_INSN (last1)))
        last1 = PREV_INSN (last1);
 
       while (last2 != BB_HEAD (bb2) && !INSN_P (PREV_INSN (last2)))
        last2 = PREV_INSN (last2);
 
-      if (last2 != BB_HEAD (bb2) && GET_CODE (PREV_INSN (last2)) == CODE_LABEL)
+      if (last2 != BB_HEAD (bb2) && LABEL_P (PREV_INSN (last2)))
        last2 = PREV_INSN (last2);
 
       *f1 = last1;
@@ -1184,10 +1236,10 @@ outgoing_edges_match (int mode, basic_block bb1, basic_block bb2)
      unconditional jump, or a fake edge to exit.  */
   if (bb1->succ && !bb1->succ->succ_next
       && (bb1->succ->flags & (EDGE_COMPLEX | EDGE_FAKE)) == 0
-      && (GET_CODE (BB_END (bb1)) != JUMP_INSN || simplejump_p (BB_END (bb1))))
+      && (!JUMP_P (BB_END (bb1)) || simplejump_p (BB_END (bb1))))
     return (bb2->succ &&  !bb2->succ->succ_next
            && (bb2->succ->flags & (EDGE_COMPLEX | EDGE_FAKE)) == 0
-           && (GET_CODE (BB_END (bb2)) != JUMP_INSN || simplejump_p (BB_END (bb2))));
+           && (!JUMP_P (BB_END (bb2)) || simplejump_p (BB_END (bb2))));
 
   /* Match conditional jumps - this may get tricky when fallthru and branch
      edges are crossed.  */
@@ -1320,7 +1372,7 @@ outgoing_edges_match (int mode, basic_block bb1, basic_block bb2)
          /* The labels should never be the same rtx.  If they really are same
             the jump tables are same too. So disable crossjumping of blocks BB1
             and BB2 because when deleting the common insns in the end of BB1
-            by delete_block () the jump table would be deleted too.  */
+            by delete_basic_block () the jump table would be deleted too.  */
          /* If LABEL2 is referenced in BB1->END do not do anything
             because we would loose information when replacing
             LABEL1 by LABEL2 and then LABEL2 by LABEL1 in BB1->END.  */
@@ -1453,6 +1505,20 @@ try_crossjump_to_edge (int mode, edge e1, edge e2)
   rtx newpos1, newpos2;
   edge s;
 
+  newpos1 = newpos2 = NULL_RTX;
+
+  /* If we have partitioned hot/cold basic blocks, it is a bad idea
+     to try this optimization. 
+
+     Basic block partitioning may result in some jumps that appear to
+     be optimizable (or blocks that appear to be mergeable), but which really 
+     must be left untouched (they are required to make it safely across 
+     partition boundaries).  See the comments at the top of 
+     bb-reorder.c:partition_hot_cold_basic_blocks for complete details.  */
+
+  if (flag_reorder_blocks_and_partition && no_new_pseudos)
+    return false;
+
   /* Search backward through forwarder blocks.  We don't need to worry
      about multiple entry or chained forwarders, as they will be optimized
      away.  We do this to look past the unconditional jump following a
@@ -1493,7 +1559,13 @@ try_crossjump_to_edge (int mode, edge e1, edge e2)
 
   /* ... and part the second.  */
   nmatch = flow_find_cross_jump (mode, src1, src2, &newpos1, &newpos2);
-  if (!nmatch)
+
+  /* Don't proceed with the crossjump unless we found a sufficient number
+     of matching instructions or the 'from' block was totally matched
+     (such that its predecessors will hopefully be redirected and the
+     block removed).  */
+  if ((nmatch < PARAM_VALUE (PARAM_MIN_CROSSJUMP_INSNS))
+      && (newpos1 != BB_HEAD (src1)))
     return false;
 
 #ifndef CASE_DROPS_THROUGH
@@ -1607,10 +1679,10 @@ try_crossjump_to_edge (int mode, edge e1, edge e2)
   /* Edit SRC1 to go to REDIRECT_TO at NEWPOS1.  */
 
   /* Skip possible basic block header.  */
-  if (GET_CODE (newpos1) == CODE_LABEL)
+  if (LABEL_P (newpos1))
     newpos1 = NEXT_INSN (newpos1);
 
-  if (GET_CODE (newpos1) == NOTE)
+  if (NOTE_P (newpos1))
     newpos1 = NEXT_INSN (newpos1);
 
   redirect_from = split_block (src1, PREV_INSN (newpos1))->src;
@@ -1639,6 +1711,21 @@ try_crossjump_bb (int mode, basic_block bb)
   if (!bb->pred || !bb->pred->pred_next)
     return false;
 
+  /* If we are partitioning hot/cold basic blocks, we don't want to
+     mess up unconditional or indirect jumps that cross between hot
+     and cold sections. 
+  
+     Basic block partitioning may result in some jumps that appear to
+     be optimizable (or blocks that appear to be mergeable), but which really 
+     must be left untouched (they are required to make it safely across 
+     partition boundaries).  See the comments at the top of 
+     bb-reorder.c:partition_hot_cold_basic_blocks for complete details.  */
+
+  if (flag_reorder_blocks_and_partition
+      && (BB_PARTITION (bb->pred->src) != BB_PARTITION (bb->pred->pred_next->src)
+         || (bb->pred->flags & EDGE_CROSSING)))
+    return false;
+
   /* It is always cheapest to redirect a block that ends in a branch to
      a block that falls through into BB, as that adds no branches to the
      program.  We'll try that combination first.  */
@@ -1751,7 +1838,7 @@ try_optimize_cfg (int mode)
   if (mode & (CLEANUP_UPDATE_LIFE | CLEANUP_CROSSJUMP | CLEANUP_THREADING))
     clear_bb_flags ();
 
-  if (! (* targetm.cannot_modify_jumps_p) ())
+  if (! targetm.cannot_modify_jumps_p ())
     {
       first_pass = true;
       /* Attempt to merge blocks as made possible by edge removal.  If
@@ -1787,15 +1874,11 @@ try_optimize_cfg (int mode)
                  b = c;
                }
 
-             /* Remove code labels no longer used.  Don't do this
-                before CALL_PLACEHOLDER is removed, as some branches
-                may be hidden within.  */
+             /* Remove code labels no longer used.  */
              if (b->pred->pred_next == NULL
                  && (b->pred->flags & EDGE_FALLTHRU)
                  && !(b->pred->flags & EDGE_COMPLEX)
-                 && GET_CODE (BB_HEAD (b)) == CODE_LABEL
-                 && (!(mode & CLEANUP_PRE_SIBCALL)
-                     || !tail_recursion_label_p (BB_HEAD (b)))
+                 && LABEL_P (BB_HEAD (b))
                  /* If the previous block ends with a branch to this
                     block, we can't delete the label.  Normally this
                     is a condjump that is yet to be simplified, but
@@ -1803,7 +1886,7 @@ try_optimize_cfg (int mode)
                     some element going to the same place as the
                     default (fallthru).  */
                  && (b->pred->src == ENTRY_BLOCK_PTR
-                     || GET_CODE (BB_END (b->pred->src)) != JUMP_INSN
+                     || !JUMP_P (BB_END (b->pred->src))
                      || ! label_is_jump_target_p (BB_HEAD (b),
                                                   BB_END (b->pred->src))))
                {
@@ -1828,7 +1911,7 @@ try_optimize_cfg (int mode)
              if (!(mode & CLEANUP_CFGLAYOUT)
                  && b->pred->pred_next == NULL
                  && (b->pred->flags & EDGE_FALLTHRU)
-                 && GET_CODE (BB_HEAD (b)) != CODE_LABEL
+                 && !LABEL_P (BB_HEAD (b))
                  && FORWARDER_BLOCK_P (b)
                  /* Note that forwarder_block_p true ensures that
                     there is a successor for this block.  */
@@ -1870,10 +1953,12 @@ try_optimize_cfg (int mode)
                  else if (!(mode & CLEANUP_CFGLAYOUT)
                           /* If the jump insn has side effects,
                              we can't kill the edge.  */
-                          && (GET_CODE (BB_END (b)) != JUMP_INSN
+                          && (!JUMP_P (BB_END (b))
                               || (reload_completed
                                   ? simplejump_p (BB_END (b))
-                                  : onlyjump_p (BB_END (b))))
+                                  : (onlyjump_p (BB_END (b))
+                                     && !tablejump_p (BB_END (b),
+                                                      NULL, NULL))))
                           && (next = merge_blocks_move (s, b, c, mode)))
                      {
                        b = next;
@@ -1895,6 +1980,7 @@ try_optimize_cfg (int mode)
                  && ! b->succ->succ_next
                  && b->succ->dest != EXIT_BLOCK_PTR
                  && onlyjump_p (BB_END (b))
+                 && !find_reg_note (BB_END (b), REG_CROSSING_JUMP, NULL_RTX)
                  && try_redirect_by_replacing_jump (b->succ, b->succ->dest,
                                                     (mode & CLEANUP_CFGLAYOUT) != 0))
                {
@@ -1935,7 +2021,7 @@ try_optimize_cfg (int mode)
     }
 
   if (mode & CLEANUP_CROSSJUMP)
-    remove_fake_edges ();
+    remove_fake_exit_edges ();
 
   clear_aux_for_blocks ();
 
@@ -1969,6 +2055,32 @@ delete_unreachable_blocks (void)
     tidy_fallthru_edges ();
   return changed;
 }
+
+/* Merges sequential blocks if possible.  */
+
+bool
+merge_seq_blocks (void)
+{
+  basic_block bb;
+  bool changed = false;
+
+  for (bb = ENTRY_BLOCK_PTR->next_bb; bb != EXIT_BLOCK_PTR; )
+    {
+      if (bb->succ
+         && !bb->succ->succ_next
+         && can_merge_blocks_p (bb, bb->succ->dest))
+       {
+         /* Merge the blocks and retry.  */
+         merge_blocks (bb, bb->succ->dest);
+         changed = true;
+         continue;
+       }
+
+      bb = bb->next_bb;
+    }
+
+  return changed;
+}
 \f
 /* Tidy the CFG by deleting unreachable code and whatnot.  */
 
@@ -1983,8 +2095,7 @@ cleanup_cfg (int mode)
       changed = true;
       /* We've possibly created trivially dead code.  Cleanup it right
         now to introduce more opportunities for try_optimize_cfg.  */
-      if (!(mode & (CLEANUP_NO_INSN_DEL
-                   | CLEANUP_UPDATE_LIFE | CLEANUP_PRE_SIBCALL))
+      if (!(mode & (CLEANUP_NO_INSN_DEL | CLEANUP_UPDATE_LIFE))
          && !reload_completed)
        delete_trivially_dead_insns (get_insns(), max_reg_num ());
     }
@@ -2007,7 +2118,7 @@ cleanup_cfg (int mode)
                                                    ? PROP_LOG_LINKS : 0)))
            break;
        }
-      else if (!(mode & (CLEANUP_NO_INSN_DEL | CLEANUP_PRE_SIBCALL))
+      else if (!(mode & CLEANUP_NO_INSN_DEL)
               && (mode & CLEANUP_EXPENSIVE)
               && !reload_completed)
        {