X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fpasses.c;h=6e58d8bbd51284244f168ee23e772ff08ae7ae2f;hb=74fd6a481624213c16c7bb04b5250d40d75f51e5;hp=0faef10b59050f3a8434ea8fff0c91559b4dc8dd;hpb=ec4791a89f84c93ce2d6e9e79be5d3dc914c418e;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/passes.c b/gcc/passes.c index 0faef10b590..6e58d8bbd51 100644 --- a/gcc/passes.c +++ b/gcc/passes.c @@ -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);