OSDN Git Service

gcc
[pf3gnuchains/gcc-fork.git] / gcc / modulo-sched.c
index ee1a236..7da7ed8 100644 (file)
@@ -1,5 +1,5 @@
 /* Swing Modulo Scheduling implementation.
-   Copyright (C) 2004, 2005, 2006
+   Copyright (C) 2004, 2005, 2006, 2007
    Free Software Foundation, Inc.
    Contributed by Ayal Zaks and Mustafa Hagog <zaks,mustafa@il.ibm.com>
 
@@ -237,12 +237,6 @@ sms_print_insn (rtx insn, int aligned ATTRIBUTE_UNUSED)
   return tmp;
 }
 
-static int
-contributes_to_priority (rtx next, rtx insn)
-{
-  return BLOCK_NUM (next) == BLOCK_NUM (insn);
-}
-
 static void
 compute_jump_reg_dependencies (rtx insn ATTRIBUTE_UNUSED,
                               regset cond_exec ATTRIBUTE_UNUSED,
@@ -259,11 +253,17 @@ static struct sched_info sms_sched_info =
   NULL,
   NULL,
   sms_print_insn,
-  contributes_to_priority,
+  NULL,
   compute_jump_reg_dependencies,
   NULL, NULL,
   NULL, NULL,
-  0, 0, 0
+  0, 0, 0,
+
+  NULL, NULL, NULL, NULL, NULL,
+#ifdef ENABLE_CHECKING
+  NULL,
+#endif
+  0
 };
 
 
@@ -312,7 +312,7 @@ const_iteration_count (rtx count_reg, basic_block pre_header,
   if (! pre_header)
     return NULL_RTX;
 
-  get_block_head_tail (pre_header->index, &head, &tail);
+  get_ebb_head_tail (pre_header, pre_header, &head, &tail);
 
   for (insn = tail; insn != PREV_INSN (head); insn = PREV_INSN (insn))
     if (INSN_P (insn) && single_set (insn) &&
@@ -742,9 +742,9 @@ generate_prolog_epilog (partial_schedule_ptr ps, struct loop * loop, rtx count_r
   for (i = 0; i < last_stage; i++)
     duplicate_insns_of_cycles (ps, 0, i, 1);
 
-  /* Put the prolog ,  on the one and only entry edge.  */
+  /* Put the prolog on the entry edge.  */
   e = loop_preheader_edge (loop);
-  loop_split_edge_with(e , get_insns());
+  split_edge_and_insert (e, get_insns ());
 
   end_sequence ();
 
@@ -754,26 +754,13 @@ generate_prolog_epilog (partial_schedule_ptr ps, struct loop * loop, rtx count_r
   for (i = 0; i < last_stage; i++)
     duplicate_insns_of_cycles (ps, i + 1, last_stage, 0);
 
-  /* Put the epilogue on the one and only one exit edge.  */
-  gcc_assert (loop->single_exit);
-  e = loop->single_exit;
-  loop_split_edge_with(e , get_insns());
+  /* Put the epilogue on the exit edge.  */
+  gcc_assert (single_exit (loop));
+  e = single_exit (loop);
+  split_edge_and_insert (e, get_insns ());
   end_sequence ();
 }
 
-/* Return the line note insn preceding INSN, for debugging.  Taken from
-   emit-rtl.c.  */
-static rtx
-find_line_note (rtx insn)
-{
-  for (; insn; insn = PREV_INSN (insn))
-    if (NOTE_P (insn)
-       && NOTE_LINE_NUMBER (insn) >= 0)
-      break;
-
-  return insn;
-}
-
 /* Return true if all the BBs of the loop are empty except the
    loop header.  */
 static bool
@@ -792,7 +779,7 @@ loop_single_full_bb_p (struct loop *loop)
 
       /* Make sure that basic blocks other than the header
          have only notes labels or jumps.  */
