OSDN Git Service

2005-12-11 Andrew Pinski <pinskia@physics.uc.edu>
[pf3gnuchains/gcc-fork.git] / gcc / passes.c
index fcbb8df..7add120 100644 (file)
@@ -158,8 +158,7 @@ rest_of_decl_compilation (tree decl,
           || DECL_INITIAL (decl))
          && !DECL_EXTERNAL (decl))
        {
-         if (flag_unit_at_a_time && !cgraph_global_info_ready
-             && TREE_CODE (decl) != FUNCTION_DECL)
+         if (TREE_CODE (decl) != FUNCTION_DECL)
            cgraph_varpool_finalize_decl (decl);
          else
            assemble_variable (decl, top_level, at_end, 0);
@@ -237,12 +236,12 @@ finish_optimization_passes (void)
   if (graph_dump_format != no_graph)
     for (i = TDI_end; (dfi = get_dump_file_info (i)) != NULL; ++i)
       if (dump_initialized_p (i)
-         && (dfi->flags & TDF_RTL) != 0
+         && (dfi->flags & TDF_GRAPH) != 0
          && (name = get_dump_file_name (i)) != NULL)
-        {
-          finish_graph_dump_file (name);
-          free (name);
-        }
+       {
+         finish_graph_dump_file (name);
+         free (name);
+       }
 
   timevar_pop (TV_DUMP);
 }
@@ -421,7 +420,25 @@ next_pass_1 (struct tree_opt_pass **list, struct tree_opt_pass *pass)
           
 }
 
-/* Construct the pass tree.  */
+/* Construct the pass tree.  The sequencing of passes is driven by
+   the cgraph routines:
+
+   cgraph_finalize_compilation_unit ()
+       for each node N in the cgraph
+          cgraph_analyze_function (N)
+              cgraph_lower_function (N) -> all_lowering_passes
+
+   If we are optimizing, cgraph_optimize is then invoked:
+
+   cgraph_optimize ()
+       ipa_passes ()                   -> all_ipa_passes
+       cgraph_expand_all_functions ()
+           for each node N in the cgraph
+              cgraph_expand_function (N)
+                  cgraph_lower_function (N)    -> Now a NOP.
+                  lang_hooks.callgraph.expand_function (DECL (N))
+                       tree_rest_of_compilation (DECL (N))  -> all_passes
+*/
 
 void
 init_optimization_passes (void)
@@ -433,15 +450,15 @@ init_optimization_passes (void)
   p = &all_ipa_passes;
   NEXT_PASS (pass_early_ipa_inline);
   NEXT_PASS (pass_early_local_passes);
+  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);
   *p = NULL;
 
-  /* All passes needed to lower the function into shape optimizers can operate
-     on.  These passes are performed before interprocedural passes, unlike rest
-     of local passes (all_passes).  */
+  /* All passes needed to lower the function into shape optimizers can
+     operate on.  */
   p = &all_lowering_passes;
   NEXT_PASS (pass_remove_useless_stmts);
   NEXT_PASS (pass_mudflap_1);
@@ -494,6 +511,12 @@ init_optimization_passes (void)
   NEXT_PASS (pass_merge_phi);
   NEXT_PASS (pass_dominator);
 
+  /* The only copy propagation opportunities left after DOM
+     should be due to degenerate PHI nodes.  So rather than
+     run the full copy propagator, just discover and copy
+     propagate away the degenerate PHI nodes.  */
+  NEXT_PASS (pass_phi_only_copy_prop);
+
   NEXT_PASS (pass_phiopt);
   NEXT_PASS (pass_may_alias);
   NEXT_PASS (pass_tail_recursion);
@@ -508,7 +531,13 @@ init_optimization_passes (void)
   NEXT_PASS (pass_may_alias);
   NEXT_PASS (pass_rename_ssa_copies);
   NEXT_PASS (pass_dominator);
-  NEXT_PASS (pass_copy_prop);
+
+  /* The only copy propagation opportunities left after DOM
+     should be due to degenerate PHI nodes.  So rather than
+     run the full copy propagator, just discover and copy
+     propagate away the degenerate PHI nodes.  */
+  NEXT_PASS (pass_phi_only_copy_prop);
+
   NEXT_PASS (pass_dce);
   NEXT_PASS (pass_dse);
   NEXT_PASS (pass_may_alias);
@@ -529,7 +558,13 @@ init_optimization_passes (void)
   NEXT_PASS (pass_sink_code);
   NEXT_PASS (pass_tree_loop);
   NEXT_PASS (pass_dominator);
