OSDN Git Service

* gcc.target/i386/sse-17.c: Include sse2-check.h.
[pf3gnuchains/gcc-fork.git] / gcc / passes.c
index 6f1a99d..833bdbd 100644 (file)
@@ -7,7 +7,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 Free
-Software Foundation; either version 2, or (at your option) any later
+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 ANY
@@ -16,9 +16,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
-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/>.  */
 
 /* This is the top level of cc1/c++.
    It parses command args, opens files, invokes the various passes
@@ -83,6 +82,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 #include "tree-flow.h"
 #include "tree-pass.h"
 #include "tree-dump.h"
+#include "df.h"
 #include "predict.h"
 
 #if defined (DWARF2_UNWIND_INFO) || defined (DWARF2_DEBUGGING_INFO)
@@ -102,9 +102,37 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
                                   declarations for e.g. AIX 4.x.  */
 #endif
 
+/* This is used for debugging.  It allows the current pass to printed
+   from anywhere in compilation.  */
+struct opt_pass *current_pass;
+
+/* Call from anywhere to find out what pass this is.  Useful for
+   printing out debugging information deep inside an service
+   routine.  */
+void
+print_current_pass (FILE *file)
+{
+  if (current_pass)
+    fprintf (file, "current pass = %s (%d)\n", 
+            current_pass->name, current_pass->static_pass_number);
+  else
+    fprintf (file, "no current pass.\n");
+}
+
+
+/* Call from the debugger to get the current pass name.  */
+void
+debug_pass (void)
+{
+  print_current_pass (stderr);
+} 
+
+
+
 /* Global variables used to communicate with passes.  */
 int dump_flags;
 bool in_gimple_form;
+bool first_pass_instance;
 
 
 /* This is called from various places for FUNCTION_DECL, VAR_DECL,
@@ -218,19 +246,19 @@ finish_optimization_passes (void)
   timevar_push (TV_DUMP);
   if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
     {
-      dump_file = dump_begin (pass_profile.static_pass_number, NULL);
+      dump_file = dump_begin (pass_profile.pass.static_pass_number, NULL);
       end_branch_prob ();
       if (dump_file)
-       dump_end (pass_profile.static_pass_number, dump_file);
+       dump_end (pass_profile.pass.static_pass_number, dump_file);
     }
 
   if (optimize > 0)
     {
-      dump_file = dump_begin (pass_combine.static_pass_number, NULL);
+      dump_file = dump_begin (pass_combine.pass.static_pass_number, NULL);
       if (dump_file)
        {
          dump_combine_total_stats (dump_file);
-          dump_end (pass_combine.static_pass_number, dump_file);
+          dump_end (pass_combine.pass.static_pass_number, dump_file);
        }
     }
 
@@ -256,8 +284,10 @@ gate_rest_of_compilation (void)
   return !(rtl_dump_and_exit || flag_syntax_only || errorcount || sorrycount);
 }
 
-struct tree_opt_pass pass_rest_of_compilation =
+struct gimple_opt_pass pass_rest_of_compilation =
 {
+ {
+  GIMPLE_PASS,
   NULL,                                 /* name */
   gate_rest_of_compilation,             /* gate */
   NULL,                                 /* execute */
@@ -269,8 +299,8 @@ struct tree_opt_pass pass_rest_of_compilation =
   0,                                    /* properties_provided */
   0,                                    /* properties_destroyed */
   0,                                    /* todo_flags_start */
-  TODO_ggc_collect,                     /* todo_flags_finish */
-  0                                     /* letter */
+  TODO_ggc_collect                      /* todo_flags_finish */
+ }
 };
 
 static bool
@@ -279,8 +309,10 @@ gate_postreload (void)
   return reload_completed;
 }
 