-      get_block_head_tail (bbs[i]->index, &head, &tail);
+      get_ebb_head_tail (bbs[i], bbs[i], &head, &tail);
       for (; head != NEXT_INSN (tail); head = NEXT_INSN (head))
         {
           if (NOTE_P (head) || LABEL_P (head)
@@ -827,20 +814,15 @@ loop_canon_p (struct loop *loop)
   if (loop->inner || ! loop->outer)
     return false;
 
-  if (!loop->single_exit)
+  if (!single_exit (loop))
     {
       if (dump_file)
        {
-         rtx line_note = find_line_note (BB_END (loop->header));
-
+         rtx insn = BB_END (loop->header);
          fprintf (dump_file, "SMS loop many exits ");
-         if (line_note)
-           {
-             expanded_location xloc;
-             NOTE_EXPANDED_LOCATION (xloc, line_note);
-             fprintf (dump_file, " %s %d (file, line)\n",
-                      xloc.file, xloc.line);
-           }
+                 fprintf (dump_file, " %s %d (file, line)\n",
+                          insn_file (insn), insn_line (insn));
        }
       return false;
     }
@@ -849,16 +831,11 @@ loop_canon_p (struct loop *loop)
     {
       if (dump_file)
        {
-         rtx line_note = find_line_note (BB_END (loop->header));
-
+         rtx insn = BB_END (loop->header);
          fprintf (dump_file, "SMS loop many BBs. ");
-         if (line_note)
-           {
-             expanded_location xloc;
-             NOTE_EXPANDED_LOCATION (xloc, line_note);
-             fprintf (dump_file, " %s %d (file, line)\n",
-                      xloc.file, xloc.line);
-           }
+         fprintf (dump_file, " %s %d (file, line)\n",
+                  insn_file (insn), insn_line (insn));
        }
       return false;
     }
@@ -879,7 +856,7 @@ canon_loop (struct loop *loop)
      block.  */
   FOR_EACH_EDGE (e, i, EXIT_BLOCK_PTR->preds)
     if ((e->flags & EDGE_FALLTHRU) && (EDGE_COUNT (e->src->succs) > 1))
-      loop_split_edge_with (e, NULL_RTX);
+      split_edge (e);
 
   if (loop->latch == loop->header
       || EDGE_COUNT (loop->latch->succs) > 1)
@@ -887,10 +864,14 @@ canon_loop (struct loop *loop)
       FOR_EACH_EDGE (e, i, loop->header->preds)
         if (e->src == loop->latch)
           break;
-      loop_split_edge_with (e, NULL_RTX);
+      split_edge (e);
     }
 }
 
+/* Probability in % that the sms-ed loop rolls enough so that optimized
+   version may be entered.  Just a guess.  */
+#define PROB_SMS_ENOUGH_ITERATIONS 80
+
 /* Main entry point, perform SMS scheduling on the loops of the function
    that consist of single basic blocks.  */
 static void
@@ -901,21 +882,19 @@ sms_schedule (void)
   ddg_ptr *g_arr, g;
   int * node_order;
   int maxii;
-  unsigned i,num_loops;
+  loop_iterator li;
   partial_schedule_ptr ps;
   struct df *df;
-  struct loops *loops;
   basic_block bb = NULL;
-  /* vars to the versioning only if needed*/
-  struct loop * nloop;
+  struct loop *loop;
   basic_block condition_bb = NULL;
   edge latch_edge;
   gcov_type trip_count = 0;
 
-  loops = loop_optimizer_init (LOOPS_HAVE_PREHEADERS
-                              | LOOPS_HAVE_MARKED_SINGLE_EXITS);
-  if (!loops)
-    return;  /* There is no loops to schedule.  */
+  loop_optimizer_init (LOOPS_HAVE_PREHEADERS
+                      | LOOPS_HAVE_RECORDED_EXITS);
+  if (!current_loops)
+    return;  /* There are no loops to schedule.  */
 
   /* Initialize issue_rate.  */
   if (targetm.sched.issue_rate)
@@ -934,24 +913,25 @@ sms_schedule (void)
   sched_init ();
 
   /* Init Data Flow analysis, to be used in interloop dep calculation.  */
