OSDN Git Service

2008-06-28 Daniel Kraft <d@domob.eu>
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-loop.c
index 7457e53..52f5a7f 100644 (file)
@@ -5,7 +5,7 @@ This file is part of GCC.
    
 GCC is free software; you can redistribute it and/or modify it
 under the terms of the GNU General Public License as published by the
    
 GCC is free software; you can redistribute it and/or modify it
 under the terms of the GNU General Public License as published by the
-Free Software Foundation; either version 2, or (at your option) any
+Free Software Foundation; either version 3, or (at your option) any
 later version.
    
 GCC is distributed in the hope that it will be useful, but WITHOUT
 later version.
    
 GCC is distributed in the hope that it will be useful, but WITHOUT
@@ -14,9 +14,8 @@ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 for more details.
    
 You should have received a copy of the GNU General Public License
 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, 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
 #include "system.h"
 
 #include "config.h"
 #include "system.h"
@@ -45,9 +44,6 @@ tree_loop_optimizer_init (void)
 {
   loop_optimizer_init (LOOPS_NORMAL
                       | LOOPS_HAVE_RECORDED_EXITS);
 {
   loop_optimizer_init (LOOPS_NORMAL
                       | LOOPS_HAVE_RECORDED_EXITS);
-  if (!current_loops)
-    return;
-
   rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
 }
 
   rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
 }
 
@@ -59,8 +55,10 @@ gate_tree_loop (void)
   return flag_tree_loop_optimize != 0;
 }
 
   return flag_tree_loop_optimize != 0;
 }
 
-struct tree_opt_pass pass_tree_loop = 
+struct gimple_opt_pass pass_tree_loop = 
 {
 {
+ {
+  GIMPLE_PASS,
   "loop",                              /* name */
   gate_tree_loop,                      /* gate */
   NULL,                                        /* execute */
   "loop",                              /* name */
   gate_tree_loop,                      /* gate */
   NULL,                                        /* execute */
@@ -72,8 +70,8 @@ struct tree_opt_pass pass_tree_loop =
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   TODO_ggc_collect,                    /* todo_flags_start */
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   TODO_ggc_collect,                    /* todo_flags_start */
-  TODO_dump_func | TODO_verify_ssa | TODO_ggc_collect, /* todo_flags_finish */
-  0                                    /* letter */
+  TODO_dump_func | TODO_verify_ssa | TODO_ggc_collect  /* todo_flags_finish */
+ }
 };
 
 /* Loop optimizer initialization.  */
 };
 
 /* Loop optimizer initialization.  */
@@ -82,15 +80,17 @@ static unsigned int
 tree_ssa_loop_init (void)
 {
   tree_loop_optimizer_init ();
 tree_ssa_loop_init (void)
 {
   tree_loop_optimizer_init ();
-  if (!current_loops)
+  if (number_of_loops () <= 1)
     return 0;
 
   scev_initialize ();
   return 0;
 }
   
     return 0;
 
   scev_initialize ();
   return 0;
 }
   
-struct tree_opt_pass pass_tree_loop_init = 
+struct gimple_opt_pass pass_tree_loop_init = 
 {
 {
+ {
+  GIMPLE_PASS,
   "loopinit",                          /* name */
   NULL,                                        /* gate */
   tree_ssa_loop_init,                  /* execute */
   "loopinit",                          /* name */
   NULL,                                        /* gate */
   tree_ssa_loop_init,                  /* execute */
@@ -102,8 +102,8 @@ struct tree_opt_pass pass_tree_loop_init =
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
-  TODO_dump_func | TODO_verify_loops,  /* todo_flags_finish */
-  0                                    /* letter */
+  TODO_dump_func | TODO_verify_loops   /* todo_flags_finish */
+ }
 };
 
 /* Loop invariant motion pass.  */
 };
 
 /* Loop invariant motion pass.  */
@@ -111,7 +111,7 @@ struct tree_opt_pass pass_tree_loop_init =
 static unsigned int
 tree_ssa_loop_im (void)
 {
 static unsigned int
 tree_ssa_loop_im (void)
 {
-  if (!current_loops)
+  if (number_of_loops () <= 1)
     return 0;
 
   tree_ssa_lim ();
     return 0;
 
   tree_ssa_lim ();
@@ -124,8 +124,10 @@ gate_tree_ssa_loop_im (void)
   return flag_tree_loop_im != 0;
 }
 
   return flag_tree_loop_im != 0;
 }
 
