OSDN Git Service

2009-05-12 Tobias Burnus <burnus@net-b.de>
[pf3gnuchains/gcc-fork.git] / gcc / passes.c
index ee3826b..b66ed1d 100644 (file)
@@ -1,6 +1,6 @@
 /* Top level of GCC compilers (cc1, cc1plus, etc.)
    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -319,7 +319,7 @@ struct rtl_opt_pass pass_postreload =
   NULL,                                 /* sub */
   NULL,                                 /* next */
   0,                                    /* static_pass_number */
-  0,                                    /* tv_id */
+  TV_NONE,                              /* tv_id */
   PROP_rtl,                             /* properties_required */
   0,                                    /* properties_provided */
   0,                                    /* properties_destroyed */
@@ -368,7 +368,7 @@ get_pass_for_id (int id)
    to do this depth first, and independent of whether the pass is
    enabled or not.  */
 
-static void
+void
 register_one_dump_file (struct opt_pass *pass)
 {
   char *dot_name, *flag_name, *glob_name;
@@ -536,13 +536,13 @@ init_optimization_passes (void)
   NEXT_PASS (pass_early_local_passes);
     {
       struct opt_pass **p = &pass_early_local_passes.pass.sub;
+      NEXT_PASS (pass_fixup_cfg);
       NEXT_PASS (pass_tree_profile);
       NEXT_PASS (pass_cleanup_cfg);
       NEXT_PASS (pass_init_datastructures);
       NEXT_PASS (pass_expand_omp);
 
       NEXT_PASS (pass_referenced_vars);
-      NEXT_PASS (pass_reset_cc_flags);
       NEXT_PASS (pass_build_ssa);
       NEXT_PASS (pass_early_warn_uninitialized);
       NEXT_PASS (pass_all_early_optimizations);
@@ -550,32 +550,24 @@ init_optimization_passes (void)
          struct opt_pass **p = &pass_all_early_optimizations.pass.sub;
          NEXT_PASS (pass_rebuild_cgraph_edges);
          NEXT_PASS (pass_early_inline);
-         NEXT_PASS (pass_cleanup_cfg);
+         NEXT_PASS (pass_remove_cgraph_callee_edges);
          NEXT_PASS (pass_rename_ssa_copies);
          NEXT_PASS (pass_ccp);
          NEXT_PASS (pass_forwprop);
          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);
-          /* Ideally the function call conditional 
-             dead code elimination phase can be delayed
-             till later where potentially more opportunities
-             can be found.  Due to lack of good ways to
-             update VDEFs associated with the shrink-wrapped
-             calls, it is better to do the transformation
-             here where memory SSA is not built yet.  */
-         NEXT_PASS (pass_call_cdce);
-         NEXT_PASS (pass_update_address_taken);
-         NEXT_PASS (pass_simple_dse);
+         NEXT_PASS (pass_cd_dce);
          NEXT_PASS (pass_tail_recursion);
          NEXT_PASS (pass_convert_switch);
+          NEXT_PASS (pass_cleanup_eh);
           NEXT_PASS (pass_profile);
+          NEXT_PASS (pass_local_pure_const);
        }
       NEXT_PASS (pass_release_ssa_names);
       NEXT_PASS (pass_rebuild_cgraph_edges);
+      NEXT_PASS (pass_inline_parameters);
     }
   NEXT_PASS (pass_ipa_increase_alignment);
   NEXT_PASS (pass_ipa_matrix_reorg);
@@ -594,30 +586,29 @@ init_optimization_passes (void)
   NEXT_PASS (pass_all_optimizations);
     {
       struct opt_pass **p = &pass_all_optimizations.pass.sub;
-      /* pass_build_alias is a dummy pass that ensures that we
-        execute TODO_rebuild_alias at this point.  */
-      NEXT_PASS (pass_build_alias);
-      NEXT_PASS (pass_return_slot);
+      NEXT_PASS (pass_remove_cgraph_callee_edges);
+      /* Initial scalar cleanups before alias computation.
+        They ensure memory accesses are not indirect wherever possible.  */
+      NEXT_PASS (pass_strip_predict_hints);
+      NEXT_PASS (pass_update_address_taken);
       NEXT_PASS (pass_rename_ssa_copies);
-      /* Initial scalar cleanups.  */
       NEXT_PASS (pass_complete_unrolli);
       NEXT_PASS (pass_ccp);
+      NEXT_PASS (pass_forwprop);
+      NEXT_PASS (pass_call_cdce);
+      /* pass_build_alias is a dummy pass that ensures that we
+        execute TODO_rebuild_alias at this point.  Re-building
+        alias information also rewrites no longer addressed
+        locals into SSA form if possible.  */
+      NEXT_PASS (pass_build_alias);
+      NEXT_PASS (pass_return_slot);
       NEXT_PASS (pass_phiprop);
       NEXT_PASS (pass_fre);
-      NEXT_PASS (pass_dce);
-      NEXT_PASS (pass_forwprop);
       NEXT_PASS (pass_copy_prop);
       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_tail_recursion);