-struct tree_opt_pass pass_postreload =
+struct rtl_opt_pass pass_postreload =
 {
+ {
+  RTL_PASS,
   NULL,                                 /* name */
   gate_postreload,                      /* gate */
   NULL,                                 /* execute */
@@ -292,21 +324,21 @@ struct tree_opt_pass pass_postreload =
   0,                                    /* properties_provided */
   0,                                    /* properties_destroyed */
   0,                                    /* todo_flags_start */
-  TODO_ggc_collect,                     /* todo_flags_finish */
-  0                                    /* letter */
+  TODO_ggc_collect | TODO_verify_rtl_sharing /* todo_flags_finish */
+ }
 };
 
 
 
 /* The root of the compilation pass tree, once constructed.  */
-struct tree_opt_pass *all_passes, *all_ipa_passes, *all_lowering_passes;
+struct opt_pass *all_passes, *all_ipa_passes, *all_lowering_passes;
 
 /* Iterate over the pass tree allocating dump file numbers.  We want
    to do this depth first, and independent of whether the pass is
    enabled or not.  */
 
 static void
-register_one_dump_file (struct tree_opt_pass *pass, bool ipa, int properties)
+register_one_dump_file (struct opt_pass *pass, bool ipa, int properties)
 {
   char *dot_name, *flag_name, *glob_name;
   const char *prefix;
@@ -330,13 +362,13 @@ register_one_dump_file (struct tree_opt_pass *pass, bool ipa, int properties)
   flag_name = concat (prefix, pass->name, num, NULL);
   glob_name = concat (prefix, pass->name, NULL);
   pass->static_pass_number = dump_register (dot_name, flag_name, glob_name,
-                                            flags, pass->letter);
+                                            flags);
 }
 
 /* Recursive worker function for register_dump_files.  */
 
 static int 
