OSDN Git Service

PR middle-end/38505
[pf3gnuchains/gcc-fork.git] / gcc / bb-reorder.c
index 18e9405..b636c1e 100644 (file)
@@ -1,5 +1,5 @@
 /* Basic block reordering routines for the GNU compiler.
-   Copyright (C) 2000, 2002, 2003, 2004, 2005, 2006, 2007
+   Copyright (C) 2000, 2002, 2003, 2004, 2005, 2006, 2007, 2008
    Free Software Foundation, Inc.
 
    This file is part of GCC.
@@ -278,7 +278,7 @@ find_traces (int *n_traces, struct trace *traces)
          basic_block bb;
          fprintf (dump_file, "Trace %d (round %d):  ", i + 1,
                   traces[i].round + 1);
-         for (bb = traces[i].first; bb != traces[i].last; bb = bb->aux)
+         for (bb = traces[i].first; bb != traces[i].last; bb = (basic_block) bb->aux)
            fprintf (dump_file, "%d [%d] ", bb->index, bb->frequency);
          fprintf (dump_file, "%d [%d]\n", bb->index, bb->frequency);
        }
@@ -358,7 +358,7 @@ rotate_loop (edge back_edge, struct trace *trace, int trace_n)
                }
            }
        }
-      bb = bb->aux;
+      bb = (basic_block) bb->aux;
     }
   while (bb != back_edge->dest);
 
@@ -368,7 +368,7 @@ rotate_loop (edge back_edge, struct trace *trace, int trace_n)
         the trace.  */
       if (back_edge->dest == trace->first)
        {
-         trace->first = best_bb->aux;
+         trace->first = (basic_block) best_bb->aux;
        }
       else
        {
@@ -376,7 +376,7 @@ rotate_loop (edge back_edge, struct trace *trace, int trace_n)
 
          for (prev_bb = trace->first;
               prev_bb->aux != back_edge->dest;
-              prev_bb = prev_bb->aux)
+              prev_bb = (basic_block) prev_bb->aux)
            ;
          prev_bb->aux = best_bb->aux;
 