-struct tree_opt_pass pass_lim = 
+struct gimple_opt_pass pass_lim = 
 {
 {
+ {
+  GIMPLE_PASS,
   "lim",                               /* name */
   gate_tree_ssa_loop_im,               /* gate */
   tree_ssa_loop_im,                    /* execute */
   "lim",                               /* name */
   gate_tree_ssa_loop_im,               /* gate */
   tree_ssa_loop_im,                    /* execute */
@@ -137,8 +139,8 @@ struct tree_opt_pass pass_lim =
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
-  TODO_dump_func | TODO_verify_loops,  /* todo_flags_finish */
-  0                                    /* letter */
+  TODO_dump_func | TODO_verify_loops   /* todo_flags_finish */
+ }
 };
 
 /* Loop unswitching pass.  */
 };
 
 /* Loop unswitching pass.  */
@@ -146,7 +148,7 @@ struct tree_opt_pass pass_lim =
 static unsigned int
 tree_ssa_loop_unswitch (void)
 {
 static unsigned int
 tree_ssa_loop_unswitch (void)
 {
-  if (!current_loops)
+  if (number_of_loops () <= 1)
     return 0;
 
   return tree_ssa_unswitch_loops ();
     return 0;
 
   return tree_ssa_unswitch_loops ();
@@ -158,8 +160,10 @@ gate_tree_ssa_loop_unswitch (void)
   return flag_unswitch_loops != 0;
 }
 
   return flag_unswitch_loops != 0;
 }
 
-struct tree_opt_pass pass_tree_unswitch = 
+struct gimple_opt_pass pass_tree_unswitch = 
 {
 {
+ {
+  GIMPLE_PASS,
   "unswitch",                          /* name */
   gate_tree_ssa_loop_unswitch,         /* gate */
   tree_ssa_loop_unswitch,              /* execute */
   "unswitch",                          /* name */
   gate_tree_ssa_loop_unswitch,         /* gate */
   tree_ssa_loop_unswitch,              /* execute */
@@ -171,8 +175,47 @@ struct tree_opt_pass pass_tree_unswitch =
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
-  TODO_dump_func | TODO_verify_loops,  /* todo_flags_finish */
-  0                                    /* letter */
+  TODO_ggc_collect | TODO_dump_func
+    | TODO_verify_loops                        /* todo_flags_finish */
+ }
+};
+
+/* Predictive commoning.  */
+
+static unsigned
+run_tree_predictive_commoning (void)
+{
+  if (!current_loops)
+    return 0;
+
+  tree_predictive_commoning ();
+  return 0;
+}
+
+static bool
+gate_tree_predictive_commoning (void)
+{
+  return flag_predictive_commoning != 0;
+}
+
+struct gimple_opt_pass pass_predcom = 
+{
+ {
+  GIMPLE_PASS,
+  "pcom",                              /* name */
+  gate_tree_predictive_commoning,      /* gate */
+  run_tree_predictive_commoning,       /* execute */
+  NULL,                                        /* sub */
+  NULL,                                        /* next */
+  0,                                   /* static_pass_number */
+  TV_PREDCOM,                          /* tv_id */
+  PROP_cfg,                            /* properties_required */
+  0,                                   /* properties_provided */
+  0,                                   /* properties_destroyed */
+  0,                                   /* todo_flags_start */
+  TODO_dump_func | TODO_verify_loops
+    | TODO_update_ssa_only_virtuals    /* todo_flags_finish */
+ }
 };
 
 /* Loop autovectorization.  */
 };
 
 /* Loop autovectorization.  */
@@ -180,17 +223,22 @@ struct tree_opt_pass pass_tree_unswitch =
 static unsigned int
 tree_vectorize (void)
 {
 static unsigned int
 tree_vectorize (void)
 {
+  if (number_of_loops () <= 1)
+    return 0;
+
   return vectorize_loops ();
 }
 
 static bool
 gate_tree_vectorize (void)
 {
   return vectorize_loops ();
 }
 
 static bool
 gate_tree_vectorize (void)
 {
-  return flag_tree_vectorize && current_loops;
+  return flag_tree_vectorize;
 }
 
 }
 