-register_dump_files_1 (struct tree_opt_pass *pass, bool ipa, int properties)
+register_dump_files_1 (struct opt_pass *pass, bool ipa, int properties)
 {
   do
     {
@@ -370,7 +402,7 @@ register_dump_files_1 (struct tree_opt_pass *pass, bool ipa, int properties)
    the pipeline.  */
 
 static void 
-register_dump_files (struct tree_opt_pass *pass, bool ipa, int properties)
+register_dump_files (struct opt_pass *pass, bool ipa, int properties)
 {
   pass->properties_required |= properties;
   register_dump_files_1 (pass, ipa, properties);
@@ -379,17 +411,20 @@ register_dump_files (struct tree_opt_pass *pass, bool ipa, int properties)
 /* Add a pass to the pass list. Duplicate the pass if it's already
    in the list.  */
 
-static struct tree_opt_pass **
-next_pass_1 (struct tree_opt_pass **list, struct tree_opt_pass *pass)
+static struct opt_pass **
+next_pass_1 (struct opt_pass **list, struct opt_pass *pass)
 {
   /* A nonzero static_pass_number indicates that the
      pass is already in the list.  */
   if (pass->static_pass_number)
     {
-      struct tree_opt_pass *new;
+      struct opt_pass *new;
 
       new = xmalloc (sizeof (*new));
       memcpy (new, pass, sizeof (*new));
+      new->next = NULL;
+
+      new->todo_flags_start &= ~TODO_mark_first_instance;
 
       /* Indicate to register_dump_files that this pass has duplicates,
          and so it should rename the dump file.  The first instance will
@@ -405,6 +440,7 @@ next_pass_1 (struct tree_opt_pass **list, struct tree_opt_pass *pass)
     }
   else
     {
+      pass->todo_flags_start |= TODO_mark_first_instance;
       pass->static_pass_number = -1;
       *list = pass;
     }  
@@ -413,6 +449,7 @@ next_pass_1 (struct tree_opt_pass **list, struct tree_opt_pass *pass)
           
 }
 
+
 /* Construct the pass tree.  The sequencing of passes is driven by
    the cgraph routines:
 
@@ -428,16 +465,15 @@ next_pass_1 (struct tree_opt_pass **list, struct tree_opt_pass *pass)
        cgraph_expand_all_functions ()
            for each node N in the cgraph
               cgraph_expand_function (N)
-                  lang_hooks.callgraph.expand_function (DECL (N))
-                       tree_rest_of_compilation (DECL (N))  -> all_passes
+                 tree_rest_of_compilation (DECL (N))  -> all_passes
 */
 
 void
 init_optimization_passes (void)
 {
-  struct tree_opt_pass **p;
+  struct opt_pass **p;
 
-#define NEXT_PASS(PASS)  (p = next_pass_1 (p, &PASS))
+#define NEXT_PASS(PASS)  (p = next_pass_1 (p, &((PASS).pass)))
 
  /* All passes needed to lower the function into shape optimizers can
     operate on.  These passes are always run first on the function, but
@@ -448,6 +484,7 @@ init_optimization_passes (void)
   NEXT_PASS (pass_mudflap_1);
   NEXT_PASS (pass_lower_omp);
   NEXT_PASS (pass_lower_cf);
+  NEXT_PASS (pass_refactor_eh);
   NEXT_PASS (pass_lower_eh);
   NEXT_PASS (pass_build_cfg);
   NEXT_PASS (pass_lower_complex_O0);
@@ -459,29 +496,30 @@ init_optimization_passes (void)
 
   /* Interprocedural optimization passes. 
      All these passes are ignored in -fno-unit-at-a-time
-     except for subpases of early_local_pases.  */
+     except for subpasses of early_local_passes.  */
   p = &all_ipa_passes;
   NEXT_PASS (pass_ipa_function_and_variable_visibility);
   NEXT_PASS (pass_ipa_early_inline);
     {
-      struct tree_opt_pass **p = &pass_ipa_early_inline.sub;
+      struct opt_pass **p = &pass_ipa_early_inline.pass.sub;
       NEXT_PASS (pass_early_inline);
       NEXT_PASS (pass_inline_parameters);
       NEXT_PASS (pass_rebuild_cgraph_edges);
     }
   NEXT_PASS (pass_early_local_passes);
     {
-      struct tree_opt_pass **p = &pass_early_local_passes.sub;
+      struct opt_pass **p = &pass_early_local_passes.pass.sub;
       NEXT_PASS (pass_tree_profile);
       NEXT_PASS (pass_cleanup_cfg);
       NEXT_PASS (pass_init_datastructures);
       NEXT_PASS (pass_expand_omp);
       NEXT_PASS (pass_all_early_optimizations);
        {
-         struct tree_opt_pass **p = &pass_all_early_optimizations.sub;
+         struct opt_pass **p = &pass_all_early_optimizations.pass.sub;
          NEXT_PASS (pass_referenced_vars);
          NEXT_PASS (pass_reset_cc_flags);
          NEXT_PASS (pass_build_ssa);
+         NEXT_PASS (pass_expand_omp_ssa);
          NEXT_PASS (pass_early_warn_uninitialized);
          NEXT_PASS (pass_rebuild_cgraph_edges);
          NEXT_PASS (pass_early_inline);
@@ -489,10 +527,14 @@ init_optimization_passes (void)
          NEXT_PASS (pass_rename_ssa_copies);
          NEXT_PASS (pass_ccp);
          NEXT_PASS (pass_forwprop);
-         NEXT_PASS (pass_sra);
+         NEXT_PASS (pass_update_address_taken);
+         NEXT_PASS (pass_simple_dse);
+         NEXT_PASS (pass_sra_early);
          NEXT_PASS (pass_copy_prop);
          NEXT_PASS (pass_merge_phi);
          NEXT_PASS (pass_dce);
+         NEXT_PASS (pass_update_address_taken);
+         NEXT_PASS (pass_simple_dse);
          NEXT_PASS (pass_tail_recursion);
           NEXT_PASS (pass_profile);
          NEXT_PASS (pass_release_ssa_names);
@@ -501,12 +543,14 @@ init_optimization_passes (void)
       NEXT_PASS (pass_inline_parameters);
     }
   NEXT_PASS (pass_ipa_increase_alignment);
+  NEXT_PASS (pass_ipa_matrix_reorg);
   NEXT_PASS (pass_ipa_cp);
   NEXT_PASS (pass_ipa_inline);
   NEXT_PASS (pass_ipa_reference);
   NEXT_PASS (pass_ipa_pure_const); 
   NEXT_PASS (pass_ipa_type_escape);
   NEXT_PASS (pass_ipa_pta);
+  NEXT_PASS (pass_ipa_struct_reorg);  
   *p = NULL;
 
   /* These passes are run after IPA passes on every function that is being
@@ -515,14 +559,18 @@ init_optimization_passes (void)
   NEXT_PASS (pass_apply_inline);
   NEXT_PASS (pass_all_optimizations);
     {
-      struct tree_opt_pass **p = &pass_all_optimizations.sub;
+      struct opt_pass **p = &pass_all_optimizations.pass.sub;
       NEXT_PASS (pass_create_structure_vars);
-      NEXT_PASS (pass_may_alias);
+      /* ??? pass_build_alias is a dummy pass that ensures that we
+        execute TODO_rebuild_alias at this point even if
+        pass_create_structure_vars was disabled.  */
+      NEXT_PASS (pass_build_alias);
       NEXT_PASS (pass_return_slot);
       NEXT_PASS (pass_rename_ssa_copies);
 
       /* Initial scalar cleanups.  */
       NEXT_PASS (pass_ccp);
+      NEXT_PASS (pass_phiprop);
       NEXT_PASS (pass_fre);
       NEXT_PASS (pass_dce);
       NEXT_PASS (pass_forwprop);
@@ -530,26 +578,21 @@ init_optimization_passes (void)
       NEXT_PASS (pass_merge_phi);
       NEXT_PASS (pass_vrp);
       NEXT_PASS (pass_dce);
+      NEXT_PASS (pass_cselim);
       NEXT_PASS (pass_dominator);
-
       /* The only const/copy propagation opportunities left after
         DOM should be due to degenerate PHI nodes.  So rather than
         run the full propagators, run a specialized pass which
         only examines PHIs to discover const/copy propagation
         opportunities.  */
       NEXT_PASS (pass_phi_only_cprop);
-
+      NEXT_PASS (pass_tree_ifcombine);
       NEXT_PASS (pass_phiopt);
-      NEXT_PASS (pass_may_alias);
       NEXT_PASS (pass_tail_recursion);
       NEXT_PASS (pass_ch);
       NEXT_PASS (pass_stdarg);
       NEXT_PASS (pass_lower_complex);
       NEXT_PASS (pass_sra);
-      /* FIXME: SRA may generate arbitrary gimple code, exposing new
-        aliased and call-clobbered variables.  As mentioned below,
-        pass_may_alias should be a TODO item.  */
-      NEXT_PASS (pass_may_alias);
       NEXT_PASS (pass_rename_ssa_copies);
       NEXT_PASS (pass_dominator);
 
@@ -563,54 +606,51 @@ init_optimization_passes (void)
       NEXT_PASS (pass_reassoc);
       NEXT_PASS (pass_dce);
       NEXT_PASS (pass_dse);
-      NEXT_PASS (pass_may_alias);
       NEXT_PASS (pass_forwprop);
       NEXT_PASS (pass_phiopt);
       NEXT_PASS (pass_object_sizes);
       NEXT_PASS (pass_store_ccp);
-      NEXT_PASS (pass_store_copy_prop);
+      NEXT_PASS (pass_copy_prop);
       NEXT_PASS (pass_fold_builtins);
       NEXT_PASS (pass_cse_sincos);
-      /* FIXME: May alias should a TODO but for 4.0.0,
-        we add may_alias right after fold builtins
-        which can create arbitrary GIMPLE.  */
-      NEXT_PASS (pass_may_alias);
       NEXT_PASS (pass_split_crit_edges);
       NEXT_PASS (pass_pre);
-      NEXT_PASS (pass_may_alias);
       NEXT_PASS (pass_sink_code);
       NEXT_PASS (pass_tree_loop);
        {
-         struct tree_opt_pass **p = &pass_tree_loop.sub;
+         struct opt_pass **p = &pass_tree_loop.pass.sub;
          NEXT_PASS (pass_tree_loop_init);
          NEXT_PASS (pass_copy_prop);
+         NEXT_PASS (pass_dce_loop);
          NEXT_PASS (pass_lim);
+         NEXT_PASS (pass_predcom);
          NEXT_PASS (pass_tree_unswitch);
          NEXT_PASS (pass_scev_cprop);
          NEXT_PASS (pass_empty_loop);
          NEXT_PASS (pass_record_bounds);
+         NEXT_PASS (pass_check_data_deps);
+         NEXT_PASS (pass_loop_distribution);
          NEXT_PASS (pass_linear_transform);
          NEXT_PASS (pass_iv_canon);
          NEXT_PASS (pass_if_conversion);
          NEXT_PASS (pass_vectorize);
            {
-             struct tree_opt_pass **p = &pass_vectorize.sub;
+             struct opt_pass **p = &pass_vectorize.pass.sub;
              NEXT_PASS (pass_lower_vector_ssa);
              NEXT_PASS (pass_dce_loop);
            }
-         /* NEXT_PASS (pass_may_alias) cannot be done again because the
-            vectorizer creates alias relations that are not supported by
-            pass_may_alias.  */
          NEXT_PASS (pass_complete_unroll);
+         NEXT_PASS (pass_parallelize_loops);
          NEXT_PASS (pass_loop_prefetch);
          NEXT_PASS (pass_iv_optimize);
          NEXT_PASS (pass_tree_loop_done);
        }
       NEXT_PASS (pass_cse_reciprocals);
+      NEXT_PASS (pass_convert_to_rsqrt);
       NEXT_PASS (pass_reassoc);
       NEXT_PASS (pass_vrp);
       NEXT_PASS (pass_dominator);
-
+      
       /* The only const/copy propagation opportunities left after
         DOM should be due to degenerate PHI nodes.  So rather than
         run the full propagators, run a specialized pass which
@@ -619,6 +659,7 @@ init_optimization_passes (void)
       NEXT_PASS (pass_phi_only_cprop);
 
       NEXT_PASS (pass_cd_dce);
+      NEXT_PASS (pass_tracer);
 
       /* FIXME: If DCE is not run before checking for uninitialized uses,
         we may get false warnings (e.g., testsuite/gcc.dg/uninit-5.c).
@@ -648,28 +689,27 @@ init_optimization_passes (void)
   NEXT_PASS (pass_expand);
   NEXT_PASS (pass_rest_of_compilation);
     {
-      struct tree_opt_pass **p = &pass_rest_of_compilation.sub;
+      struct opt_pass **p = &pass_rest_of_compilation.pass.sub;
       NEXT_PASS (pass_init_function);
       NEXT_PASS (pass_jump);
-      NEXT_PASS (pass_insn_locators_initialize);
       NEXT_PASS (pass_rtl_eh);
       NEXT_PASS (pass_initial_value_sets);
       NEXT_PASS (pass_unshare_all_rtl);
       NEXT_PASS (pass_instantiate_virtual_regs);
+      NEXT_PASS (pass_into_cfg_layout_mode);
       NEXT_PASS (pass_jump2);
       NEXT_PASS (pass_lower_subreg);
+      NEXT_PASS (pass_df_initialize_opt);
       NEXT_PASS (pass_cse);
       NEXT_PASS (pass_rtl_fwprop);
       NEXT_PASS (pass_gcse);
-      NEXT_PASS (pass_jump_bypass);
       NEXT_PASS (pass_rtl_ifcvt);
-      NEXT_PASS (pass_tracer);
       /* Perform loop optimizations.  It might be better to do them a bit
         sooner, but we want the profile feedback to work more
         efficiently.  */
       NEXT_PASS (pass_loop2);
        {
-         struct tree_opt_pass **p = &pass_loop2.sub;
+         struct opt_pass **p = &pass_loop2.pass.sub;
          NEXT_PASS (pass_rtl_loop_init);
          NEXT_PASS (pass_rtl_move_loop_invariants);
          NEXT_PASS (pass_rtl_unswitch);
@@ -679,39 +719,59 @@ init_optimization_passes (void)
          *p = NULL;
        }
       NEXT_PASS (pass_web);
+      NEXT_PASS (pass_jump_bypass);
       NEXT_PASS (pass_cse2);
+      NEXT_PASS (pass_rtl_dse1);
       NEXT_PASS (pass_rtl_fwprop_addr);
-      NEXT_PASS (pass_life);
+      NEXT_PASS (pass_regclass_init);
+      NEXT_PASS (pass_inc_dec);
+      NEXT_PASS (pass_initialize_regs);
+      NEXT_PASS (pass_outof_cfg_layout_mode);
+      NEXT_PASS (pass_ud_rtl_dce);
       NEXT_PASS (pass_combine);
       NEXT_PASS (pass_if_after_combine);
       NEXT_PASS (pass_partition_blocks);
       NEXT_PASS (pass_regmove);
       NEXT_PASS (pass_split_all_insns);
       NEXT_PASS (pass_lower_subreg2);
+      NEXT_PASS (pass_df_initialize_no_opt);
+      NEXT_PASS (pass_stack_ptr_mod);
       NEXT_PASS (pass_mode_switching);
       NEXT_PASS (pass_see);
-      NEXT_PASS (pass_recompute_reg_usage);
+      NEXT_PASS (pass_match_asm_constraints);
       NEXT_PASS (pass_sms);
       NEXT_PASS (pass_sched);
+      NEXT_PASS (pass_subregs_of_mode_init);
       NEXT_PASS (pass_local_alloc);
       NEXT_PASS (pass_global_alloc);
+      NEXT_PASS (pass_subregs_of_mode_finish);
       NEXT_PASS (pass_postreload);
        {
-         struct tree_opt_pass **p = &pass_postreload.sub;
+         struct opt_pass **p = &pass_postreload.pass.sub;
          NEXT_PASS (pass_postreload_cse);
          NEXT_PASS (pass_gcse2);
-         NEXT_PASS (pass_flow2);
+         NEXT_PASS (pass_split_after_reload);
+         NEXT_PASS (pass_branch_target_load_optimize1);
+         NEXT_PASS (pass_thread_prologue_and_epilogue);
+         NEXT_PASS (pass_rtl_dse2);
          NEXT_PASS (pass_rtl_seqabstr);
          NEXT_PASS (pass_stack_adjustments);
          NEXT_PASS (pass_peephole2);
          NEXT_PASS (pass_if_after_reload);
          NEXT_PASS (pass_regrename);
+         NEXT_PASS (pass_cprop_hardreg);
+         NEXT_PASS (pass_fast_rtl_dce);
          NEXT_PASS (pass_reorder_blocks);
-         NEXT_PASS (pass_branch_target_load_optimize);
+         NEXT_PASS (pass_branch_target_load_optimize2);
          NEXT_PASS (pass_leaf_regs);
+         NEXT_PASS (pass_split_before_sched2);
          NEXT_PASS (pass_sched2);
-         NEXT_PASS (pass_split_before_regstack);
          NEXT_PASS (pass_stack_regs);
+           {
+             struct opt_pass **p = &pass_stack_regs.pass.sub;
+             NEXT_PASS (pass_split_before_regstack);
+             NEXT_PASS (pass_stack_regs_run);
+           }
          NEXT_PASS (pass_compute_alignments);
          NEXT_PASS (pass_duplicate_computed_gotos);
          NEXT_PASS (pass_variable_tracking);
@@ -725,6 +785,7 @@ init_optimization_passes (void)
          NEXT_PASS (pass_set_nothrow_function_flags);
          NEXT_PASS (pass_final);
        }
+      NEXT_PASS (pass_df_finish);
     }
   NEXT_PASS (pass_clean_state);
   *p = NULL;
@@ -830,12 +891,7 @@ execute_function_todo (void *data)
   /* Always cleanup the CFG before trying to update SSA.  */
   if (flags & TODO_cleanup_cfg)
     {
-      bool cleanup;
-
-      if (current_loops)
-       cleanup = cleanup_tree_cfg_loop ();
-      else
-       cleanup = cleanup_tree_cfg ();
+      bool cleanup = cleanup_tree_cfg ();
 
       if (cleanup && (cfun->curr_properties & PROP_ssa))
        flags |= TODO_remove_unused_locals;
@@ -856,7 +912,13 @@ execute_function_todo (void *data)
       update_ssa (update_flags);
       cfun->last_verified &= ~TODO_verify_ssa;
     }
-
+  
+  if (flags & TODO_rebuild_alias)
+    {
+      compute_may_aliases ();
+      cfun->curr_properties |= PROP_alias;
+    }
+  
   if (flags & TODO_remove_unused_locals)
     remove_unused_locals ();
 
@@ -914,6 +976,8 @@ execute_function_todo (void *data)
     verify_stmts ();
   if (flags & TODO_verify_loops)
     verify_loop_closed_ssa ();
+  if (flags & TODO_verify_rtl_sharing)
+    verify_rtl_sharing ();
 #endif
 
   cfun->last_verified = flags & TODO_verify_all;
@@ -928,6 +992,9 @@ execute_todo (unsigned int flags)
     gcc_assert (flags & TODO_update_ssa_any);
 #endif
 
+  /* Inform the pass whether it is the first time it is run.  */
+  first_pass_instance = (flags & TODO_mark_first_instance) != 0;
+
   do_per_function (execute_function_todo, (void *)(size_t) flags);
 
   /* Always remove functions just as before inlining: IPA passes might be
@@ -950,6 +1017,11 @@ execute_todo (unsigned int flags)
     {
       ggc_collect ();
     }
+
+  /* Now that the dumping has been done, we can get rid of the optional 
+     df problems.  */
+  if (flags & TODO_df_finish)
+    df_finish_pass ((flags & TODO_df_verify) != 0);
 }
 
 /* Verify invariants that should hold between passes.  This is a place
@@ -988,17 +1060,18 @@ verify_curr_properties (void *data)
 static void
 update_properties_after_pass (void *data)
 {
-  struct tree_opt_pass *pass = data;
+  struct opt_pass *pass = data;
   cfun->curr_properties = (cfun->curr_properties | pass->properties_provided)
                           & ~pass->properties_destroyed;
 }
 
 static bool
-execute_one_pass (struct tree_opt_pass *pass)
+execute_one_pass (struct opt_pass *pass)
 {
   bool initializing_dump;
   unsigned int todo_after = 0;
 
+  current_pass = pass;
   /* See if we're supposed to run this pass.  */
   if (pass->gate && !pass->gate ())
     return false;
@@ -1082,7 +1155,7 @@ execute_one_pass (struct tree_opt_pass *pass)
   /* Flush and close dump file.  */
   if (dump_file_name)
     {
-      free ((char *) dump_file_name);
+      free (CONST_CAST (char *, dump_file_name));
       dump_file_name = NULL;
     }
 
@@ -1092,6 +1165,7 @@ execute_one_pass (struct tree_opt_pass *pass)
       dump_file = NULL;
     }
 
+  current_pass = NULL;
   /* Reset in_gimple_form to not break non-unit-at-a-time mode.  */
   in_gimple_form = false;
 
@@ -1099,7 +1173,7 @@ execute_one_pass (struct tree_opt_pass *pass)
 }
 
 void
-execute_pass_list (struct tree_opt_pass *pass)
+execute_pass_list (struct opt_pass *pass)
 {
   do
     {
@@ -1113,7 +1187,7 @@ execute_pass_list (struct tree_opt_pass *pass)
 /* Same as execute_pass_list but assume that subpasses of IPA passes
    are local passes.  */
 void
-execute_ipa_pass_list (struct tree_opt_pass *pass)
+execute_ipa_pass_list (struct opt_pass *pass)
 {
   do
     {