Hello. As part of upcoming merge of HSA branch, we would like to have possibility to terminate pass manager after execution of the HSA generation pass. The HSA back-end is implemented as a tree pass that directly emits HSAIL from gimple tree representation. The pass operates on clones created by HSA IPA pass and the pass manager should stop execution of further RTL passes.
Suggested patch survives bootstrap and regression tests on x86_64-linux-pc. What do you think about it? Thanks, Martin
>From fc60561c3ac09188fb61dac61b1cc2422061fc1d Mon Sep 17 00:00:00 2001 From: marxin <mli...@suse.cz> Date: Mon, 19 Oct 2015 23:26:54 +0200 Subject: [PATCH] Add support for termination of pass manager. gcc/ChangeLog: 2015-10-19 Martin Liska <mli...@suse.cz> * passes.c (execute_one_pass): Add new argument called exit. (execute_pass_list_1): Terminate pass manager if a pass requests termination. (execute_ipa_pass_list): Likewise. * tree-pass.h: Introduce new TODO_stop_pass_execution. --- gcc/passes.c | 24 ++++++++++++++++++++---- gcc/tree-pass.h | 3 +++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/gcc/passes.c b/gcc/passes.c index 6ef6d2e..1199ae3 100644 --- a/gcc/passes.c +++ b/gcc/passes.c @@ -2279,10 +2279,11 @@ override_gate_status (opt_pass *pass, tree func, bool gate_status) } -/* Execute PASS. */ +/* Execute PASS. If the PASS requests to stop after its execution, EXIT + value is set to true. */ bool -execute_one_pass (opt_pass *pass) +execute_one_pass (opt_pass *pass, bool *exit) { unsigned int todo_after = 0; @@ -2387,18 +2388,28 @@ execute_one_pass (opt_pass *pass) if (!((todo_after | pass->todo_flags_finish) & TODO_do_not_ggc_collect)) ggc_collect (); + /* If finish TODO flags contain TODO_stop_pass_execution, set exit = true. */ + if (todo_after & TODO_stop_pass_execution) + *exit = true; + return true; } static void execute_pass_list_1 (opt_pass *pass) { + bool stop_pass_execution = false; + do { gcc_assert (pass->type == GIMPLE_PASS || pass->type == RTL_PASS); - if (execute_one_pass (pass) && pass->sub) + if (execute_one_pass (pass, &stop_pass_execution) && pass->sub) execute_pass_list_1 (pass->sub); + + if (stop_pass_execution) + return; + pass = pass->next; } while (pass); @@ -2739,12 +2750,14 @@ ipa_read_optimization_summaries (void) void execute_ipa_pass_list (opt_pass *pass) { + bool stop_pass_execution = false; + do { gcc_assert (!current_function_decl); gcc_assert (!cfun); gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS); - if (execute_one_pass (pass) && pass->sub) + if (execute_one_pass (pass, &stop_pass_execution) && pass->sub) { if (pass->sub->type == GIMPLE_PASS) { @@ -2763,6 +2776,9 @@ execute_ipa_pass_list (opt_pass *pass) gcc_assert (!current_function_decl); symtab->process_new_functions (); pass = pass->next; + + if (stop_pass_execution) + return; } while (pass); } diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h index c37e4b2..a481bac 100644 --- a/gcc/tree-pass.h +++ b/gcc/tree-pass.h @@ -300,6 +300,9 @@ protected: /* Rebuild the callgraph edges. */ #define TODO_rebuild_cgraph_edges (1 << 22) +/* Stop pass manager after execution of a pass. */ +#define TODO_stop_pass_execution (1 << 23) + /* Internally used in execute_function_todo(). */ #define TODO_update_ssa_any \ (TODO_update_ssa \ -- 2.6.0