OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / passes.c
index 0faef10..6e58d8b 100644 (file)
@@ -1,7 +1,7 @@
 /* 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, 2009, 2010
-   Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+   2011, 2012  Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -156,6 +156,11 @@ rest_of_decl_compilation (tree decl,
       {
        alias = TREE_VALUE (TREE_VALUE (alias));
        alias = get_identifier (TREE_STRING_POINTER (alias));
+       /* A quirk of the initial implementation of aliases required that the
+          user add "extern" to all of them.  Which is silly, but now
+          historical.  Do note that the symbol is in fact locally defined.  */
+       if (!lookup_attribute ("weakref", DECL_ATTRIBUTES (decl)))
+         DECL_EXTERNAL (decl) = 0;
        assemble_alias (decl, alias);
       }
   }
@@ -332,7 +337,7 @@ struct rtl_opt_pass pass_postreload =
 
 /* The root of the compilation pass tree, once constructed.  */
 struct opt_pass *all_passes, *all_small_ipa_passes, *all_lowering_passes,
-  *all_regular_ipa_passes, *all_lto_gen_passes;
+  *all_regular_ipa_passes, *all_late_ipa_passes, *all_lto_gen_passes;
 
 /* This is used by plugins, and should also be used in register_pass.  */
 #define DEF_PASS_LIST(LIST) &LIST,
@@ -409,6 +414,7 @@ register_one_dump_file (struct opt_pass *pass)
   set_pass_for_id (id, pass);
   full_name = concat (prefix, pass->name, num, NULL);
   register_pass_name (pass, full_name);
+  free (CONST_CAST (char *, full_name));
 }
 
 /* Recursive worker function for register_dump_files.  */
@@ -617,6 +623,7 @@ dump_passes (void)
   dump_pass_list (all_small_ipa_passes, 1);
   dump_pass_list (all_regular_ipa_passes, 1);
   dump_pass_list (all_lto_gen_passes, 1);
+  dump_pass_list (all_late_ipa_passes, 1);
   dump_pass_list (all_passes, 1);
 
   pop_cfun ();
@@ -702,7 +709,7 @@ enable_disable_pass (const char *arg, bool is_enable)
       if (is_enable)
         error ("unknown pass %s specified in -fenable", phase_name);
       else
-        error ("unknown pass %s specified in -fdisble", phase_name);
+        error ("unknown pass %s specified in -fdisable", phase_name);
       free (argstr);
       return;
     }
@@ -1103,6 +1110,8 @@ register_pass (struct register_pass_info *pass_info)
   if (!success || all_instances)
     success |= position_pass (pass_info, &all_lto_gen_passes);
   if (!success || all_instances)
+    success |= position_pass (pass_info, &all_late_ipa_passes);
+  if (!success || all_instances)
     success |= position_pass (pass_info, &all_passes);
   if (!success)
     fatal_error
@@ -1171,9 +1180,11 @@ init_optimization_passes (void)
   p = &all_lowering_passes;
   NEXT_PASS (pass_warn_unused_result);
   NEXT_PASS (pass_diagnose_omp_blocks);
+  NEXT_PASS (pass_diagnose_tm_blocks);
   NEXT_PASS (pass_mudflap_1);
   NEXT_PASS (pass_lower_omp);
   NEXT_PASS (pass_lower_cf);
+  NEXT_PASS (pass_lower_tm);
   NEXT_PASS (pass_refactor_eh);
   NEXT_PASS (pass_lower_eh);
   NEXT_PASS (pass_build_cfg);
@@ -1238,6 +1249,7 @@ init_optimization_passes (void)
     }
   NEXT_PASS (pass_ipa_increase_alignment);
   NEXT_PASS (pass_ipa_matrix_reorg);
+  NEXT_PASS (pass_ipa_tm);
   NEXT_PASS (pass_ipa_lower_emutls);
   *p = NULL;
 
@@ -1249,7 +1261,6 @@ init_optimization_passes (void)
   NEXT_PASS (pass_ipa_inline);
   NEXT_PASS (pass_ipa_pure_const);
   NEXT_PASS (pass_ipa_reference);
-  NEXT_PASS (pass_ipa_pta);
   *p = NULL;
 
   p = &all_lto_gen_passes;
@@ -1257,9 +1268,16 @@ init_optimization_passes (void)
   NEXT_PASS (pass_ipa_lto_finish_out);  /* This must be the last LTO pass.  */
   *p = NULL;
 
+  /* Simple IPA passes executed after the regular passes.  In WHOPR mode the
+     passes are executed after partitioning and thus see just parts of the
+     compiled unit.  */
+  p = &all_late_ipa_passes;
+  NEXT_PASS (pass_ipa_pta);
+  *p = NULL;
   /* These passes are run after IPA passes on every function that is being
      output to the assembler file.  */
   p = &all_passes;