-struct tree_opt_pass pass_vectorize =
+struct gimple_opt_pass pass_vectorize =
 {
 {
+ {
+  GIMPLE_PASS,
   "vect",                               /* name */
   gate_tree_vectorize,                  /* gate */
   tree_vectorize,                       /* execute */
   "vect",                               /* name */
   gate_tree_vectorize,                  /* gate */
   tree_vectorize,                       /* execute */
@@ -202,8 +250,9 @@ struct tree_opt_pass pass_vectorize =
   0,                                    /* properties_provided */
   0,                                    /* properties_destroyed */
   TODO_verify_loops,                   /* todo_flags_start */
   0,                                    /* properties_provided */
   0,                                    /* properties_destroyed */
   TODO_verify_loops,                   /* todo_flags_start */
-  TODO_dump_func | TODO_update_ssa,    /* todo_flags_finish */
-  0                                    /* letter */
+  TODO_dump_func | TODO_update_ssa
+    | TODO_ggc_collect                 /* todo_flags_finish */
+ }
 };
 
 /* Loop nest optimizations.  */
 };
 
 /* Loop nest optimizations.  */
@@ -211,7 +260,7 @@ struct tree_opt_pass pass_vectorize =
 static unsigned int
 tree_linear_transform (void)
 {
 static unsigned int
 tree_linear_transform (void)
 {
-  if (!current_loops)
+  if (number_of_loops () <= 1)
     return 0;
 
   linear_transform_loops ();
     return 0;
 
   linear_transform_loops ();
@@ -224,8 +273,10 @@ gate_tree_linear_transform (void)
   return flag_tree_loop_linear != 0;
 }
 
   return flag_tree_loop_linear != 0;
 }
 
-struct tree_opt_pass pass_linear_transform =
+struct gimple_opt_pass pass_linear_transform =
 {
 {
+ {
+  GIMPLE_PASS,
   "ltrans",                            /* name */
   gate_tree_linear_transform,          /* gate */
   tree_linear_transform,                       /* execute */
   "ltrans",                            /* name */
   gate_tree_linear_transform,          /* gate */
   tree_linear_transform,                       /* execute */
@@ -237,8 +288,10 @@ struct tree_opt_pass pass_linear_transform =
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
-  TODO_dump_func | TODO_verify_loops,  /* todo_flags_finish */
-  0                                    /* letter */    
+  TODO_dump_func | TODO_verify_loops
+    | TODO_update_ssa_only_virtuals
+    | TODO_ggc_collect                 /* todo_flags_finish */
+ }
 };
 
 /* Check the correctness of the data dependence analyzers.  */
 };
 
 /* Check the correctness of the data dependence analyzers.  */
@@ -246,7 +299,7 @@ struct tree_opt_pass pass_linear_transform =
 static unsigned int
 check_data_deps (void)
 {
 static unsigned int
 check_data_deps (void)
 {
-  if (!current_loops)
+  if (number_of_loops () <= 1)
     return 0;
 
   tree_check_data_deps ();
     return 0;
 
   tree_check_data_deps ();
@@ -259,8 +312,10 @@ gate_check_data_deps (void)
   return flag_check_data_deps != 0;
 }
 
   return flag_check_data_deps != 0;
 }
 
-struct tree_opt_pass pass_check_data_deps =
+struct gimple_opt_pass pass_check_data_deps =
 {
 {
+ {
+  GIMPLE_PASS,
   "ckdd",                              /* name */
   gate_check_data_deps,                        /* gate */
   check_data_deps,                     /* execute */
   "ckdd",                              /* name */
   gate_check_data_deps,                        /* gate */
   check_data_deps,                     /* execute */
@@ -272,8 +327,8 @@ struct tree_opt_pass pass_check_data_deps =
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
-  TODO_dump_func,                      /* todo_flags_finish */
-  0                                    /* letter */    
+  TODO_dump_func                       /* todo_flags_finish */
+ }
 };
 
 /* Canonical induction variable creation pass.  */
 };
 
 /* Canonical induction variable creation pass.  */
@@ -281,7 +336,7 @@ struct tree_opt_pass pass_check_data_deps =
 static unsigned int
 tree_ssa_loop_ivcanon (void)
 {
 static unsigned int
 tree_ssa_loop_ivcanon (void)
 {
-  if (!current_loops)
+  if (number_of_loops () <= 1)
     return 0;
 
   return canonicalize_induction_variables ();
     return 0;
 
   return canonicalize_induction_variables ();
@@ -293,8 +348,10 @@ gate_tree_ssa_loop_ivcanon (void)
   return flag_tree_loop_ivcanon != 0;
 }
 
   return flag_tree_loop_ivcanon != 0;
 }
 
