OSDN Git Service

2006-01-16 Richard Guenther <rguenther@suse.de>
[pf3gnuchains/gcc-fork.git] / gcc / modulo-sched.c
index f42dd1b..a669bb8 100644 (file)
@@ -1,5 +1,5 @@
 /* Swing Modulo Scheduling implementation.
-   Copyright (C) 2004, 2005
+   Copyright (C) 2004, 2005, 2006
    Free Software Foundation, Inc.
    Contributed by Ayal Zaks and Mustafa Hagog <zaks,mustafa@il.ibm.com>
 
@@ -17,8 +17,8 @@ for more details.
 
 You should have received a copy of the GNU General Public License
 along with GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA.  */
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.  */
 
 
 #include "config.h"
@@ -47,6 +47,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "gcov-io.h"
 #include "df.h"
 #include "ddg.h"
+#include "timevar.h"
+#include "tree-pass.h"
 
 #ifdef INSN_SCHEDULING
 
@@ -273,8 +275,9 @@ static struct sched_info sms_sched_info =
    or zero if it is not a decrement-and-branch insn.  */
 
 static rtx
-doloop_register_get (rtx insn)
+doloop_register_get (rtx insn ATTRIBUTE_UNUSED)
 {
+#ifdef HAVE_doloop_end
   rtx pattern, reg, condition;
 
   if (! JUMP_P (insn))
@@ -294,6 +297,9 @@ doloop_register_get (rtx insn)
     gcc_unreachable ();
 
   return reg;
+#else
+  return NULL_RTX;
+#endif
 }
 
 /* Check if COUNT_REG is set to a constant in the PRE_HEADER block, so
@@ -495,9 +501,10 @@ generate_reg_moves (partial_schedule_ptr ps)
 
       for (i_reg_move = 0; i_reg_move < nreg_moves; i_reg_move++)
        {
-         int i_use;
+         unsigned int i_use = 0;
          rtx new_reg = gen_reg_rtx (GET_MODE (prev_reg));
          rtx reg_move = gen_move_insn (new_reg, prev_reg);
+         sbitmap_iterator sbi;
 
          add_insn_before (reg_move, last_reg_move);
          last_reg_move = reg_move;
@@ -505,7 +512,7 @@ generate_reg_moves (partial_schedule_ptr ps)
          if (!SCHED_FIRST_REG_MOVE (u))
            SCHED_FIRST_REG_MOVE (u) = reg_move;
 
-         EXECUTE_IF_SET_IN_SBITMAP (uses_of_defs[i_reg_move], 0, i_use,
+         EXECUTE_IF_SET_IN_SBITMAP (uses_of_defs[i_reg_move], 0, i_use, sbi)
            {
              struct undo_replace_buff_elem *rep;
 
@@ -524,7 +531,7 @@ generate_reg_moves (partial_schedule_ptr ps)
                }
 
              replace_rtx (g->nodes[i_use].insn, old_reg, new_reg);
-           });
+           }
 
          prev_reg = new_reg;
        }
@@ -969,8 +976,11 @@ sms_schedule (FILE *dump_file)
   sched_init (NULL);
 
   /* Init Data Flow analysis, to be used in interloop dep calculation.  */
-  df = df_init ();
-  df_analyze (df, 0, DF_ALL);
+  df = df_init (DF_HARD_REGS | DF_EQUIV_NOTES |        DF_SUBREGS);
+  df_rd_add_problem (df);
+  df_ru_add_problem (df);
+  df_chain_add_problem (df, DF_DU_CHAIN | DF_UD_CHAIN);
+  df_analyze (df);
 
   /* Allocate memory to hold the DDG array one entry for each loop.
      We use loop->num as index into this array.  */
@@ -1084,6 +1094,7 @@ sms_schedule (FILE *dump_file)
 
   /* Release Data Flow analysis data structures.  */
   df_finish (df);
+  df = NULL;
 
   /* We don't want to perform SMS on new loops - created by versioning.  */
   num_loops = loops->num;
@@ -1254,7 +1265,8 @@ sms_schedule (FILE *dump_file)
                  rtx comp_rtx = gen_rtx_fmt_ee (GT, VOIDmode, count_reg,
                                                 GEN_INT(stage_count));
 
-                 nloop = loop_version (loops, loop, comp_rtx, &condition_bb);
+                 nloop = loop_version (loops, loop, comp_rtx, &condition_bb,
+                                       true);
                }
 
              /* Set new iteration count of loop kernel.  */