+  NEXT_PASS (pass_fixup_cfg);
   NEXT_PASS (pass_lower_eh_dispatch);
   NEXT_PASS (pass_all_optimizations);
     {
@@ -1312,6 +1330,7 @@ init_optimization_passes (void)
       NEXT_PASS (pass_forwprop);
       NEXT_PASS (pass_phiopt);
       NEXT_PASS (pass_object_sizes);
+      NEXT_PASS (pass_strlen);
       NEXT_PASS (pass_ccp);
       NEXT_PASS (pass_copy_prop);
       NEXT_PASS (pass_cse_sincos);
@@ -1345,7 +1364,6 @@ init_optimization_passes (void)
          NEXT_PASS (pass_vectorize);
            {
              struct opt_pass **p = &pass_vectorize.pass.sub;
-             NEXT_PASS (pass_lower_vector_ssa);
              NEXT_PASS (pass_dce_loop);
            }
           NEXT_PASS (pass_predcom);
@@ -1354,8 +1372,10 @@ init_optimization_passes (void)
          NEXT_PASS (pass_parallelize_loops);
          NEXT_PASS (pass_loop_prefetch);
          NEXT_PASS (pass_iv_optimize);
+         NEXT_PASS (pass_lim);
          NEXT_PASS (pass_tree_loop_done);
        }
+      NEXT_PASS (pass_lower_vector_ssa);
       NEXT_PASS (pass_cse_reciprocals);
       NEXT_PASS (pass_reassoc);
       NEXT_PASS (pass_vrp);
@@ -1389,6 +1409,13 @@ init_optimization_passes (void)
       NEXT_PASS (pass_uncprop);
       NEXT_PASS (pass_local_pure_const);
     }
+  NEXT_PASS (pass_tm_init);
+    {
+      struct opt_pass **p = &pass_tm_init.pass.sub;
+      NEXT_PASS (pass_tm_mark);
+      NEXT_PASS (pass_tm_memopt);
+      NEXT_PASS (pass_tm_edges);
+    }
   NEXT_PASS (pass_lower_complex_O0);
   NEXT_PASS (pass_cleanup_eh);
   NEXT_PASS (pass_lower_resx);
@@ -1458,13 +1485,14 @@ init_optimization_passes (void)
       NEXT_PASS (pass_sms);
       NEXT_PASS (pass_sched);
       NEXT_PASS (pass_ira);
+      NEXT_PASS (pass_reload);
       NEXT_PASS (pass_postreload);
        {
          struct opt_pass **p = &pass_postreload.pass.sub;
          NEXT_PASS (pass_postreload_cse);
          NEXT_PASS (pass_gcse2);
          NEXT_PASS (pass_split_after_reload);
-         NEXT_PASS (pass_implicit_zee);
+         NEXT_PASS (pass_ree);
          NEXT_PASS (pass_compare_elim_after_reload);
          NEXT_PASS (pass_branch_target_load_optimize1);
          NEXT_PASS (pass_thread_prologue_and_epilogue);
@@ -1497,6 +1525,7 @@ init_optimization_passes (void)
          NEXT_PASS (pass_convert_to_eh_region_ranges);
          NEXT_PASS (pass_shorten_branches);
          NEXT_PASS (pass_set_nothrow_function_flags);
+         NEXT_PASS (pass_dwarf2_frame);
          NEXT_PASS (pass_final);
        }
       NEXT_PASS (pass_df_finish);
@@ -1517,6 +1546,9 @@ init_optimization_passes (void)
   register_dump_files (all_lto_gen_passes,
                       PROP_gimple_any | PROP_gimple_lcf | PROP_gimple_leh
                       | PROP_cfg);
+  register_dump_files (all_late_ipa_passes,
+                      PROP_gimple_any | PROP_gimple_lcf | PROP_gimple_leh
+                      | PROP_cfg);
   register_dump_files (all_passes,
                       PROP_gimple_any | PROP_gimple_lcf | PROP_gimple_leh
                       | PROP_cfg);
@@ -1602,6 +1634,37 @@ do_per_function_toporder (void (*callback) (void *data), void *data)
   nnodes = 0;
 }
 
+/* Helper function to perform function body dump.  */
+
+static void
+execute_function_dump (void *data ATTRIBUTE_UNUSED)
+{
+  if (dump_file && current_function_decl)
+    {
+      if (cfun->curr_properties & PROP_trees)
+        dump_function_to_file (current_function_decl, dump_file, dump_flags);
+      else
+       {
+         if (dump_flags & TDF_SLIM)
+           print_rtl_slim_with_bb (dump_file, get_insns (), dump_flags);
+         else if ((cfun->curr_properties & PROP_cfg)
+                  && (dump_flags & TDF_BLOCKS))
+           print_rtl_with_bb (dump_file, get_insns ());
+          else
+           print_rtl (dump_file, get_insns ());
+
+         if ((cfun->curr_properties & PROP_cfg)
+             && graph_dump_format != no_graph
+             && (dump_flags & TDF_GRAPH))
+           print_rtl_graph_with_bb (dump_file_name, get_insns ());
+       }
+
+      /* Flush the file.  If verification fails, we won't be able to
+        close the file before aborting.  */
+      fflush (dump_file);
+    }
+}
+
 /* Perform all TODO actions that ought to be done on each function.  */
 
 static void
