OSDN Git Service

Fix another mips typo.
[pf3gnuchains/gcc-fork.git] / gcc / bb-reorder.c
index 2d72807..32234b1 100644 (file)
@@ -197,8 +197,10 @@ push_to_next_round_p (basic_block bb, int round, int number_of_rounds,
   bool there_exists_another_round;
   bool cold_block;
   bool block_not_hot_enough;
+  bool next_round_is_last;
 
   there_exists_another_round = round < number_of_rounds - 1;
+  next_round_is_last = round + 1 == number_of_rounds - 1;
 
   cold_block = (flag_reorder_blocks_and_partition 
                && bb->partition == COLD_PARTITION);
@@ -207,7 +209,11 @@ push_to_next_round_p (basic_block bb, int round, int number_of_rounds,
                          || bb->count < count_th
                          || probably_never_executed_bb_p (bb));
 
-  if (there_exists_another_round
+  if (flag_reorder_blocks_and_partition
+      && next_round_is_last
+      && bb->partition != COLD_PARTITION)
+    return false;
+  else if (there_exists_another_round
       && (cold_block || block_not_hot_enough))
     return true;
   else 
@@ -383,7 +389,9 @@ rotate_loop (edge back_edge, struct trace *trace, int trace_n)
 
              /* Duplicate HEADER if it is a small block containing cond jump
                 in the end.  */
-             if (any_condjump_p (BB_END (header)) && copy_bb_p (header, 0))
+             if (any_condjump_p (BB_END (header)) && copy_bb_p (header, 0)
+                 && !find_reg_note (BB_END (header), REG_CROSSING_JUMP, 
+                                    NULL_RTX))
                {
                  copy_bb (header, prev_bb->succ, prev_bb, trace_n);
                }
@@ -749,7 +757,9 @@ copy_bb (basic_block old_bb, edge e, basic_block bb, int trace)
 {
   basic_block new_bb;
 
-  new_bb = cfg_layout_duplicate_bb (old_bb, e);
+  new_bb = duplicate_block (old_bb, e);
+  new_bb->partition = old_bb->partition;
+
   if (e->dest != new_bb)
     abort ();
   if (e->dest->rbi->visited)
@@ -901,7 +911,7 @@ connect_traces (int n_traces, struct trace *traces)
   last_trace = -1;
 
   /* If we are partitioning hot/cold basic blocks, mark the cold
-     traces as already connnected, to remove them from consideration
+     traces as already connected, to remove them from consideration
      for connection to the hot traces.  After the hot traces have all
      been connected (determined by "unconnected_hot_trace_count"), we
      will go back and connect the cold traces.  */
@@ -1159,6 +1169,7 @@ connect_traces (int n_traces, struct trace *traces)
     }
 
   FREE (connected);
+  FREE (cold_traces);
 }
 
 /* Return true when BB can and should be copied. CODE_MAY_GROW is true
@@ -1177,7 +1188,7 @@ copy_bb_p (basic_block bb, int code_may_grow)
     return false;
   if (!bb->pred || !bb->pred->pred_next)
     return false;
-  if (!cfg_layout_can_duplicate_bb_p (bb))
+  if (!can_duplicate_block_p (bb))
     return false;
 
   /* Avoid duplicating blocks which have many successors (PR/13430).  */
@@ -1235,6 +1246,8 @@ add_unlikely_executed_notes (void)
 {
   basic_block bb;
 
+  /* Add the UNLIKELY_EXECUTED_NOTES to each cold basic block.  */
+
   FOR_EACH_BB (bb)
     if (bb->partition == COLD_PARTITION)
       mark_bb_for_unlikely_executed_section (bb);
@@ -1250,6 +1263,7 @@ 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;
 
@@ -1260,32 +1274,49 @@ find_rarely_executed_basic_blocks_and_crossing_edges (edge *crossing_edges,
       if (probably_never_executed_bb_p (bb))
        bb->partition = COLD_PARTITION;
       else
-       bb->partition = HOT_PARTITION;
+       {
+         bb->partition = HOT_PARTITION;
+         has_hot_blocks = true;
+       }
     }
 
+  /* Since all "hot" basic blocks will eventually be scheduled before all
+     cold basic blocks, make *sure* the real function entry block is in
+     the hot partition (if there is one).  */
+  
+  if (has_hot_blocks)
+    for (e = ENTRY_BLOCK_PTR->succ; e; e = e->succ_next)
+      if (e->dest->index >= 0)
+       {
+         e->dest->partition = HOT_PARTITION;
+         break;
+       }
+
   /* Mark every edge that crosses between sections.  */
 
   i = 0;
-  FOR_EACH_BB (bb)
-    for (e = bb->succ; e; e = e->succ_next)
-      {
-       if (e->src != ENTRY_BLOCK_PTR
-           && e->dest != EXIT_BLOCK_PTR
-           && e->src->partition != e->dest->partition)
+  if (targetm.have_named_sections)
+    {
+      FOR_EACH_BB (bb)
+       for (e = bb->succ; e; e = e->succ_next)
          {
-           e->crossing_edge = true;
-           if (i == *max_idx)
+           if (e->src != ENTRY_BLOCK_PTR
+               && e->dest != EXIT_BLOCK_PTR
+               && e->src->partition != e->dest->partition)
              {
-               *max_idx *= 2;
-               crossing_edges = xrealloc (crossing_edges,
-                                          (*max_idx) * sizeof (edge));
+               e->crossing_edge = true;
+               if (i == *max_idx)
+                 {
+                   *max_idx *= 2;
+                   crossing_edges = xrealloc (crossing_edges,
+                                              (*max_idx) * sizeof (edge));
+                 }
+               crossing_edges[i++] = e;
              }
-           crossing_edges[i++] = e;
+           else
+             e->crossing_edge = false;
          }
-       else
-         e->crossing_edge = false;
-      }
-
+    }
   *n_crossing_edges = i;
 }
 
@@ -1300,37 +1331,33 @@ mark_bb_for_unlikely_executed_section (basic_block bb)
   rtx insert_insn = NULL;
   rtx new_note;
   
-  /* Find first non-note instruction and insert new NOTE before it (as
-     long as new NOTE is not first instruction in basic block).  */
-  
-  for (cur_insn = BB_HEAD (bb); cur_insn != NEXT_INSN (BB_END (bb)); 
+  /* Insert new NOTE immediately after  BASIC_BLOCK note.  */
+
+  for (cur_insn = BB_HEAD (bb); cur_insn != NEXT_INSN (BB_END (bb));
        cur_insn = NEXT_INSN (cur_insn))
-    if (GET_CODE (cur_insn) != NOTE
-       && GET_CODE (cur_insn) != CODE_LABEL)
+    if (GET_CODE (cur_insn) == NOTE
+       && NOTE_LINE_NUMBER (cur_insn) == NOTE_INSN_BASIC_BLOCK)
       {
        insert_insn = cur_insn;
        break;
       }
-  
+    
+  /* If basic block does not contain a NOTE_INSN_BASIC_BLOCK, there is
+     a major problem.  */
+
+  if (!insert_insn)
+    abort ();
+
   /* Insert note and assign basic block number to it.  */
   
-  if (insert_insn) 
-    {
-      new_note = emit_note_before (NOTE_INSN_UNLIKELY_EXECUTED_CODE, 
-                                  insert_insn);
-      NOTE_BASIC_BLOCK (new_note) = bb;
-    }
-  else
-    {
-      new_note = emit_note_after (NOTE_INSN_UNLIKELY_EXECUTED_CODE,
-                                 BB_END (bb));
-      NOTE_BASIC_BLOCK (new_note) = bb;
-    }
+  new_note = emit_note_after (NOTE_INSN_UNLIKELY_EXECUTED_CODE, 
+                             insert_insn);
+  NOTE_BASIC_BLOCK (new_note) = bb;
 }
 
 /* If any destination of a crossing edge does not have a label, add label;
    Convert any fall-through crossing edges (for blocks that do not contain
-   a jump) to unconditional jumps.   */
+   a jump) to unconditional jumps.  */
 
 static void 
 add_labels_and_missing_jumps (edge *crossing_edges, int n_crossing_edges)
