OSDN Git Service

2008-03-13 Jerry DeLisle <jvdelisle@gcc.gnu.org>
[pf3gnuchains/gcc-fork.git] / gcc / bb-reorder.c
index 9bf4086..18e9405 100644 (file)
@@ -1223,7 +1223,6 @@ find_rarely_executed_basic_blocks_and_crossing_edges (edge **crossing_edges,
                                                      int *max_idx)
 {
   basic_block bb;
-  bool has_hot_blocks = false;
   edge e;
   int i;
   edge_iterator ei;
@@ -1235,10 +1234,7 @@ find_rarely_executed_basic_blocks_and_crossing_edges (edge **crossing_edges,
       if (probably_never_executed_bb_p (bb))
        BB_SET_PARTITION (bb, BB_COLD_PARTITION);
       else
-       {
-         BB_SET_PARTITION (bb, BB_HOT_PARTITION);
-         has_hot_blocks = true;
-       }
+       BB_SET_PARTITION (bb, BB_HOT_PARTITION);
     }
 
   /* Mark every edge that crosses between sections.  */
@@ -1293,11 +1289,14 @@ add_labels_and_missing_jumps (edge *crossing_edges, int n_crossing_edges)
            {
              label = block_label (dest);
 
-             /* Make sure source block ends with a jump.  */
+             /* Make sure source block ends with a jump.  If the
+                source block does not end with a jump it might end
+                with a call_insn;  this case will be handled in
+                fix_up_fall_thru_edges function.  */
 
              if (src && (src != ENTRY_BLOCK_PTR))
                {
-                 if (!JUMP_P (BB_END (src)))
+                 if (!JUMP_P (BB_END (src)) && !block_ends_with_call_p (src))
                    /* bb just falls through.  */
                    {
                      /* make sure there's only one successor */
@@ -1322,13 +1321,13 @@ add_labels_and_missing_jumps (edge *crossing_edges, int n_crossing_edges)
 }
 
 /* Find any bb's where the fall-through edge is a crossing edge (note that
-   these bb's must also contain a conditional jump; we've already
-   dealt with fall-through edges for blocks that didn't have a
-   conditional jump in the call to add_labels_and_missing_jumps).
-   Convert the fall-through edge to non-crossing edge by inserting a
-   new bb to fall-through into.  The new bb will contain an
-   unconditional jump (crossing edge) to the original fall through
-   destination.  */
+   these bb's must also contain a conditional jump or end with a call
+   instruction; we've already dealt with fall-through edges for blocks
+   that didn't have a conditional jump or didn't end with call instruction
+   in the call to add_labels_and_missing_jumps).  Convert the fall-through
+   edge to non-crossing edge by inserting a new bb to fall-through into.
+   The new bb will contain an unconditional jump (crossing edge) to the
+   original fall through destination.  */
 
 static void
 fix_up_fall_thru_edges (void)
@@ -1373,6 +1372,19 @@ fix_up_fall_thru_edges (void)
          fall_thru = succ2;
          cond_jump = succ1;
        }
+      else if (!fall_thru && succ1 && block_ends_with_call_p (cur_bb))
+      {
+        edge e;
+        edge_iterator ei;
+
+        /* Find EDGE_CAN_FALLTHRU edge.  */
+        FOR_EACH_EDGE (e, ei, cur_bb->succs) 
+          if (e->flags & EDGE_CAN_FALLTHRU)
+          {
+            fall_thru = e;
+            break;
+          }
+      }
 
       if (fall_thru && (fall_thru->dest != EXIT_BLOCK_PTR))
        {
@@ -1430,8 +1442,14 @@ fix_up_fall_thru_edges (void)
                  /* This is the case where both edges out of the basic
                     block are crossing edges. Here we will fix up the
                     fall through edge. The jump edge will be taken care
-                    of later.  */
-
+                    of later.  The EDGE_CROSSING flag of fall_thru edge 
+                     is unset before the call to force_nonfallthru
+                     function because if a new basic-block is created
+                     this edge remains in the current section boundary
+                     while the edge between new_bb and the fall_thru->dest
+                     becomes EDGE_CROSSING.  */
+
+                  fall_thru->flags &= ~EDGE_CROSSING;
                  new_bb = force_nonfallthru (fall_thru);
 
                  if (new_bb)
@@ -1445,6 +1463,12 @@ fix_up_fall_thru_edges (void)
                      BB_COPY_PARTITION (new_bb, cur_bb);
                      single_succ_edge (new_bb)->flags |= EDGE_CROSSING;
                    }
+                  else
+                    {
+                      /* If a new basic-block was not created; restore
+                         the EDGE_CROSSING flag.  */
+                      fall_thru->flags |= EDGE_CROSSING;
+                    }
 
                  /* Add barrier after new jump */
 
@@ -1524,7 +1548,6 @@ fix_crossing_conditional_branches (void)
   basic_block new_bb;
   basic_block last_bb;
   basic_block dest;
-  basic_block prev_bb;
   edge succ1;
   edge succ2;
   edge crossing_edge;
@@ -1605,7 +1628,6 @@ fix_crossing_conditional_branches (void)
                  new_bb = create_basic_block (NULL, NULL, last_bb);
                  new_bb->aux = last_bb->aux;
                  last_bb->aux = new_bb;
-                 prev_bb = last_bb;
                  last_bb = new_bb;
                  /* Put appropriate instructions in new bb.  */
 
@@ -1947,6 +1969,9 @@ insert_section_boundary_note (void)
        {
          new_note = emit_note_before (NOTE_INSN_SWITCH_TEXT_SECTIONS,
                                       BB_HEAD (bb));
+         /* ??? This kind of note always lives between basic blocks,
+            but add_insn_before will set BLOCK_FOR_INSN anyway.  */
+         BLOCK_FOR_INSN (new_note) = NULL;
          break;
        }
     }