@@ -1648,31 +1711,6 @@ execute_function_todo (void *data)
   if (flags & TODO_remove_unused_locals)
     remove_unused_locals ();
 
-  if ((flags & TODO_dump_func) && dump_file && current_function_decl)
-    {
-      if (cfun->curr_properties & PROP_trees)
-        dump_function_to_file (current_function_decl, dump_file, dump_flags);
-      else
-       {
-         if (dump_flags & TDF_SLIM)
-           print_rtl_slim_with_bb (dump_file, get_insns (), dump_flags);
-         else if ((cfun->curr_properties & PROP_cfg)
-                  && (dump_flags & TDF_BLOCKS))
-           print_rtl_with_bb (dump_file, get_insns ());
-          else
-           print_rtl (dump_file, get_insns ());
-
-         if ((cfun->curr_properties & PROP_cfg)
-             && graph_dump_format != no_graph
-             && (dump_flags & TDF_GRAPH))
-           print_rtl_graph_with_bb (dump_file_name, get_insns ());
-       }
-
-      /* Flush the file.  If verification fails, we won't be able to
-        close the file before aborting.  */
-      fflush (dump_file);
-    }
-
   if (flags & TODO_rebuild_frequencies)
     rebuild_frequencies ();
 
@@ -1686,11 +1724,14 @@ execute_function_todo (void *data)
 #if defined ENABLE_CHECKING
   if (flags & TODO_verify_ssa
       || (current_loops && loops_state_satisfies_p (LOOP_CLOSED_SSA)))
-    verify_ssa (true);
+    {
+      verify_gimple_in_cfg (cfun);
+      verify_ssa (true);
+    }
+  else if (flags & TODO_verify_stmts)
+    verify_gimple_in_cfg (cfun);
   if (flags & TODO_verify_flow)
     verify_flow_info ();
-  if (flags & TODO_verify_stmts)
-    verify_gimple_in_cfg (cfun);
   if (current_loops && loops_state_satisfies_p (LOOP_CLOSED_SSA))
     verify_loop_closed_ssa (false);
   if (flags & TODO_verify_rtl_sharing)
@@ -1898,6 +1939,7 @@ execute_one_ipa_transform_pass (struct cgraph_node *node,
   execute_todo (todo_after);
   verify_interpass_invariants ();
 
+  do_per_function (execute_function_dump, NULL);
   pass_fini_dump_file (pass);
 
   current_pass = NULL;
@@ -1928,6 +1970,20 @@ execute_all_ipa_transforms (void)
     }
 }
 
+/* Callback for do_per_function to apply all IPA transforms.  */
+
+static void
+apply_ipa_transforms (void *data)
+{
+  struct cgraph_node *node = cgraph_get_node (current_function_decl);
+  if (!node->global.inlined_to && node->ipa_transforms_to_apply)
+    {
+      *(bool *)data = true;
+      execute_all_ipa_transforms();
+      rebuild_cgraph_edges ();
+    }
+}
+
 /* Check if PASS is explicitly disabled or enabled and return
    the gate status.  FUNC is the function to be processed, and
    GATE_STATUS is the gate status determined by pass manager by
@@ -1989,6 +2045,18 @@ execute_one_pass (struct opt_pass *pass)
      executed.  */
   invoke_plugin_callbacks (PLUGIN_PASS_EXECUTION, pass);
 
+  /* SIPLE IPA passes do not handle callgraphs with IPA transforms in it.
+     Apply all trnasforms first.  */
+  if (pass->type == SIMPLE_IPA_PASS)
+    {
+      bool applied = false;
+      do_per_function (apply_ipa_transforms, (void *)&applied);
+      if (applied)
+        cgraph_remove_unreachable_nodes (true, dump_file);
+      /* Restore current_pass.  */
+      current_pass = pass;
+    }
+
   if (!quiet_flag && !cfun)
     fprintf (stderr, " <%s>", pass->name ? pass->name : "");
 
@@ -2038,6 +2106,7 @@ execute_one_pass (struct opt_pass *pass)
   /* Run post-pass cleanup and verification.  */
   execute_todo (todo_after | pass->todo_flags_finish);
   verify_interpass_invariants ();
+  do_per_function (execute_function_dump, NULL);
   if (pass->type == IPA_PASS)
     {
       struct cgraph_node *node;
@@ -2182,7 +2251,7 @@ ipa_write_summaries (void)
   vset = varpool_node_set_new ();
 
   for (vnode = varpool_nodes; vnode; vnode = vnode->next)
-    if (vnode->needed && !vnode->alias)
+    if (vnode->needed && (!vnode->alias || vnode->alias_of))
       varpool_node_set_add (vset, vnode);
 
   ipa_write_summaries_1 (set, vset);