@@ -442,7 +442,7 @@ find_traces_1_round (int branch_th, int exec_th, gcov_type count_th,
       fibheapkey_t key;
       edge_iterator ei;
 
-      bb = fibheap_extract_min (*heap);
+      bb = (basic_block) fibheap_extract_min (*heap);
       bbd[bb->index].heap = NULL;
       bbd[bb->index].node = NULL;
 
@@ -648,7 +648,8 @@ find_traces_1_round (int branch_th, int exec_th, gcov_type count_th,
                          /* The loop has less than 4 iterations.  */
 
                          if (single_succ_p (bb)
-                             && copy_bb_p (best_edge->dest, !optimize_size))
+                             && copy_bb_p (best_edge->dest,
+                                           optimize_edge_for_speed_p (best_edge)))
                            {
                              bb = copy_bb (best_edge->dest, best_edge, bb,
                                            *n_traces);
@@ -780,7 +781,7 @@ copy_bb (basic_block old_bb, edge e, basic_block bb, int trace)
 
       new_size = MAX (last_basic_block, new_bb->index + 1);
       new_size = GET_ARRAY_SIZE (new_size);
-      bbd = xrealloc (bbd, new_size * sizeof (bbro_basic_block_data));
+      bbd = XRESIZEVEC (bbro_basic_block_data, bbd, new_size);
       for (i = array_size; i < new_size; i++)
        {
          bbd[i].start_of_trace = -1;
@@ -1102,7 +1103,7 @@ connect_traces (int n_traces, struct trace *traces)
                 edge is traversed frequently enough.  */
              if (try_copy
                  && copy_bb_p (best->dest,
-                               !optimize_size
+                               optimize_edge_for_speed_p (best)
                                && EDGE_FREQUENCY (best) >= freq_threshold
                                && best->count >= count_threshold))
                {
@@ -1143,7 +1144,7 @@ connect_traces (int n_traces, struct trace *traces)
       basic_block bb;
 
       fprintf (dump_file, "Final order:\n");
-      for (bb = traces[0].first; bb; bb = bb->aux)
+      for (bb = traces[0].first; bb; bb = (basic_block) bb->aux)
        fprintf (dump_file, "%d ", bb->index);
       fprintf (dump_file, "\n");
       fflush (dump_file);
@@ -1173,7 +1174,7 @@ copy_bb_p (const_basic_block bb, int code_may_grow)
   if (EDGE_COUNT (bb->succs) > 8)
     return false;
 
-  if (code_may_grow && maybe_hot_bb_p (bb))
+  if (code_may_grow && optimize_bb_for_speed_p (bb))
     max_size *= PARAM_VALUE (PARAM_MAX_GROW_COPY_BB_INSNS);
 
   FOR_BB_INSNS (bb, insn)
@@ -1251,8 +1252,7 @@ find_rarely_executed_basic_blocks_and_crossing_edges (edge **crossing_edges,
          if (i == *max_idx)
            {
              *max_idx *= 2;
-             *crossing_edges = xrealloc (*crossing_edges,
-                                        (*max_idx) * sizeof (edge));
+             *crossing_edges = XRESIZEVEC (edge, *crossing_edges, *max_idx);
            }
          (*crossing_edges)[i++] = e;
        }
@@ -1490,7 +1490,7 @@ fix_up_fall_thru_edges (void)
     }
 }
 
-/* This function checks the destination blockof a "crossing jump" to
+/* This function checks the destination block of a "crossing jump" to
    see if it has any crossing predecessors that begin with a code label
    and end with an unconditional jump.  If so, it returns that predecessor
    block.  (This is to avoid creating lots of new basic blocks that all
@@ -1786,10 +1786,7 @@ add_reg_crossing_jump_notes (void)
     FOR_EACH_EDGE (e, ei, bb->succs)
       if ((e->flags & EDGE_CROSSING)
          && 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
-                                                                 (e->src)));
+       add_reg_note (BB_END (e->src), REG_CROSSING_JUMP, NULL_RTX);
 }
 
 /* Hot and cold basic blocks are partitioned and put in separate
@@ -1988,7 +1985,7 @@ gate_duplicate_computed_gotos (void)
 {
   if (targetm.cannot_modify_jumps_p ())
     return false;
-  return (optimize > 0 && flag_expensive_optimizations && !optimize_size);
+  return (optimize > 0 && flag_expensive_optimizations);
 }
 
 
@@ -2079,6 +2076,9 @@ duplicate_computed_gotos (void)
          || single_pred_p (single_succ (bb)))
        continue;
 
+      if (!optimize_bb_for_size_p (bb))
+       continue;
+
       /* The successor block has to be a duplication candidate.  */
       if (!bitmap_bit_p (candidates, single_succ (bb)->index))
        continue;
@@ -2096,8 +2096,10 @@ done:
   return 0;
 }
 
-struct tree_opt_pass pass_duplicate_computed_gotos =
+struct rtl_opt_pass pass_duplicate_computed_gotos =
 {
+ {
+  RTL_PASS,
   "compgotos",                          /* name */
   gate_duplicate_computed_gotos,        /* gate */
   duplicate_computed_gotos,             /* execute */
@@ -2110,7 +2112,7 @@ struct tree_opt_pass pass_duplicate_computed_gotos =
   0,                                    /* properties_destroyed */
   0,                                    /* todo_flags_start */
   TODO_dump_func | TODO_verify_rtl_sharing,/* todo_flags_finish */
-  0                                     /* letter */
+ }
 };
 
 
@@ -2223,7 +2225,15 @@ rest_of_handle_reorder_blocks (void)
      splitting possibly introduced more crossjumping opportunities.  */
   cfg_layout_initialize (CLEANUP_EXPENSIVE);
 
-  if (flag_reorder_blocks || flag_reorder_blocks_and_partition)
+  if ((flag_reorder_blocks || flag_reorder_blocks_and_partition)
+      /* Don't reorder blocks when optimizing for size because extra jump insns may
+        be created; also barrier may create extra padding.
+
+        More correctly we should have a block reordering mode that tried to
+        minimize the combined size of all the jumps.  This would more or less
+        automatically remove extra jumps, but would also try to use more short
+        jumps instead of long jumps.  */
+      && optimize_function_for_speed_p (cfun))
     {
       reorder_basic_blocks ();
       cleanup_cfg (CLEANUP_EXPENSIVE);
@@ -2239,8 +2249,10 @@ rest_of_handle_reorder_blocks (void)
   return 0;
 }
 
-struct tree_opt_pass pass_reorder_blocks =
+struct rtl_opt_pass pass_reorder_blocks =
 {
+ {
+  RTL_PASS,
   "bbro",                               /* name */
   gate_handle_reorder_blocks,           /* gate */
   rest_of_handle_reorder_blocks,        /* execute */
@@ -2253,7 +2265,7 @@ struct tree_opt_pass pass_reorder_blocks =
   0,                                    /* properties_destroyed */
   0,                                    /* todo_flags_start */
   TODO_dump_func | TODO_verify_rtl_sharing,/* todo_flags_finish */
-  'B'                                   /* letter */
+ }
 };
 
 static bool
@@ -2277,8 +2289,10 @@ rest_of_handle_partition_blocks (void)
   return 0;
 }
 
-struct tree_opt_pass pass_partition_blocks =
+struct rtl_opt_pass pass_partition_blocks =
 {
+ {
+  RTL_PASS,
   "bbpart",                             /* name */
   gate_handle_partition_blocks,         /* gate */
   rest_of_handle_partition_blocks,      /* execute */
@@ -2290,8 +2304,8 @@ struct tree_opt_pass pass_partition_blocks =
   0,                                    /* properties_provided */
   0,                                    /* properties_destroyed */
   0,                                    /* todo_flags_start */
-  TODO_dump_func | TODO_verify_rtl_sharing,/* todo_flags_finish */
-  0                                     /* letter */
+  TODO_dump_func | TODO_verify_rtl_sharing/* todo_flags_finish */
+ }
 };