@@ -2084,7 +2109,7 @@ struct tree_opt_pass pass_duplicate_computed_gotos =
   0,                                    /* properties_provided */
   0,                                    /* properties_destroyed */
   0,                                    /* todo_flags_start */
-  TODO_dump_func,                       /* todo_flags_finish */
+  TODO_dump_func | TODO_verify_rtl_sharing,/* todo_flags_finish */
   0                                     /* letter */
 };
 
@@ -2198,19 +2223,12 @@ rest_of_handle_reorder_blocks (void)
      splitting possibly introduced more crossjumping opportunities.  */
   cfg_layout_initialize (CLEANUP_EXPENSIVE);
 
-  if (flag_sched2_use_traces && flag_schedule_insns_after_reload)
+  if (flag_reorder_blocks || flag_reorder_blocks_and_partition)
     {
-      timevar_push (TV_TRACER);
-      tracer ();
-      timevar_pop (TV_TRACER);
+      reorder_basic_blocks ();
+      cleanup_cfg (CLEANUP_EXPENSIVE);
     }
 
-  if (flag_reorder_blocks || flag_reorder_blocks_and_partition)
-    reorder_basic_blocks ();
-  if (flag_reorder_blocks || flag_reorder_blocks_and_partition
-      || (flag_sched2_use_traces && flag_schedule_insns_after_reload))
-    cleanup_cfg (CLEANUP_EXPENSIVE);
-
   FOR_EACH_BB (bb)
     if (bb->next_bb != EXIT_BLOCK_PTR)
       bb->aux = bb->next_bb;
@@ -2234,7 +2252,7 @@ struct tree_opt_pass pass_reorder_blocks =
   0,                                    /* properties_provided */
   0,                                    /* properties_destroyed */
   0,                                    /* todo_flags_start */
-  TODO_dump_func,                       /* todo_flags_finish */
+  TODO_dump_func | TODO_verify_rtl_sharing,/* todo_flags_finish */
   'B'                                   /* letter */
 };
 
@@ -2272,7 +2290,7 @@ struct tree_opt_pass pass_partition_blocks =
   0,                                    /* properties_provided */
   0,                                    /* properties_destroyed */
   0,                                    /* todo_flags_start */
-  TODO_dump_func,                       /* todo_flags_finish */
+  TODO_dump_func | TODO_verify_rtl_sharing,/* todo_flags_finish */
   0                                     /* letter */
 };