Mercurial > hg > CbC > CbC_gcc
diff gcc/passes.c @ 63:b7f97abdc517 gcc-4.6-20100522
update gcc from gcc-4.5.0 to gcc-4.6
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 24 May 2010 12:47:05 +0900 |
parents | 77e2b8dfacca |
children | f6334be47118 |
line wrap: on
line diff
--- a/gcc/passes.c Fri Feb 12 23:41:23 2010 +0900 +++ b/gcc/passes.c Mon May 24 12:47:05 2010 +0900 @@ -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, 2009 + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. This file is part of GCC. @@ -25,8 +25,6 @@ Error messages and low-level interface to malloc also handled here. */ #include "config.h" -#undef FLOAT /* This is for hpux. They should change hpux. */ -#undef FFS /* Some systems define this in param.h. */ #include "system.h" #include "coretypes.h" #include "tm.h" @@ -67,7 +65,6 @@ #include "reload.h" #include "dwarf2asm.h" #include "integrate.h" -#include "real.h" #include "debug.h" #include "target.h" #include "langhooks.h" @@ -191,7 +188,11 @@ || DECL_INITIAL (decl)) && !DECL_EXTERNAL (decl)) { - if (TREE_CODE (decl) != FUNCTION_DECL) + /* When reading LTO unit, we also read varpool, so do not + rebuild it. */ + if (in_lto_p && !at_end) + ; + else if (TREE_CODE (decl) != FUNCTION_DECL) varpool_finalize_decl (decl); else assemble_variable (decl, top_level, at_end, 0); @@ -218,7 +219,9 @@ } /* Let cgraph know about the existence of variables. */ - if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl)) + if (in_lto_p && !at_end) + ; + else if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl)) varpool_node (decl); } @@ -632,6 +635,8 @@ void register_pass (struct register_pass_info *pass_info) { + bool all_instances, success; + /* The checks below could fail in buggy plugins. Existing GCC passes should never fail these checks, so we mention plugin in the messages. */ @@ -647,46 +652,50 @@ pass_info->pass->name); /* Try to insert the new pass to the pass lists. We need to check - all three lists as the reference pass could be in one (or all) of + all five lists as the reference pass could be in one (or all) of them. */ - if (!position_pass (pass_info, &all_lowering_passes) - && !position_pass (pass_info, &all_small_ipa_passes) - && !position_pass (pass_info, &all_regular_ipa_passes) - && !position_pass (pass_info, &all_lto_gen_passes) - && !position_pass (pass_info, &all_passes)) + all_instances = pass_info->ref_pass_instance_number == 0; + success = position_pass (pass_info, &all_lowering_passes); + if (!success || all_instances) + success |= position_pass (pass_info, &all_small_ipa_passes); + if (!success || all_instances) + success |= position_pass (pass_info, &all_regular_ipa_passes); + if (!success || all_instances) + success |= position_pass (pass_info, &all_lto_gen_passes); + if (!success || all_instances) + success |= position_pass (pass_info, &all_passes); + if (!success) fatal_error ("pass %qs not found but is referenced by new pass %qs", pass_info->reference_pass_name, pass_info->pass->name); - else + + /* OK, we have successfully inserted the new pass. We need to register + the dump files for the newly added pass and its duplicates (if any). + Because the registration of plugin/backend passes happens after the + command-line options are parsed, the options that specify single + pass dumping (e.g. -fdump-tree-PASSNAME) cannot be used for new + passes. Therefore we currently can only enable dumping of + new passes when the 'dump-all' flags (e.g. -fdump-tree-all) + are specified. While doing so, we also delete the pass_list_node + objects created during pass positioning. */ + while (added_pass_nodes) { - /* OK, we have successfully inserted the new pass. We need to register - the dump files for the newly added pass and its duplicates (if any). - Because the registration of plugin/backend passes happens after the - command-line options are parsed, the options that specify single - pass dumping (e.g. -fdump-tree-PASSNAME) cannot be used for new - passes. Therefore we currently can only enable dumping of - new passes when the 'dump-all' flags (e.g. -fdump-tree-all) - are specified. While doing so, we also delete the pass_list_node - objects created during pass positioning. */ - while (added_pass_nodes) - { - struct pass_list_node *next_node = added_pass_nodes->next; - enum tree_dump_index tdi; - register_one_dump_file (added_pass_nodes->pass); - if (added_pass_nodes->pass->type == SIMPLE_IPA_PASS - || added_pass_nodes->pass->type == IPA_PASS) - tdi = TDI_ipa_all; - else if (added_pass_nodes->pass->type == GIMPLE_PASS) - tdi = TDI_tree_all; - else - tdi = TDI_rtl_all; - /* Check if dump-all flag is specified. */ - if (get_dump_file_info (tdi)->state) - get_dump_file_info (added_pass_nodes->pass->static_pass_number) - ->state = get_dump_file_info (tdi)->state; - XDELETE (added_pass_nodes); - added_pass_nodes = next_node; - } + struct pass_list_node *next_node = added_pass_nodes->next; + enum tree_dump_index tdi; + register_one_dump_file (added_pass_nodes->pass); + if (added_pass_nodes->pass->type == SIMPLE_IPA_PASS + || added_pass_nodes->pass->type == IPA_PASS) + tdi = TDI_ipa_all; + else if (added_pass_nodes->pass->type == GIMPLE_PASS) + tdi = TDI_tree_all; + else + tdi = TDI_rtl_all; + /* Check if dump-all flag is specified. */ + if (get_dump_file_info (tdi)->state) + get_dump_file_info (added_pass_nodes->pass->static_pass_number) + ->state = get_dump_file_info (tdi)->state; + XDELETE (added_pass_nodes); + added_pass_nodes = next_node; } } @@ -728,7 +737,6 @@ NEXT_PASS (pass_refactor_eh); NEXT_PASS (pass_lower_eh); NEXT_PASS (pass_build_cfg); - NEXT_PASS (pass_lower_complex_O0); NEXT_PASS (pass_lower_vector); NEXT_PASS (pass_warn_function_return); NEXT_PASS (pass_build_cgraph_edges); @@ -737,6 +745,7 @@ /* Interprocedural optimization passes. */ p = &all_small_ipa_passes; + NEXT_PASS (pass_ipa_free_lang_data); NEXT_PASS (pass_ipa_function_and_variable_visibility); NEXT_PASS (pass_ipa_early_inline); { @@ -745,7 +754,6 @@ NEXT_PASS (pass_inline_parameters); NEXT_PASS (pass_rebuild_cgraph_edges); } - NEXT_PASS (pass_ipa_free_lang_data); NEXT_PASS (pass_early_local_passes); { struct opt_pass **p = &pass_early_local_passes.pass.sub; @@ -798,6 +806,7 @@ p = &all_regular_ipa_passes; NEXT_PASS (pass_ipa_whole_program_visibility); + NEXT_PASS (pass_ipa_profile); NEXT_PASS (pass_ipa_cp); NEXT_PASS (pass_ipa_inline); NEXT_PASS (pass_ipa_reference); @@ -809,7 +818,6 @@ p = &all_lto_gen_passes; NEXT_PASS (pass_ipa_lto_gimple_out); - NEXT_PASS (pass_ipa_lto_wpa_fixup); NEXT_PASS (pass_ipa_lto_finish_out); /* This must be the last LTO pass. */ *p = NULL; @@ -880,9 +888,9 @@ { struct opt_pass **p = &pass_tree_loop.pass.sub; NEXT_PASS (pass_tree_loop_init); + NEXT_PASS (pass_lim); NEXT_PASS (pass_copy_prop); NEXT_PASS (pass_dce_loop); - NEXT_PASS (pass_lim); NEXT_PASS (pass_tree_unswitch); NEXT_PASS (pass_scev_cprop); NEXT_PASS (pass_record_bounds); @@ -892,6 +900,7 @@ NEXT_PASS (pass_graphite_transforms); { struct opt_pass **p = &pass_graphite_transforms.pass.sub; + NEXT_PASS (pass_copy_prop); NEXT_PASS (pass_dce_loop); NEXT_PASS (pass_lim); } @@ -938,11 +947,13 @@ NEXT_PASS (pass_forwprop); NEXT_PASS (pass_phiopt); NEXT_PASS (pass_fold_builtins); + NEXT_PASS (pass_optimize_widening_mul); NEXT_PASS (pass_tail_calls); NEXT_PASS (pass_rename_ssa_copies); NEXT_PASS (pass_uncprop); NEXT_PASS (pass_local_pure_const); } + NEXT_PASS (pass_lower_complex_O0); NEXT_PASS (pass_cleanup_eh); NEXT_PASS (pass_lower_resx); NEXT_PASS (pass_nrv); @@ -1017,6 +1028,7 @@ NEXT_PASS (pass_postreload_cse); NEXT_PASS (pass_gcse2); NEXT_PASS (pass_split_after_reload); + NEXT_PASS (pass_implicit_zee); NEXT_PASS (pass_branch_target_load_optimize1); NEXT_PASS (pass_thread_prologue_and_epilogue); NEXT_PASS (pass_rtl_dse2); @@ -1249,14 +1261,15 @@ } #if defined ENABLE_CHECKING - if (flags & TODO_verify_ssa) + if (flags & TODO_verify_ssa + || (current_loops && loops_state_satisfies_p (LOOP_CLOSED_SSA))) verify_ssa (true); if (flags & TODO_verify_flow) verify_flow_info (); if (flags & TODO_verify_stmts) verify_stmts (); - if (flags & TODO_verify_loops) - verify_loop_closed_ssa (); + if (current_loops && loops_state_satisfies_p (LOOP_CLOSED_SSA)) + verify_loop_closed_ssa (false); if (flags & TODO_verify_rtl_sharing) verify_rtl_sharing (); #endif @@ -1353,14 +1366,17 @@ if (dump_file && current_function_decl) { const char *dname, *aname; + struct cgraph_node *node = cgraph_node (current_function_decl); dname = lang_hooks.decl_printable_name (current_function_decl, 2); aname = (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl))); fprintf (dump_file, "\n;; Function %s (%s)%s\n\n", dname, aname, - cfun->function_frequency == FUNCTION_FREQUENCY_HOT + node->frequency == NODE_FREQUENCY_HOT ? " (hot)" - : cfun->function_frequency == FUNCTION_FREQUENCY_UNLIKELY_EXECUTED + : node->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED ? " (unlikely executed)" + : node->frequency == NODE_FREQUENCY_EXECUTED_ONCE + ? " (executed once)" : ""); } return initializing_dump; @@ -1479,10 +1495,20 @@ void execute_all_ipa_transforms (void) { + enum cgraph_state old_state = cgraph_state; struct cgraph_node *node; if (!cfun) return; node = cgraph_node (current_function_decl); + + /* Statement verification skip verification of nothorw when + state is IPA_SSA because we do not modify function bodies + after setting the flag on function. Instead we leave it + to fixup_cfg to do such a transformation. We need to temporarily + change the cgraph state so statement verifier before + transform do not fire. */ + cgraph_state = CGRAPH_STATE_IPA_SSA; + if (node->ipa_transforms_to_apply) { unsigned int i; @@ -1496,6 +1522,7 @@ VEC_free (ipa_opt_pass, heap, node->ipa_transforms_to_apply); node->ipa_transforms_to_apply = NULL; } + cgraph_state = old_state; } /* Execute PASS. */ @@ -1626,6 +1653,7 @@ static void ipa_write_summaries_2 (struct opt_pass *pass, cgraph_node_set set, + varpool_node_set vset, struct lto_out_decl_state *state) { while (pass) @@ -1642,7 +1670,7 @@ if (pass->tv_id) timevar_push (pass->tv_id); - ipa_pass->write_summary (set); + ipa_pass->write_summary (set,vset); /* If a timevar is present, start it. */ if (pass->tv_id) @@ -1650,7 +1678,7 @@ } if (pass->sub && pass->sub->type != GIMPLE_PASS) - ipa_write_summaries_2 (pass->sub, set, state); + ipa_write_summaries_2 (pass->sub, set, vset, state); pass = pass->next; } @@ -1661,14 +1689,16 @@ summaries. SET is the set of nodes to be written. */ static void -ipa_write_summaries_1 (cgraph_node_set set) +ipa_write_summaries_1 (cgraph_node_set set, varpool_node_set vset) { struct lto_out_decl_state *state = lto_new_out_decl_state (); + compute_ltrans_boundary (state, set, vset); + lto_push_out_decl_state (state); - if (!flag_wpa) - ipa_write_summaries_2 (all_regular_ipa_passes, set, state); - ipa_write_summaries_2 (all_lto_gen_passes, set, state); + gcc_assert (!flag_wpa); + ipa_write_summaries_2 (all_regular_ipa_passes, set, vset, state); + ipa_write_summaries_2 (all_lto_gen_passes, set, vset, state); gcc_assert (lto_get_out_decl_state () == state); lto_pop_out_decl_state (); @@ -1681,13 +1711,14 @@ ipa_write_summaries (void) { cgraph_node_set set; + varpool_node_set vset; struct cgraph_node **order; + struct varpool_node *vnode; int i, order_pos; if (!flag_generate_lto || errorcount || sorrycount) return; - lto_new_extern_inline_states (); set = cgraph_node_set_new (); /* Create the callgraph set in the same order used in @@ -1714,25 +1745,77 @@ renumber_gimple_stmt_uids (); pop_cfun (); } - cgraph_node_set_add (set, node); + if (node->analyzed) + cgraph_node_set_add (set, node); } + vset = varpool_node_set_new (); - ipa_write_summaries_1 (set); - lto_delete_extern_inline_states (); + for (vnode = varpool_nodes; vnode; vnode = vnode->next) + if (vnode->needed && !vnode->alias) + varpool_node_set_add (vset, vnode); + + ipa_write_summaries_1 (set, vset); free (order); ggc_free (set); + ggc_free (vset); } +/* Same as execute_pass_list but assume that subpasses of IPA passes + are local passes. If SET is not NULL, write out optimization summaries of + only those node in SET. */ -/* Write all the summaries for the cgraph nodes in SET. If SET is +static void +ipa_write_optimization_summaries_1 (struct opt_pass *pass, cgraph_node_set set, + varpool_node_set vset, + struct lto_out_decl_state *state) +{ + while (pass) + { + struct ipa_opt_pass_d *ipa_pass = (struct ipa_opt_pass_d *)pass; + gcc_assert (!current_function_decl); + gcc_assert (!cfun); + gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS); + if (pass->type == IPA_PASS + && ipa_pass->write_optimization_summary + && (!pass->gate || pass->gate ())) + { + /* If a timevar is present, start it. */ + if (pass->tv_id) + timevar_push (pass->tv_id); + + ipa_pass->write_optimization_summary (set, vset); + + /* If a timevar is present, start it. */ + if (pass->tv_id) + timevar_pop (pass->tv_id); + } + + if (pass->sub && pass->sub->type != GIMPLE_PASS) + ipa_write_optimization_summaries_1 (pass->sub, set, vset, state); + + pass = pass->next; + } +} + +/* Write all the optimization summaries for the cgraph nodes in SET. If SET is NULL, write out all summaries of all nodes. */ void -ipa_write_summaries_of_cgraph_node_set (cgraph_node_set set) +ipa_write_optimization_summaries (cgraph_node_set set, varpool_node_set vset) { - if (flag_generate_lto && !(errorcount || sorrycount)) - ipa_write_summaries_1 (set); + struct lto_out_decl_state *state = lto_new_out_decl_state (); + compute_ltrans_boundary (state, set, vset); + + lto_push_out_decl_state (state); + + gcc_assert (flag_wpa); + ipa_write_optimization_summaries_1 (all_regular_ipa_passes, set, vset, state); + ipa_write_optimization_summaries_1 (all_lto_gen_passes, set, vset, state); + + gcc_assert (lto_get_out_decl_state () == state); + lto_pop_out_decl_state (); + lto_delete_out_decl_state (state); } /* Same as execute_pass_list but assume that subpasses of IPA passes @@ -1777,13 +1860,57 @@ void ipa_read_summaries (void) { - if (!flag_ltrans) - ipa_read_summaries_1 (all_regular_ipa_passes); + ipa_read_summaries_1 (all_regular_ipa_passes); ipa_read_summaries_1 (all_lto_gen_passes); } /* Same as execute_pass_list but assume that subpasses of IPA passes are local passes. */ + +static void +ipa_read_optimization_summaries_1 (struct opt_pass *pass) +{ + while (pass) + { + struct ipa_opt_pass_d *ipa_pass = (struct ipa_opt_pass_d *) pass; + + gcc_assert (!current_function_decl); + gcc_assert (!cfun); + gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS); + + if (pass->gate == NULL || pass->gate ()) + { + if (pass->type == IPA_PASS && ipa_pass->read_optimization_summary) + { + /* If a timevar is present, start it. */ + if (pass->tv_id) + timevar_push (pass->tv_id); + + ipa_pass->read_optimization_summary (); + + /* Stop timevar. */ + if (pass->tv_id) + timevar_pop (pass->tv_id); + } + + if (pass->sub && pass->sub->type != GIMPLE_PASS) + ipa_read_optimization_summaries_1 (pass->sub); + } + pass = pass->next; + } +} + +/* Read all the summaries for all_regular_ipa_passes and all_lto_gen_passes. */ + +void +ipa_read_optimization_summaries (void) +{ + ipa_read_optimization_summaries_1 (all_regular_ipa_passes); + ipa_read_optimization_summaries_1 (all_lto_gen_passes); +} + +/* Same as execute_pass_list but assume that subpasses of IPA passes + are local passes. */ void execute_ipa_pass_list (struct opt_pass *pass) { @@ -1883,6 +2010,8 @@ fprintf (dump, "PROP_rtl\n"); if (props & PROP_gimple_lomp) fprintf (dump, "PROP_gimple_lomp\n"); + if (props & PROP_gimple_lcx) + fprintf (dump, "PROP_gimple_lcx\n"); } void