OSDN Git Service

gcc/ada/
[pf3gnuchains/gcc-fork.git] / gcc / final.c
index 8af31cc..654f847 100644 (file)
@@ -78,6 +78,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "df.h"
 #include "vecprim.h"
 #include "ggc.h"
+#include "cfgloop.h"
+#include "params.h"
 
 #ifdef XCOFF_DEBUGGING_INFO
 #include "xcoffout.h"          /* Needed for external data
@@ -673,6 +675,8 @@ compute_alignments (void)
 {
   int log, max_skip, max_log;
   basic_block bb;
+  int freq_max = 0;
+  int freq_threshold = 0;
 
   if (label_align)
     {
@@ -688,6 +692,19 @@ compute_alignments (void)
   if (! optimize || optimize_size)
     return 0;
 
+  if (dump_file)
+    {
+      dump_flow_info (dump_file, TDF_DETAILS);
+      flow_loops_dump (dump_file, NULL, 1);
+      loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
+    }
+  FOR_EACH_BB (bb)
+    if (bb->frequency > freq_max)
+      freq_max = bb->frequency;
+  freq_threshold = freq_max / PARAM_VALUE (PARAM_ALIGN_THRESHOLD);
+
+  if (dump_file)
+    fprintf(dump_file, "freq_max: %i\n",freq_max);
   FOR_EACH_BB (bb)
     {
       rtx label = BB_HEAD (bb);
@@ -697,7 +714,12 @@ compute_alignments (void)
 
       if (!LABEL_P (label)
          || probably_never_executed_bb_p (bb))
-       continue;
+       {
+         if (dump_file)
+           fprintf(dump_file, "BB %4i freq %4i loop %2i loop_depth %2i skipped.\n",
+                   bb->index, bb->frequency, bb->loop_father->num, bb->loop_depth);
+         continue;
+       }
       max_log = LABEL_ALIGN (label);
       max_skip = LABEL_ALIGN_MAX_SKIP;
 
@@ -708,6 +730,18 @@ compute_alignments (void)
          else
            branch_frequency += EDGE_FREQUENCY (e);
        }
+      if (dump_file)
+       {
+         fprintf(dump_file, "BB %4i freq %4i loop %2i loop_depth %2i fall %4i branch %4i",
+                 bb->index, bb->frequency, bb->loop_father->num,
+                 bb->loop_depth,
+                 fallthru_frequency, branch_frequency);
+         if (!bb->loop_father->inner && bb->loop_father->num)
+           fprintf (dump_file, " inner_loop");
+         if (bb->loop_father->header == bb)
+           fprintf (dump_file, " loop_header");
+         fprintf (dump_file, "\n");
+       }
 
       /* There are two purposes to align block with no fallthru incoming edge:
         1) to avoid fetch stalls when branch destination is near cache boundary
@@ -720,12 +754,14 @@ compute_alignments (void)
         when function is called.  */
 
       if (!has_fallthru
-         && (branch_frequency > BB_FREQ_MAX / 10
+         && (branch_frequency > freq_threshold
              || (bb->frequency > bb->prev_bb->frequency * 10
                  && (bb->prev_bb->frequency
                      <= ENTRY_BLOCK_PTR->frequency / 2))))
        {
          log = JUMP_ALIGN (label);
+         if (dump_file)
+           fprintf(dump_file, "  jump alignment added.\n");
          if (max_log < log)
            {
              max_log = log;
@@ -736,10 +772,13 @@ compute_alignments (void)
         align it.  It is most likely a first block of loop.  */
       if (has_fallthru
          && maybe_hot_bb_p (bb)
-         && branch_frequency + fallthru_frequency > BB_FREQ_MAX / 10
-         && branch_frequency > fallthru_frequency * 2)
+         && branch_frequency + fallthru_frequency > freq_threshold
+         && (branch_frequency
+             > fallthru_frequency * PARAM_VALUE (PARAM_ALIGN_LOOP_ITERATIONS)))
        {
          log = LOOP_ALIGN (label);
+         if (dump_file)
+           fprintf(dump_file, "  internal loop alignment added.\n");
          if (max_log < log)
            {
              max_log = log;
@@ -749,12 +788,15 @@ compute_alignments (void)
       LABEL_TO_ALIGNMENT (label) = max_log;
       LABEL_TO_MAX_SKIP (label) = max_skip;
     }
+
+  if (dump_file)
+    loop_optimizer_finalize ();
   return 0;
 }
 
 struct tree_opt_pass pass_compute_alignments =
 {
-  NULL,                                 /* name */
+  "alignments",                         /* name */
   NULL,                                 /* gate */
   compute_alignments,                   /* execute */
   NULL,                                 /* sub */
@@ -765,7 +807,8 @@ struct tree_opt_pass pass_compute_alignments =
   0,                                    /* properties_provided */
   0,                                    /* properties_destroyed */
   0,                                    /* todo_flags_start */
-  0,                                    /* todo_flags_finish */
+  TODO_dump_func | TODO_verify_rtl_sharing
+  | TODO_ggc_collect,                   /* todo_flags_finish */
   0                                     /* letter */
 };
 
@@ -2387,41 +2430,6 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
              INSN_CODE (insn) = -1;
          }
 
-       /* If this is a conditional trap, maybe modify it if the cc's
-          are in a nonstandard state so that it accomplishes the same
-          thing that it would do straightforwardly if the cc's were
-          set up normally.  */
-       if (cc_status.flags != 0
-           && NONJUMP_INSN_P (insn)
-           && GET_CODE (body) == TRAP_IF
-           && COMPARISON_P (TRAP_CONDITION (body))
-           && XEXP (TRAP_CONDITION (body), 0) == cc0_rtx)
-         {
-           /* This function may alter the contents of its argument
-              and clear some of the cc_status.flags bits.
-              It may also return 1 meaning condition now always true
-              or -1 meaning condition now always false
-              or 2 meaning condition nontrivial but altered.  */
-           int result = alter_cond (TRAP_CONDITION (body));
-
-           /* If TRAP_CONDITION has become always false, delete the
-              instruction.  */
-           if (result == -1)
-             {
-               delete_insn (insn);
-               break;
-             }
-
-           /* If TRAP_CONDITION has become always true, replace
-              TRAP_CONDITION with const_true_rtx.  */
-           if (result == 1)
-             TRAP_CONDITION (body) = const_true_rtx;
-
-           /* Rerecognize the instruction if it has changed.  */
-           if (result != 0)
-             INSN_CODE (insn) = -1;
-         }
-
        /* Make same adjustments to instructions that examine the
           condition codes without jumping and instructions that
           handle conditional moves (if this machine has either one).  */