@@ -1838,11 +1850,12 @@ calculate_order_params (ddg_ptr g, int mii ATTRIBUTE_UNUSED)
 static int
 find_max_asap (ddg_ptr g, sbitmap nodes)
 {
-  int u;
+  unsigned int u = 0;
   int max_asap = -1;
   int result = -1;
+  sbitmap_iterator sbi;
 
-  EXECUTE_IF_SET_IN_SBITMAP (nodes, 0, u,
+  EXECUTE_IF_SET_IN_SBITMAP (nodes, 0, u, sbi)
     {
       ddg_node_ptr u_node = &g->nodes[u];
 
@@ -1851,19 +1864,20 @@ find_max_asap (ddg_ptr g, sbitmap nodes)
          max_asap = ASAP (u_node);
          result = u;
        }
-    });
+    }
   return result;
 }
 
 static int
 find_max_hv_min_mob (ddg_ptr g, sbitmap nodes)
 {
-  int u;
+  unsigned int u = 0;
   int max_hv = -1;
   int min_mob = INT_MAX;
   int result = -1;
+  sbitmap_iterator sbi;
 
-  EXECUTE_IF_SET_IN_SBITMAP (nodes, 0, u,
+  EXECUTE_IF_SET_IN_SBITMAP (nodes, 0, u, sbi)
     {
       ddg_node_ptr u_node = &g->nodes[u];
 
@@ -1879,19 +1893,20 @@ find_max_hv_min_mob (ddg_ptr g, sbitmap nodes)
          min_mob = MOB (u_node);
          result = u;
        }
-    });
+    }
   return result;
 }
 
 static int
 find_max_dv_min_mob (ddg_ptr g, sbitmap nodes)
 {
-  int u;
+  unsigned int u = 0;
   int max_dv = -1;
   int min_mob = INT_MAX;
   int result = -1;
+  sbitmap_iterator sbi;
 
-  EXECUTE_IF_SET_IN_SBITMAP (nodes, 0, u,
+  EXECUTE_IF_SET_IN_SBITMAP (nodes, 0, u, sbi)
     {
       ddg_node_ptr u_node = &g->nodes[u];
 
@@ -1907,7 +1922,7 @@ find_max_dv_min_mob (ddg_ptr g, sbitmap nodes)
          min_mob = MOB (u_node);
          result = u;
        }
-    });
+    }
   return result;
 }
 
@@ -2509,5 +2524,64 @@ ps_unschedule_node (partial_schedule_ptr ps, ddg_node_ptr n)
 
   return remove_node_from_ps (ps, ps_i);
 }
-#endif /* INSN_SCHEDULING*/
+#endif /* INSN_SCHEDULING */
+\f
+static bool
+gate_handle_sms (void)
+{
+  return (optimize > 0 && flag_modulo_sched);
+}
+
+
+/* Run instruction scheduler.  */
+/* Perform SMS module scheduling.  */
+static void
+rest_of_handle_sms (void)
+{
+#ifdef INSN_SCHEDULING
+  basic_block bb;
+
+  /* We want to be able to create new pseudos.  */
+  no_new_pseudos = 0;
+  /* Collect loop information to be used in SMS.  */
+  cfg_layout_initialize (CLEANUP_UPDATE_LIFE);
+  sms_schedule (dump_file);
+
+  /* Update the life information, because we add pseudos.  */
+  max_regno = max_reg_num ();
+  allocate_reg_info (max_regno, FALSE, FALSE);
+  update_life_info (NULL, UPDATE_LIFE_GLOBAL_RM_NOTES,
+                    (PROP_DEATH_NOTES
+                     | PROP_REG_INFO
+                     | PROP_KILL_DEAD_CODE
+                     | PROP_SCAN_DEAD_CODE));
+
+  no_new_pseudos = 1;
+
+  /* Finalize layout changes.  */
+  FOR_EACH_BB (bb)
+    if (bb->next_bb != EXIT_BLOCK_PTR)
+      bb->aux = bb->next_bb;
+  cfg_layout_finalize ();
+  free_dominance_info (CDI_DOMINATORS);
+#endif /* INSN_SCHEDULING */
+}
+
+struct tree_opt_pass pass_sms =
+{
+  "sms",                                /* name */
+  gate_handle_sms,                      /* gate */
+  rest_of_handle_sms,                   /* execute */
+  NULL,                                 /* sub */
+  NULL,                                 /* next */
+  0,                                    /* static_pass_number */
+  TV_SMS,                               /* tv_id */
+  0,                                    /* properties_required */
+  0,                                    /* properties_provided */
+  0,                                    /* properties_destroyed */
+  0,                                    /* todo_flags_start */
+  TODO_dump_func |
+  TODO_ggc_collect,                     /* todo_flags_finish */
+  'm'                                   /* letter */
+};