-  df = df_init (DF_HARD_REGS | DF_EQUIV_NOTES |        DF_SUBREGS);
-  df_rd_add_problem (df);
-  df_ru_add_problem (df);
+  df = df_init (DF_HARD_REGS | DF_EQUIV_NOTES | DF_SUBREGS);
+  df_rd_add_problem (df, 0);
+  df_ru_add_problem (df, 0);
   df_chain_add_problem (df, DF_DU_CHAIN | DF_UD_CHAIN);
   df_analyze (df);
 
+  if (dump_file)
+    df_dump (df, dump_file);
+
   /* Allocate memory to hold the DDG array one entry for each loop.
      We use loop->num as index into this array.  */
-  g_arr = XCNEWVEC (ddg_ptr, loops->num);
-
+  g_arr = XCNEWVEC (ddg_ptr, number_of_loops ());
 
   /* Build DDGs for all the relevant loops and hold them in G_ARR
      indexed by the loop index.  */
-  for (i = 0; i < loops->num; i++)
+  FOR_EACH_LOOP (li, loop, 0)
     {
       rtx head, tail;
       rtx count_reg;
-      struct loop *loop = loops->parray[i];
 
       /* For debugging.  */
       if ((passes++ > MAX_SMS_LOOP_NUMBER) && (MAX_SMS_LOOP_NUMBER != -1))
@@ -970,28 +950,21 @@ sms_schedule (void)
 
       bb = loop->header;
 
-      get_block_head_tail (bb->index, &head, &tail);
+      get_ebb_head_tail (bb, bb, &head, &tail);
       latch_edge = loop_latch_edge (loop);
-      gcc_assert (loop->single_exit);
-      if (loop->single_exit->count)
-       trip_count = latch_edge->count / loop->single_exit->count;
+      gcc_assert (single_exit (loop));
+      if (single_exit (loop)->count)
+       trip_count = latch_edge->count / single_exit (loop)->count;
 
       /* Perfrom SMS only on loops that their average count is above threshold.  */
 
       if ( latch_edge->count
-          && (latch_edge->count < loop->single_exit->count * SMS_LOOP_AVERAGE_COUNT_THRESHOLD))
+          && (latch_edge->count < single_exit (loop)->count * SMS_LOOP_AVERAGE_COUNT_THRESHOLD))
        {
          if (dump_file)
            {
-             rtx line_note = find_line_note (tail);
-
-             if (line_note)
-               {
-                 expanded_location xloc;
-                 NOTE_EXPANDED_LOCATION (xloc, line_note);
-                 fprintf (dump_file, "SMS bb %s %d (file, line)\n",
-                          xloc.file, xloc.line);
-               }
+             fprintf (dump_file, " %s %d (file, line)\n",
+                      insn_file (tail), insn_line (tail));
              fprintf (dump_file, "SMS single-bb-loop\n");
              if (profile_info && flag_branch_probabilities)
                {
@@ -1047,7 +1020,7 @@ sms_schedule (void)
          continue;
         }
 
-      g_arr[i] = g;
+      g_arr[loop->num] = g;
     }
 
   /* Release Data Flow analysis data structures.  */
@@ -1055,41 +1028,31 @@ sms_schedule (void)
   df = NULL;
 
   /* We don't want to perform SMS on new loops - created by versioning.  */
-  num_loops = loops->num;
-  /* Go over the built DDGs and perfrom SMS for each one of them.  */
-  for (i = 0; i < num_loops; i++)
+  FOR_EACH_LOOP (li, loop, 0)
     {
       rtx head, tail;
       rtx count_reg, count_init;
       int mii, rec_mii;
       unsigned stage_count = 0;
       HOST_WIDEST_INT loop_count = 0;
-      struct loop *loop = loops->parray[i];
 
-      if (! (g = g_arr[i]))
+      if (! (g = g_arr[loop->num]))
         continue;
 
       if (dump_file)
        print_ddg (dump_file, g);
 
-      get_block_head_tail (loop->header->index, &head, &tail);
+      get_ebb_head_tail (loop->header, loop->header, &head, &tail);
 
       latch_edge = loop_latch_edge (loop);
-      gcc_assert (loop->single_exit);
-      if (loop->single_exit->count)
-       trip_count = latch_edge->count / loop->single_exit->count;
+      gcc_assert (single_exit (loop));
+      if (single_exit (loop)->count)
+       trip_count = latch_edge->count / single_exit (loop)->count;
 
       if (dump_file)
        {
-         rtx line_note = find_line_note (tail);
-
-         if (line_note)
-           {
-             expanded_location xloc;
-             NOTE_EXPANDED_LOCATION (xloc, line_note);
-             fprintf (dump_file, "SMS bb %s %d (file, line)\n",
-                      xloc.file, xloc.line);
-           }
+         fprintf (dump_file, " %s %d (file, line)\n",
+                  insn_file (tail), insn_line (tail));
          fprintf (dump_file, "SMS single-bb-loop\n");
          if (profile_info && flag_branch_probabilities)
            {
@@ -1222,9 +1185,12 @@ sms_schedule (void)
                {
                  rtx comp_rtx = gen_rtx_fmt_ee (GT, VOIDmode, count_reg,
                                                 GEN_INT(stage_count));
+                 unsigned prob = (PROB_SMS_ENOUGH_ITERATIONS
+                                  * REG_BR_PROB_BASE) / 100;
 
-                 nloop = loop_version (loops, loop, comp_rtx, &condition_bb,
-                                       true);
+                 loop_version (loop, comp_rtx, &condition_bb,
+                               prob, prob, REG_BR_PROB_BASE - prob,
+                               true);
                }
 
              /* Set new iteration count of loop kernel.  */
@@ -1264,7 +1230,7 @@ sms_schedule (void)
 
   /* Release scheduler data, needed until now because of DFA.  */
   sched_finish ();
-  loop_optimizer_finalize (loops);
+  loop_optimizer_finalize ();
 }
 
 /* The SMS scheduling algorithm itself
@@ -1503,7 +1469,7 @@ sms_schedule_by_order (ddg_ptr g, int mii, int maxii, int *nodes_order)
       bool unscheduled_nodes = false;
 
       if (dump_file)
-       fprintf(dump_file, "Starting with ii=%d\n", ii);
+       fprintf (dump_file, "Starting with ii=%d\n", ii);
       if (try_again_with_larger_ii)
        {
          try_again_with_larger_ii = false;
@@ -1555,8 +1521,9 @@ sms_schedule_by_order (ddg_ptr g, int mii, int maxii, int *nodes_order)
            }
          /* 2. Try scheduling u in window.  */
          if (dump_file)
-           fprintf(dump_file, "Trying to schedule node %d in (%d .. %d) step %d\n",
-                   u, start, end, step);
+           fprintf (dump_file,
+                    "Trying to schedule node %d in (%d .. %d) step %d\n",
+                    u, start, end, step);
 
           /* use must_follow & must_precede bitmaps to determine order
             of nodes within the cycle.  */
@@ -1590,7 +1557,7 @@ sms_schedule_by_order (ddg_ptr g, int mii, int maxii, int *nodes_order)
                    SET_BIT (sched_nodes, u);
                    success = 1;
                    if (dump_file)
-                     fprintf(dump_file, "Schedule in %d\n", c);
+                     fprintf (dump_file, "Schedule in %d\n", c);
                    break;
                  }
              }
@@ -2545,7 +2512,7 @@ struct tree_opt_pass pass_sms =
   0,                                    /* properties_required */
   0,                                    /* properties_provided */
   0,                                    /* properties_destroyed */
-  0,                                    /* todo_flags_start */
+  TODO_dump_func,                       /* todo_flags_start */
   TODO_dump_func |
   TODO_ggc_collect,                     /* todo_flags_finish */
   'm'                                   /* letter */