-struct tree_opt_pass pass_iv_canon =
+struct gimple_opt_pass pass_iv_canon =
 {
 {
+ {
+  GIMPLE_PASS,
   "ivcanon",                           /* name */
   gate_tree_ssa_loop_ivcanon,          /* gate */
   tree_ssa_loop_ivcanon,               /* execute */
   "ivcanon",                           /* name */
   gate_tree_ssa_loop_ivcanon,          /* gate */
   tree_ssa_loop_ivcanon,               /* execute */
@@ -306,8 +363,8 @@ struct tree_opt_pass pass_iv_canon =
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
-  TODO_dump_func | TODO_verify_loops,  /* todo_flags_finish */
-  0                                    /* letter */
+  TODO_dump_func | TODO_verify_loops   /* todo_flags_finish */
+ }
 };
 
 /* Propagation of constants using scev.  */
 };
 
 /* Propagation of constants using scev.  */
@@ -318,8 +375,10 @@ gate_scev_const_prop (void)
   return flag_tree_scev_cprop;
 }
 
   return flag_tree_scev_cprop;
 }
 
-struct tree_opt_pass pass_scev_cprop =
+struct gimple_opt_pass pass_scev_cprop =
 {
 {
+ {
+  GIMPLE_PASS,
   "sccp",                              /* name */
   gate_scev_const_prop,                        /* gate */
   scev_const_prop,                     /* execute */
   "sccp",                              /* name */
   gate_scev_const_prop,                        /* gate */
   scev_const_prop,                     /* execute */
@@ -332,9 +391,9 @@ struct tree_opt_pass pass_scev_cprop =
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
   TODO_dump_func | TODO_cleanup_cfg
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
   TODO_dump_func | TODO_cleanup_cfg
-    | TODO_update_ssa_only_virtuals,
+    | TODO_update_ssa_only_virtuals
                                        /* todo_flags_finish */
                                        /* todo_flags_finish */
-  0                                    /* letter */
+ }
 };
 
 /* Remove empty loops.  */
 };
 
 /* Remove empty loops.  */
@@ -342,14 +401,16 @@ struct tree_opt_pass pass_scev_cprop =
 static unsigned int
 tree_ssa_empty_loop (void)
 {
 static unsigned int
 tree_ssa_empty_loop (void)
 {
-  if (!current_loops)
+  if (number_of_loops () <= 1)
     return 0;
 
   return remove_empty_loops ();
 }
 
     return 0;
 
   return remove_empty_loops ();
 }
 
-struct tree_opt_pass pass_empty_loop =
+struct gimple_opt_pass pass_empty_loop =
 {
 {
+ {
+  GIMPLE_PASS,
   "empty",                             /* name */
   NULL,                                        /* gate */
   tree_ssa_empty_loop,                 /* execute */
   "empty",                             /* name */
   NULL,                                        /* gate */
   tree_ssa_empty_loop,                 /* execute */
@@ -361,8 +422,9 @@ struct tree_opt_pass pass_empty_loop =
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
-  TODO_dump_func | TODO_verify_loops,  /* todo_flags_finish */
-  0                                    /* letter */
+  TODO_dump_func | TODO_verify_loops 
+    | TODO_ggc_collect                 /* todo_flags_finish */
+ }
 };
 
 /* Record bounds on numbers of iterations of loops.  */
 };
 
 /* Record bounds on numbers of iterations of loops.  */
@@ -370,7 +432,7 @@ struct tree_opt_pass pass_empty_loop =
 static unsigned int
 tree_ssa_loop_bounds (void)
 {
 static unsigned int
 tree_ssa_loop_bounds (void)
 {
-  if (!current_loops)
+  if (number_of_loops () <= 1)
     return 0;
 
   estimate_numbers_of_iterations ();
     return 0;
 
   estimate_numbers_of_iterations ();
@@ -378,8 +440,10 @@ tree_ssa_loop_bounds (void)
   return 0;
 }
 
   return 0;
 }
 
-struct tree_opt_pass pass_record_bounds =
+struct gimple_opt_pass pass_record_bounds =
 {
 {
+ {
+  GIMPLE_PASS,
   NULL,                                        /* name */
   NULL,                                        /* gate */
   tree_ssa_loop_bounds,                        /* execute */
   NULL,                                        /* name */
   NULL,                                        /* gate */
   tree_ssa_loop_bounds,                        /* execute */
@@ -391,8 +455,8 @@ struct tree_opt_pass pass_record_bounds =
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
-  0,                                   /* todo_flags_finish */
-  0                                    /* letter */
+  0                                    /* todo_flags_finish */
+ }
 };
 
 /* Complete unrolling of loops.  */
 };
 
 /* Complete unrolling of loops.  */