@@ -1359,7 +1386,7 @@ add_labels_and_missing_jumps (edge *crossing_edges, int n_crossing_edges)
              
              if (src && (src != ENTRY_BLOCK_PTR)) 
                {
-                 if (GET_CODE (BB_END (src)) != JUMP_INSN)
+                 if (!JUMP_P (BB_END (src)))
                    /* bb just falls through.  */
                    {
                      /* make sure there's only one successor */
@@ -1409,7 +1436,7 @@ fix_up_fall_thru_edges (void)
   edge succ1;
   edge succ2;
   edge fall_thru;
-  edge cond_jump;
+  edge cond_jump = NULL;
   edge e;
   bool cond_jump_crosses;
   int invert_worked;
@@ -1471,7 +1498,7 @@ fix_up_fall_thru_edges (void)
                      && cur_bb->rbi->next == cond_jump->dest)
                    {
                      /* Find label in fall_thru block. We've already added
-                        any missing labels, so there must be one. */
+                        any missing labels, so there must be one.  */
                      
                      fall_thru_label = block_label (fall_thru->dest);
 
@@ -1553,16 +1580,16 @@ find_jump_block (basic_block jump_dest)
        
        /* Check each predecessor to see if it has a label, and contains
           only one executable instruction, which is an unconditional jump.
-          If so, we can use it.   */
+          If so, we can use it.  */
        
-       if (GET_CODE (BB_HEAD (src)) == CODE_LABEL)
+       if (LABEL_P (BB_HEAD (src)))
          for (insn = BB_HEAD (src); 
               !INSN_P (insn) && insn != NEXT_INSN (BB_END (src));
               insn = NEXT_INSN (insn))
            {
              if (INSN_P (insn)
                  && insn == BB_END (src)
-                 && GET_CODE (insn) == JUMP_INSN
+                 && JUMP_P (insn)
                  && !any_condjump_p (insn))
                {
                  source_bb = src;
@@ -1753,7 +1780,7 @@ fix_crossing_unconditional_branches (void)
   rtx new_reg;
   rtx cur_insn;
   edge succ;
-  
+
   FOR_EACH_BB (cur_bb)
     {
       last_insn = BB_END (cur_bb);
@@ -1762,7 +1789,7 @@ fix_crossing_unconditional_branches (void)
       /* Check to see if bb ends in a crossing (unconditional) jump.  At
          this point, no crossing jumps should be conditional.  */
 
-      if (GET_CODE (last_insn) == JUMP_INSN
+      if (JUMP_P (last_insn)
          && succ->crossing_edge)
        {
          rtx label2, table;
@@ -1802,7 +1829,7 @@ fix_crossing_unconditional_branches (void)
                   cur_insn = NEXT_INSN (cur_insn))
                {
                  BLOCK_FOR_INSN (cur_insn) = cur_bb;
-                 if (GET_CODE (cur_insn) == JUMP_INSN)
+                 if (JUMP_P (cur_insn))
                    jump_insn = cur_insn;
                }
              
@@ -1832,7 +1859,7 @@ add_reg_crossing_jump_notes (void)
   FOR_EACH_BB (bb)
     for (e = bb->succ; e; e = e->succ_next)
       if (e->crossing_edge
-         && GET_CODE (BB_END (e->src)) == JUMP_INSN)
+         && JUMP_P (BB_END (e->src)))
        REG_NOTES (BB_END (e->src)) = gen_rtx_EXPR_LIST (REG_CROSSING_JUMP, 
                                                         NULL_RTX, 
                                                         REG_NOTES (BB_END 
@@ -1885,32 +1912,43 @@ fix_edges_for_rarely_executed_code (edge *crossing_edges,
   
   fix_up_fall_thru_edges ();
   
-  /* If the architecture does not have conditional branches that can
-     span all of memory, convert crossing conditional branches into
-     crossing unconditional branches.  */
-  
-  if (!HAS_LONG_COND_BRANCH)
-    fix_crossing_conditional_branches ();
+  /* Only do the parts necessary for writing separate sections if
+     the target architecture has the ability to write separate sections
+     (i.e. it has named sections).  Otherwise, the hot/cold partitioning
+     information will be used when reordering blocks to try to put all
+     the hot blocks together, then all the cold blocks, but no actual
+     section partitioning will be done.  */
+
+  if (targetm.have_named_sections)
+    {
+      /* If the architecture does not have conditional branches that can
+        span all of memory, convert crossing conditional branches into
+        crossing unconditional branches.  */
   
-  /* If the architecture does not have unconditional branches that
-     can span all of memory, convert crossing unconditional branches
-     into indirect jumps.  Since adding an indirect jump also adds
-     a new register usage, update the register usage information as
-     well.  */
+      if (!HAS_LONG_COND_BRANCH)
+       fix_crossing_conditional_branches ();
   
-  if (!HAS_LONG_UNCOND_BRANCH)
-    {
-      fix_crossing_unconditional_branches ();
-      reg_scan (get_insns(), max_reg_num (), 1);
-    }
+      /* If the architecture does not have unconditional branches that
+        can span all of memory, convert crossing unconditional branches
+        into indirect jumps.  Since adding an indirect jump also adds
+        a new register usage, update the register usage information as
+        well.  */
+      
+      if (!HAS_LONG_UNCOND_BRANCH)
+       {
+         fix_crossing_unconditional_branches ();
+         reg_scan (get_insns(), max_reg_num (), 1);
+       }
 
-  add_reg_crossing_jump_notes ();
+      add_reg_crossing_jump_notes ();
+    }
 }
 
-/* Reorder basic blocks.  The main entry point to this file.  */
+/* Reorder basic blocks.  The main entry point to this file.  FLAGS is
+   the set of flags to pass to cfg_layout_initialize().  */
 
 void
-reorder_basic_blocks (void)
+reorder_basic_blocks (unsigned int flags)
 {
   int n_traces;
   int i;
@@ -1924,7 +1962,7 @@ reorder_basic_blocks (void)
 
   timevar_push (TV_REORDER_BLOCKS);
 
-  cfg_layout_initialize ();
+  cfg_layout_initialize (flags);
 
   set_edge_can_fallthru_flag ();
   mark_dfs_back_edges ();
@@ -1955,7 +1993,8 @@ reorder_basic_blocks (void)
   if (dump_file)
     dump_flow_info (dump_file);
 
-  if (flag_reorder_blocks_and_partition)
+  if (flag_reorder_blocks_and_partition
+      && targetm.have_named_sections)
     add_unlikely_executed_notes ();
 
   cfg_layout_finalize ();
@@ -1998,7 +2037,7 @@ partition_hot_cold_basic_blocks (void)
   
   crossing_edges = xcalloc (max_edges, sizeof (edge));
 
-  cfg_layout_initialize ();
+  cfg_layout_initialize (0);
   
   FOR_EACH_BB (cur_bb)
     if (cur_bb->index >= 0