@@ -639,7 +630,7 @@ init_optimization_passes (void)
       NEXT_PASS (pass_forwprop);
       NEXT_PASS (pass_phiopt);
       NEXT_PASS (pass_object_sizes);
-      NEXT_PASS (pass_store_ccp);
+      NEXT_PASS (pass_ccp);
       NEXT_PASS (pass_copy_prop);
       NEXT_PASS (pass_fold_builtins);
       NEXT_PASS (pass_cse_sincos);
@@ -661,6 +652,7 @@ init_optimization_passes (void)
          NEXT_PASS (pass_check_data_deps);
          NEXT_PASS (pass_loop_distribution);
          NEXT_PASS (pass_linear_transform);
+         NEXT_PASS (pass_graphite_transforms);
          NEXT_PASS (pass_iv_canon);
          NEXT_PASS (pass_if_conversion);
          NEXT_PASS (pass_vectorize);
@@ -705,18 +697,16 @@ init_optimization_passes (void)
       NEXT_PASS (pass_tail_calls);
       NEXT_PASS (pass_rename_ssa_copies);
       NEXT_PASS (pass_uncprop);
+      NEXT_PASS (pass_local_pure_const);
     }
-  NEXT_PASS (pass_del_ssa);
+  NEXT_PASS (pass_cleanup_eh);
   NEXT_PASS (pass_nrv);
-  NEXT_PASS (pass_mark_used_blocks);
+  NEXT_PASS (pass_mudflap_2);
   NEXT_PASS (pass_cleanup_cfg_post_optimizing);
-
   NEXT_PASS (pass_warn_function_noreturn);
-  NEXT_PASS (pass_free_datastructures);
-  NEXT_PASS (pass_mudflap_2);
 
-  NEXT_PASS (pass_free_cfg_annotations);
   NEXT_PASS (pass_expand);
+
   NEXT_PASS (pass_rest_of_compilation);
     {
       struct opt_pass **p = &pass_rest_of_compilation.pass.sub;
@@ -732,7 +722,12 @@ init_optimization_passes (void)
       NEXT_PASS (pass_df_initialize_opt);
       NEXT_PASS (pass_cse);
       NEXT_PASS (pass_rtl_fwprop);
-      NEXT_PASS (pass_gcse);
+      NEXT_PASS (pass_rtl_cprop);
+      NEXT_PASS (pass_rtl_pre);
+      NEXT_PASS (pass_rtl_hoist);
+      NEXT_PASS (pass_rtl_cprop);
+      NEXT_PASS (pass_rtl_store_motion);
+      NEXT_PASS (pass_cse_after_global_opts);
       NEXT_PASS (pass_rtl_ifcvt);
       /* Perform loop optimizations.  It might be better to do them a bit
         sooner, but we want the profile feedback to work more
@@ -749,19 +744,19 @@ init_optimization_passes (void)
          *p = NULL;
        }
       NEXT_PASS (pass_web);
-      NEXT_PASS (pass_jump_bypass);
+      NEXT_PASS (pass_rtl_cprop);
       NEXT_PASS (pass_cse2);
       NEXT_PASS (pass_rtl_dse1);
       NEXT_PASS (pass_rtl_fwprop_addr);
-      NEXT_PASS (pass_regclass_init);
+      NEXT_PASS (pass_reginfo_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_outof_cfg_layout_mode);
       NEXT_PASS (pass_split_all_insns);
       NEXT_PASS (pass_lower_subreg2);
       NEXT_PASS (pass_df_initialize_no_opt);
@@ -772,8 +767,7 @@ init_optimization_passes (void)
       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_ira);
       NEXT_PASS (pass_subregs_of_mode_finish);
       NEXT_PASS (pass_postreload);
        {
@@ -784,7 +778,6 @@ init_optimization_passes (void)
          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);
@@ -846,7 +839,7 @@ do_per_function (void (*callback) (void *data), void *data)
     {
       struct cgraph_node *node;
       for (node = cgraph_nodes; node; node = node->next)
-       if (node->analyzed)
+       if (node->analyzed && gimple_has_body_p (node->decl))
          {
            push_cfun (DECL_STRUCT_FUNCTION (node->decl));
            current_function_decl = node->decl;
@@ -883,11 +876,14 @@ do_per_function_toporder (void (*callback) (void *data), void *data)
       order = GGC_NEWVEC (struct cgraph_node *, cgraph_n_nodes);
       nnodes = cgraph_postorder (order);
       for (i = nnodes - 1; i >= 0; i--)
+        order[i]->process = 1;
+      for (i = nnodes - 1; i >= 0; i--)
        {
          struct cgraph_node *node = order[i];
 
          /* Allow possibly removed nodes to be garbage collected.  */
          order[i] = NULL;
+         node->process = 0;
          if (node->analyzed && (node->needed || node->reachable))
            {
              push_cfun (DECL_STRUCT_FUNCTION (node->decl));
@@ -934,7 +930,7 @@ execute_function_todo (void *data)
         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 ())
+      if (!(flags & TODO_update_ssa_any) && need_ssa_update_p (cfun))
        flags |= TODO_update_ssa;
     }
 