-  NEXT_PASS (pass_copy_prop);
+
+  /* The only copy propagation opportunities left after DOM
+     should be due to degenerate PHI nodes.  So rather than
+     run the full copy propagator, just discover and copy
+     propagate away the degenerate PHI nodes.  */
+  NEXT_PASS (pass_phi_only_copy_prop);
+
   NEXT_PASS (pass_cd_dce);
 
   /* FIXME: If DCE is not run before checking for uninitialized uses,
@@ -570,12 +605,16 @@ init_optimization_passes (void)
   /* 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_lower_vector_ssa);
   NEXT_PASS (pass_complete_unroll);
   NEXT_PASS (pass_iv_optimize);
   NEXT_PASS (pass_tree_loop_done);
   *p = NULL;
 
+  p = &pass_vectorize.sub;
+  NEXT_PASS (pass_lower_vector_ssa);
+  NEXT_PASS (pass_dce_loop);
+  *p = NULL;
+
   p = &pass_loop2.sub;
   NEXT_PASS (pass_rtl_loop_init);
   NEXT_PASS (pass_rtl_move_loop_invariants);
@@ -600,7 +639,7 @@ init_optimization_passes (void)
   NEXT_PASS (pass_loop_optimize);
   NEXT_PASS (pass_jump_bypass);
   NEXT_PASS (pass_cfg);
-  NEXT_PASS (pass_profiling);
+  NEXT_PASS (pass_branch_prob);
   NEXT_PASS (pass_rtl_ifcvt);
   NEXT_PASS (pass_tracer);
   /* Perform loop optimizations.  It might be better to do them a bit
@@ -624,12 +663,6 @@ init_optimization_passes (void)
   NEXT_PASS (pass_postreload);
   *p = NULL;
 
-  p = &pass_profiling.sub;
-  NEXT_PASS (pass_branch_prob);
-  NEXT_PASS (pass_value_profile_transformations);
-  NEXT_PASS (pass_remove_death_notes);
-  *p = NULL;
-
   p = &pass_postreload.sub;
   NEXT_PASS (pass_postreload_cse);
   NEXT_PASS (pass_gcse2);
@@ -662,11 +695,9 @@ init_optimization_passes (void)
 #undef NEXT_PASS
 
   /* Register the passes with the tree dump code.  */
+  register_dump_files (all_ipa_passes, true, PROP_gimple_leh | PROP_cfg);
   register_dump_files (all_lowering_passes, false, PROP_gimple_any);
-  register_dump_files (all_passes, false, PROP_gimple_leh
-                                         | PROP_cfg);
-  register_dump_files (all_ipa_passes, true, PROP_gimple_leh
-                                            | PROP_cfg);
+  register_dump_files (all_passes, false, PROP_gimple_leh | PROP_cfg);
 }
 
 static unsigned int last_verified;
@@ -689,6 +720,15 @@ execute_todo (struct tree_opt_pass *pass, unsigned int flags, bool use_required)
        cleanup_tree_cfg_loop ();
       else
        cleanup_tree_cfg ();
+
+      /* When cleanup_tree_cfg merges consecutive blocks, it may
+        perform some simplistic propagation when removing single
+        valued PHI nodes.  This propagation may, in turn, cause the
+        SSA form to become out-of-date (see PR 22037).  So, even
+        if the parent pass had not scheduled an SSA update, we may
+        still need to do one.  */
+      if (!(flags & TODO_update_ssa_any) && need_ssa_update_p ())
+       flags |= TODO_update_ssa;
     }
 
   if (flags & TODO_update_ssa_any)
@@ -704,7 +744,13 @@ execute_todo (struct tree_opt_pass *pass, unsigned int flags, bool use_required)
         dump_function_to_file (current_function_decl,
                                dump_file, dump_flags);
       else if (properties & PROP_cfg)
-        print_rtl_with_bb (dump_file, get_insns ());
+       {
+         print_rtl_with_bb (dump_file, get_insns ());
+
+         if (graph_dump_format != no_graph
+             && (dump_flags & TDF_GRAPH))
+           print_rtl_graph_with_bb (dump_file_name, get_insns ());
+       }
       else
         print_rtl (dump_file, get_insns ());
 
@@ -778,10 +824,15 @@ execute_one_pass (struct tree_opt_pass *pass)
        }
 
       if (initializing_dump
-          && graph_dump_format != no_graph
+         && dump_file
+         && graph_dump_format != no_graph
          && (pass->properties_provided & (PROP_cfg | PROP_rtl))
              == (PROP_cfg | PROP_rtl))
-        clean_graph_dump_file (dump_file_name);
+       {
+         get_dump_file_info (pass->static_pass_number)->flags |= TDF_GRAPH;
+         dump_flags |= TDF_GRAPH;
+         clean_graph_dump_file (dump_file_name);
+       }
     }
 
   /* If a timevar is present, start it.  */