@@ -400,12 +464,12 @@ struct tree_opt_pass pass_record_bounds =
 static unsigned int
 tree_complete_unroll (void)
 {
 static unsigned int
 tree_complete_unroll (void)
 {
-  if (!current_loops)
+  if (number_of_loops () <= 1)
     return 0;
 
   return tree_unroll_loops_completely (flag_unroll_loops
                                       || flag_peel_loops
     return 0;
 
   return tree_unroll_loops_completely (flag_unroll_loops
                                       || flag_peel_loops
-                                      || optimize >= 3);
+                                      || optimize >= 3, true);
 }
 
 static bool
 }
 
 static bool
@@ -414,8 +478,10 @@ gate_tree_complete_unroll (void)
   return true;
 }
 
   return true;
 }
 
-struct tree_opt_pass pass_complete_unroll =
+struct gimple_opt_pass pass_complete_unroll =
 {
 {
+ {
+  GIMPLE_PASS,
   "cunroll",                           /* name */
   gate_tree_complete_unroll,           /* gate */
   tree_complete_unroll,                        /* execute */
   "cunroll",                           /* name */
   gate_tree_complete_unroll,           /* gate */
   tree_complete_unroll,                        /* execute */
@@ -427,8 +493,94 @@ struct tree_opt_pass pass_complete_unroll =
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
-  TODO_dump_func | TODO_verify_loops,  /* todo_flags_finish */
-  0                                    /* letter */
+  TODO_dump_func | TODO_verify_loops
+    | TODO_ggc_collect                 /* todo_flags_finish */
+ }
+};
+
+/* Complete unrolling of inner loops.  */
+
+static unsigned int
+tree_complete_unroll_inner (void)
+{
+  unsigned ret = 0;
+
+  loop_optimizer_init (LOOPS_NORMAL
+                      | LOOPS_HAVE_RECORDED_EXITS);
+  if (number_of_loops () > 1)
+    {
+      scev_initialize ();
+      ret = tree_unroll_loops_completely (optimize >= 3, false);
+      free_numbers_of_iterations_estimates ();
+      scev_finalize ();
+    }
+  loop_optimizer_finalize ();
+
+  return ret;
+}
+
+static bool
+gate_tree_complete_unroll_inner (void)
+{
+  return optimize >= 2;
+}
+
+struct gimple_opt_pass pass_complete_unrolli =
+{
+ {
+  GIMPLE_PASS,
+  "cunrolli",                          /* name */
+  gate_tree_complete_unroll_inner,     /* gate */
+  tree_complete_unroll_inner,          /* execute */
+  NULL,                                        /* sub */
+  NULL,                                        /* next */
+  0,                                   /* static_pass_number */
+  TV_COMPLETE_UNROLL,                  /* tv_id */
+  PROP_cfg | PROP_ssa,                 /* properties_required */
+  0,                                   /* properties_provided */
+  0,                                   /* properties_destroyed */
+  0,                                   /* todo_flags_start */
+  TODO_dump_func | TODO_verify_loops
+    | TODO_ggc_collect                         /* todo_flags_finish */
+ }
+};
+
+/* Parallelization.  */
+
+static bool
+gate_tree_parallelize_loops (void)
+{
+  return flag_tree_parallelize_loops > 1;
+}
+
+static unsigned
+tree_parallelize_loops (void)
+{
+  if (number_of_loops () <= 1)
+    return 0;
+
+  if (parallelize_loops ())
+    return TODO_cleanup_cfg | TODO_rebuild_alias;
+  return 0;
+}
+
+struct gimple_opt_pass pass_parallelize_loops =
+{
+ {
+  GIMPLE_PASS,
+  "parloops",                          /* name */
+  gate_tree_parallelize_loops,         /* gate */
+  tree_parallelize_loops,                      /* execute */
+  NULL,                                        /* sub */
+  NULL,                                        /* next */
+  0,                                   /* static_pass_number */
+  TV_TREE_PARALLELIZE_LOOPS,           /* tv_id */
+  PROP_cfg | PROP_ssa,                 /* properties_required */
+  0,                                   /* properties_provided */
+  0,                                   /* properties_destroyed */
+  0,                                   /* todo_flags_start */
+  TODO_dump_func | TODO_verify_loops   /* todo_flags_finish */
+ }
 };
 
 /* Prefetching.  */
 };
 
 /* Prefetching.  */