@@ -945,10 +941,14 @@ execute_function_todo (void *data)
       cfun->last_verified &= ~TODO_verify_ssa;
     }
   
+  if (flags & TODO_update_address_taken)
+    execute_update_addresses_taken (true);
+
   if (flags & TODO_rebuild_alias)
     {
+      if (!(flags & TODO_update_address_taken))
+       execute_update_addresses_taken (true);
       compute_may_aliases ();
-      cfun->curr_properties |= PROP_alias;
     }
   
   if (flags & TODO_remove_unused_locals)
@@ -1018,7 +1018,8 @@ static void
 execute_todo (unsigned int flags)
 {
 #if defined ENABLE_CHECKING
-  if (need_ssa_update_p ())
+  if (cfun
+      && need_ssa_update_p (cfun))
     gcc_assert (flags & TODO_update_ssa_any);
 #endif
 
@@ -1199,14 +1200,14 @@ execute_one_ipa_transform_pass (struct cgraph_node *node,
   execute_todo (ipa_pass->function_transform_todo_flags_start);
 
   /* If a timevar is present, start it.  */
-  if (pass->tv_id)
+  if (pass->tv_id != TV_NONE)
     timevar_push (pass->tv_id);
 
   /* Do it!  */
   todo_after = ipa_pass->function_transform (node);
 
   /* Stop timevar.  */
-  if (pass->tv_id)
+  if (pass->tv_id != TV_NONE)
     timevar_pop (pass->tv_id);
 
   /* Run post-pass cleanup and verification.  */
@@ -1262,6 +1263,8 @@ execute_one_pass (struct opt_pass *pass)
      This is a hack until the new folder is ready.  */
   in_gimple_form = (cfun && (cfun->curr_properties & PROP_trees)) != 0;
 
+  initializing_dump = pass_init_dump_file (pass);
+
   /* Run pre-pass verification.  */
   execute_todo (pass->todo_flags_start);
 
@@ -1270,10 +1273,8 @@ execute_one_pass (struct opt_pass *pass)
                   (void *)(size_t)pass->properties_required);
 #endif
 
-  initializing_dump = pass_init_dump_file (pass);
-
   /* If a timevar is present, start it.  */
-  if (pass->tv_id)
+  if (pass->tv_id != TV_NONE)
     timevar_push (pass->tv_id);
 
   /* Do it!  */
@@ -1284,7 +1285,7 @@ execute_one_pass (struct opt_pass *pass)
     }
 
   /* Stop timevar.  */
-  if (pass->tv_id)
+  if (pass->tv_id != TV_NONE)
     timevar_pop (pass->tv_id);
 
   do_per_function (update_properties_after_pass, pass);
@@ -1292,6 +1293,7 @@ execute_one_pass (struct opt_pass *pass)
   if (initializing_dump
       && dump_file
       && graph_dump_format != no_graph
+      && cfun
       && (cfun->curr_properties & (PROP_cfg | PROP_rtl))
          == (PROP_cfg | PROP_rtl))
     {
@@ -1373,4 +1375,30 @@ execute_ipa_pass_list (struct opt_pass *pass)
   while (pass);
 }
 
+/* Called by local passes to see if function is called by already processed nodes.
+   Because we process nodes in topological order, this means that function is
+   in recursive cycle or we introduced new direct calls.  */
+bool
+function_called_by_processed_nodes_p (void)
+{
+  struct cgraph_edge *e;
+  for (e = cgraph_node (current_function_decl)->callers; e; e = e->next_caller)
+    {
+      if (e->caller->decl == current_function_decl)
+        continue;
+      if (!e->caller->analyzed || (!e->caller->needed && !e->caller->reachable))
+        continue;
+      if (TREE_ASM_WRITTEN (e->caller->decl))
+        continue;
+      if (!e->caller->process && !e->caller->global.inlined_to)
+       break;
+    }
+  if (dump_file && e)
+    {
+      fprintf (dump_file, "Already processed call to:\n");
+      dump_cgraph_node (dump_file, e->caller);
+    }
+  return e != NULL;
+}
+
 #include "gt-passes.h"