From 8438a0518b3b65162201d6181c2771e7a7203476 Mon Sep 17 00:00:00 2001 From: marxin Date: Thu, 22 Oct 2015 12:46:16 +0200 Subject: [PATCH] Pass manager: add support for termination of pass list gcc/ChangeLog: 2015-10-30 Martin Liska * passes.c (do_per_function_toporder): Push to cfun before calling the pass manager. (execute_one_pass): Handle TODO_discard_function. (execute_pass_list_1): Terminate if current function is null. (execute_pass_list): Do not push and pop function. * tree-pass.h: Define new TODO_discard_function. --- gcc/passes.c | 32 ++++++++++++++++++++++++++++---- gcc/tree-pass.h | 3 +++ 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/gcc/passes.c b/gcc/passes.c index 8b3fb2f..f24fc57 100644 --- a/gcc/passes.c +++ b/gcc/passes.c @@ -1728,7 +1728,12 @@ do_per_function_toporder (void (*callback) (function *, void *data), void *data) order[i] = NULL; node->process = 0; if (node->has_gimple_body_p ()) - callback (DECL_STRUCT_FUNCTION (node->decl), data); + { + struct function *fn = DECL_STRUCT_FUNCTION (node->decl); + push_cfun (fn); + callback (fn, data); + pop_cfun (); + } } symtab->remove_cgraph_removal_hook (hook); } @@ -2378,6 +2383,23 @@ execute_one_pass (opt_pass *pass) current_pass = NULL; + if (todo_after & TODO_discard_function) + { + gcc_assert (cfun); + /* As cgraph_node::release_body expects release dominators info, + we have to release it. */ + if (dom_info_available_p (CDI_DOMINATORS)) + free_dominance_info (CDI_DOMINATORS); + + if (dom_info_available_p (CDI_POST_DOMINATORS)) + free_dominance_info (CDI_POST_DOMINATORS); + + cgraph_node::get (current_function_decl)->release_body (); + + current_function_decl = NULL; + set_cfun (NULL); + } + /* Signal this is a suitable GC collection point. */ if (!((todo_after | pass->todo_flags_finish) & TODO_do_not_ggc_collect)) ggc_collect (); @@ -2392,6 +2414,9 @@ execute_pass_list_1 (opt_pass *pass) { gcc_assert (pass->type == GIMPLE_PASS || pass->type == RTL_PASS); + + if (cfun == NULL) + return; if (execute_one_pass (pass) && pass->sub) execute_pass_list_1 (pass->sub); @@ -2403,14 +2428,13 @@ execute_pass_list_1 (opt_pass *pass) void execute_pass_list (function *fn, opt_pass *pass) { - push_cfun (fn); + gcc_assert (fn == cfun); execute_pass_list_1 (pass); - if (fn->cfg) + if (cfun && fn->cfg) { free_dominance_info (CDI_DOMINATORS); free_dominance_info (CDI_POST_DOMINATORS); } - pop_cfun (); } /* Write out all LTO data. */ diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h index 7a5f476..2627df3 100644 --- a/gcc/tree-pass.h +++ b/gcc/tree-pass.h @@ -296,6 +296,9 @@ protected: /* Rebuild the callgraph edges. */ #define TODO_rebuild_cgraph_edges (1 << 22) +/* Release function body and stop pass manager. */ +#define TODO_discard_function (1 << 23) + /* Internally used in execute_function_todo(). */ #define TODO_update_ssa_any \ (TODO_update_ssa \ -- 2.6.2