@@ -436,7 +588,7 @@ struct tree_opt_pass pass_complete_unroll =
 static unsigned int
 tree_ssa_loop_prefetch (void)
 {
 static unsigned int
 tree_ssa_loop_prefetch (void)
 {
-  if (!current_loops)
+  if (number_of_loops () <= 1)
     return 0;
 
   return tree_ssa_prefetch_arrays ();
     return 0;
 
   return tree_ssa_prefetch_arrays ();
@@ -448,8 +600,10 @@ gate_tree_ssa_loop_prefetch (void)
   return flag_prefetch_loop_arrays != 0;
 }
 
   return flag_prefetch_loop_arrays != 0;
 }
 
-struct tree_opt_pass pass_loop_prefetch =
+struct gimple_opt_pass pass_loop_prefetch =
 {
 {
+ {
+  GIMPLE_PASS,
   "aprefetch",                         /* name */
   gate_tree_ssa_loop_prefetch,         /* gate */
   tree_ssa_loop_prefetch,              /* execute */
   "aprefetch",                         /* name */
   gate_tree_ssa_loop_prefetch,         /* gate */
   tree_ssa_loop_prefetch,              /* execute */
@@ -461,8 +615,8 @@ struct tree_opt_pass pass_loop_prefetch =
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
-  TODO_dump_func | TODO_verify_loops,  /* todo_flags_finish */
-  0                                    /* letter */
+  TODO_dump_func | TODO_verify_loops   /* todo_flags_finish */
+ }
 };
 
 /* Induction variable optimizations.  */
 };
 
 /* Induction variable optimizations.  */
@@ -470,7 +624,7 @@ struct tree_opt_pass pass_loop_prefetch =
 static unsigned int
 tree_ssa_loop_ivopts (void)
 {
 static unsigned int
 tree_ssa_loop_ivopts (void)
 {
-  if (!current_loops)
+  if (number_of_loops () <= 1)
     return 0;
 
   tree_ssa_iv_optimize ();
     return 0;
 
   tree_ssa_iv_optimize ();
@@ -483,8 +637,10 @@ gate_tree_ssa_loop_ivopts (void)
   return flag_ivopts != 0;
 }
 
   return flag_ivopts != 0;
 }
 
-struct tree_opt_pass pass_iv_optimize =
+struct gimple_opt_pass pass_iv_optimize =
 {
 {
+ {
+  GIMPLE_PASS,
   "ivopts",                            /* name */
   gate_tree_ssa_loop_ivopts,           /* gate */
   tree_ssa_loop_ivopts,                        /* execute */
   "ivopts",                            /* name */
   gate_tree_ssa_loop_ivopts,           /* gate */
   tree_ssa_loop_ivopts,                        /* execute */
@@ -496,10 +652,9 @@ struct tree_opt_pass pass_iv_optimize =
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
-  TODO_dump_func
-  | TODO_verify_loops
-  | TODO_update_ssa,                   /* todo_flags_finish */
-  0                                    /* letter */
+  TODO_dump_func | TODO_verify_loops
+  | TODO_update_ssa | TODO_ggc_collect /* todo_flags_finish */
+ }
 };
 
 /* Loop optimizer finalization.  */
 };
 
 /* Loop optimizer finalization.  */
@@ -507,17 +662,16 @@ struct tree_opt_pass pass_iv_optimize =
 static unsigned int
 tree_ssa_loop_done (void)
 {
 static unsigned int
 tree_ssa_loop_done (void)
 {
-  if (!current_loops)
-    return 0;
-
   free_numbers_of_iterations_estimates ();
   scev_finalize ();
   loop_optimizer_finalize ();
   return 0;
 }
   
   free_numbers_of_iterations_estimates ();
   scev_finalize ();
   loop_optimizer_finalize ();
   return 0;
 }
   
-struct tree_opt_pass pass_tree_loop_done = 
+struct gimple_opt_pass pass_tree_loop_done = 
 {
 {
+ {
+  GIMPLE_PASS,
   "loopdone",                          /* name */
   NULL,                                        /* gate */
   tree_ssa_loop_done,                  /* execute */
   "loopdone",                          /* name */
   NULL,                                        /* gate */
   tree_ssa_loop_done,                  /* execute */
@@ -529,6 +683,6 @@ struct tree_opt_pass pass_tree_loop_done =
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
-  TODO_cleanup_cfg | TODO_dump_func,   /* todo_flags_finish */
-  0                                    /* letter */
+  TODO_cleanup_cfg | TODO_dump_func    /* todo_flags_finish */
+ }
 };
 };