diff options
author | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-05-06 07:25:24 +0000 |
---|---|---|
committer | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-05-06 07:25:24 +0000 |
commit | 1e7864e44136433004d5c8adb767dddf90830cb4 (patch) | |
tree | 09b0a22654ae562c449d45f3d1fb178722c10a17 /gcc/passes.c | |
parent | 9306644f396b57a5977c121820ef4cf010217f71 (diff) | |
download | gcc-1e7864e44136433004d5c8adb767dddf90830cb4.tar.gz |
2008-05-06 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk r134973
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@134974 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/passes.c')
-rw-r--r-- | gcc/passes.c | 215 |
1 files changed, 171 insertions, 44 deletions
diff --git a/gcc/passes.c b/gcc/passes.c index a34dd11a584..fc305ef6479 100644 --- a/gcc/passes.c +++ b/gcc/passes.c @@ -355,7 +355,7 @@ register_one_dump_file (struct opt_pass *pass) ? 1 : pass->static_pass_number)); dot_name = concat (".", pass->name, num, NULL); - if (pass->type == SIMPLE_IPA_PASS) + if (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS) prefix = "ipa-", flags = TDF_IPA; else if (pass->type == GIMPLE_PASS) prefix = "tree-", flags = TDF_TREE; @@ -541,7 +541,6 @@ init_optimization_passes (void) 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); @@ -560,7 +559,7 @@ init_optimization_passes (void) /* These passes are run after IPA passes on every function that is being output to the assembler file. */ p = &all_passes; - NEXT_PASS (pass_apply_inline); + NEXT_PASS (pass_O0_always_inline); NEXT_PASS (pass_all_optimizations); { struct opt_pass **p = &pass_all_optimizations.pass.sub; @@ -573,6 +572,7 @@ init_optimization_passes (void) NEXT_PASS (pass_rename_ssa_copies); /* Initial scalar cleanups. */ + NEXT_PASS (pass_complete_unrolli); NEXT_PASS (pass_ccp); NEXT_PASS (pass_phiprop); NEXT_PASS (pass_fre); @@ -742,7 +742,6 @@ init_optimization_passes (void) NEXT_PASS (pass_partition_blocks); NEXT_PASS (pass_regmove); NEXT_PASS (pass_split_all_insns); - NEXT_PASS (pass_fast_rtl_byte_dce); NEXT_PASS (pass_lower_subreg2); NEXT_PASS (pass_df_initialize_no_opt); NEXT_PASS (pass_stack_ptr_mod); @@ -1012,11 +1011,15 @@ execute_todo (unsigned int flags) to analyze side effects. The full removal is done just at the end of IPA pass queue. */ if (flags & TODO_remove_functions) - cgraph_remove_unreachable_nodes (true, dump_file); + { + gcc_assert (!cfun); + cgraph_remove_unreachable_nodes (true, dump_file); + } if ((flags & TODO_dump_cgraph) && dump_file && !current_function_decl) { + gcc_assert (!cfun); dump_cgraph (dump_file); /* Flush the file. If verification fails, we won't be able to close the file before aborting. */ @@ -1065,8 +1068,58 @@ verify_curr_properties (void *data) } #endif +/* Initialize pass dump file. */ + +static bool +pass_init_dump_file (struct opt_pass *pass) +{ + /* If a dump file name is present, open it if enabled. */ + if (pass->static_pass_number != -1) + { + bool initializing_dump = !dump_initialized_p (pass->static_pass_number); + dump_file_name = get_dump_file_name (pass->static_pass_number); + dump_file = dump_begin (pass->static_pass_number, &dump_flags); + if (dump_file && current_function_decl) + { + const char *dname, *aname; + dname = lang_hooks.decl_printable_name (current_function_decl, 2); + aname = (IDENTIFIER_POINTER + (DECL_ASSEMBLER_NAME (current_function_decl))); + fprintf (dump_file, "\n;; Apply transform to function %s (%s)%s\n\n", dname, aname, + cfun->function_frequency == FUNCTION_FREQUENCY_HOT + ? " (hot)" + : cfun->function_frequency == FUNCTION_FREQUENCY_UNLIKELY_EXECUTED + ? " (unlikely executed)" + : ""); + } + return initializing_dump; + } + else + return false; +} + +/* Flush PASS dump file. */ + +static void +pass_fini_dump_file (struct opt_pass *pass) +{ + /* Flush and close dump file. */ + if (dump_file_name) + { + free (CONST_CAST (char *, dump_file_name)); + dump_file_name = NULL; + } + + if (dump_file) + { + dump_end (pass->static_pass_number, dump_file); + dump_file = NULL; + } +} + /* After executing the pass, apply expected changes to the function properties. */ + static void update_properties_after_pass (void *data) { @@ -1075,6 +1128,80 @@ update_properties_after_pass (void *data) & ~pass->properties_destroyed; } +/* Schedule IPA transform pass DATA for CFUN. */ + +static void +add_ipa_transform_pass (void *data) +{ + struct ipa_opt_pass *ipa_pass = (struct ipa_opt_pass *) data; + VEC_safe_push (ipa_opt_pass, heap, cfun->ipa_transforms_to_apply, ipa_pass); +} + +/* Execute IPA pass function summary generation. DATA is pointer to + pass list to execute. */ + +static void +execute_ipa_summary_passes (void *data) +{ + struct ipa_opt_pass *ipa_pass = (struct ipa_opt_pass *)data; + struct cgraph_node *node = cgraph_node (cfun->decl); + while (ipa_pass && ipa_pass->pass.type == IPA_PASS) + { + struct opt_pass *pass = &ipa_pass->pass; + if (!pass->gate || pass->gate ()) + { + pass_init_dump_file (pass); + ipa_pass->function_generate_summary (node); + pass_fini_dump_file (pass); + } + ipa_pass = (struct ipa_opt_pass *)ipa_pass->pass.next; + } +} + +/* Execute IPA_PASS function transform on NODE. */ + +static void +execute_one_ipa_transform_pass (struct cgraph_node *node, + struct ipa_opt_pass *ipa_pass) +{ + struct opt_pass *pass = &ipa_pass->pass; + unsigned int todo_after = 0; + + current_pass = pass; + if (!ipa_pass->function_transform) + return; + + /* Note that the folders should only create gimple expressions. + This is a hack until the new folder is ready. */ + in_gimple_form = (cfun && (cfun->curr_properties & PROP_trees)) != 0; + + pass_init_dump_file (pass); + + /* Run pre-pass verification. */ + execute_todo (ipa_pass->function_transform_todo_flags_start); + + /* If a timevar is present, start it. */ + if (pass->tv_id) + timevar_push (pass->tv_id); + + /* Do it! */ + todo_after = ipa_pass->function_transform (node); + + /* Stop timevar. */ + if (pass->tv_id) + timevar_pop (pass->tv_id); + + /* Run post-pass cleanup and verification. */ + execute_todo (todo_after); + verify_interpass_invariants (); + + pass_fini_dump_file (pass); + + current_pass = NULL; + /* Reset in_gimple_form to not break non-unit-at-a-time mode. */ + in_gimple_form = false; +} + static bool execute_one_pass (struct opt_pass *pass) { @@ -1087,13 +1214,24 @@ execute_one_pass (struct opt_pass *pass) /* IPA passes are executed on whole program, so cfun should be NULL. Ohter passes needs function context set. */ - if (pass->type == SIMPLE_IPA_PASS) + if (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS) gcc_assert (!cfun && !current_function_decl); else + gcc_assert (cfun && current_function_decl); + + if (cfun && cfun->ipa_transforms_to_apply) { - gcc_assert (cfun && current_function_decl); - gcc_assert (!(cfun->curr_properties & PROP_trees) - || pass->type != RTL_PASS); + unsigned int i; + struct cgraph_node *node = cgraph_node (current_function_decl); + + for (i = 0; i < VEC_length (ipa_opt_pass, cfun->ipa_transforms_to_apply); + i++) + execute_one_ipa_transform_pass (node, + VEC_index (ipa_opt_pass, + cfun->ipa_transforms_to_apply, + i)); + VEC_free (ipa_opt_pass, heap, cfun->ipa_transforms_to_apply); + cfun->ipa_transforms_to_apply = NULL; } current_pass = pass; @@ -1119,6 +1257,7 @@ execute_one_pass (struct opt_pass *pass) (void *)(size_t)pass->properties_required); #endif + if (pass->name && comprobe_replf) { static char buf[80]; memset(buf, 0, sizeof(buf)); @@ -1126,28 +1265,7 @@ execute_one_pass (struct opt_pass *pass) comprobe_show_message(buf); } - /* If a dump file name is present, open it if enabled. */ - if (pass->static_pass_number != -1) - { - initializing_dump = !dump_initialized_p (pass->static_pass_number); - dump_file_name = get_dump_file_name (pass->static_pass_number); - dump_file = dump_begin (pass->static_pass_number, &dump_flags); - if (dump_file && current_function_decl) - { - const char *dname, *aname; - 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 - ? " (hot)" - : cfun->function_frequency == FUNCTION_FREQUENCY_UNLIKELY_EXECUTED - ? " (unlikely executed)" - : ""); - } - } - else - initializing_dump = false; + initializing_dump = pass_init_dump_file (pass); /* If a timevar is present, start it. */ if (pass->tv_id) @@ -1188,22 +1306,17 @@ execute_one_pass (struct opt_pass *pass) /* Run post-pass cleanup and verification. */ execute_todo (todo_after | pass->todo_flags_finish); verify_interpass_invariants (); + if (pass->type == IPA_PASS) + do_per_function (add_ipa_transform_pass, pass); if (!current_function_decl) cgraph_process_new_functions (); - /* Flush and close dump file. */ - if (dump_file_name) - { - free (CONST_CAST (char *, dump_file_name)); - dump_file_name = NULL; - } + pass_fini_dump_file (pass); - if (dump_file) - { - dump_end (pass->static_pass_number, dump_file); - dump_file = NULL; - } + if (pass->type != SIMPLE_IPA_PASS && pass->type != IPA_PASS) + gcc_assert (!(cfun->curr_properties & PROP_trees) + || pass->type != RTL_PASS); current_pass = NULL; /* Reset in_gimple_form to not break non-unit-at-a-time mode. */ @@ -1231,17 +1344,31 @@ execute_pass_list (struct opt_pass *pass) void execute_ipa_pass_list (struct opt_pass *pass) { + bool summaries_generated = false; do { gcc_assert (!current_function_decl); gcc_assert (!cfun); - gcc_assert (pass->type == SIMPLE_IPA_PASS); + gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS); + if (pass->type == IPA_PASS && (!pass->gate || pass->gate ())) + { + if (!summaries_generated) + { + if (!quiet_flag && !cfun) + fprintf (stderr, " <summary generate>"); + do_per_function_toporder (execute_ipa_summary_passes, pass); + } + summaries_generated = true; + } + else + summaries_generated = false; if (execute_one_pass (pass) && pass->sub) { if (pass->sub->type == GIMPLE_PASS) do_per_function_toporder ((void (*)(void *))execute_pass_list, pass->sub); - else if (pass->sub->type == SIMPLE_IPA_PASS) + else if (pass->sub->type == SIMPLE_IPA_PASS + || pass->sub->type == IPA_PASS) execute_ipa_pass_list (pass->sub); else gcc_unreachable (); |