On Mon, 2013-07-29 at 13:56 -0600, Jeff Law wrote: > On 07/26/2013 09:04 AM, David Malcolm wrote: [...snip quote of ChangeLog...] > So as has been discussed elsewhere I'd like to see pipeline changed to > pass_manager. > > WRT references. Not being a C++ guy, I'd always mentally equated > references with pointers. I've done a little reading and it seems that > references actually convey more information, which I'm generally a fan > of -- with the caveat that they're pointers that act more like values, > which might get confusing. > > At least in the immediate term, I think we should stick with pointers > until we have a clearer sense of whether or not we want to be using > references in this way. I doubt it's terribly important, but the > non-nullness ought to be expressable via an attribute. > > With the pipeline->pass_manager change and using pointers instead of > references on the return type, this patch is fine. Pre-approved with > those changes.
Thanks. I've committed the attached to trunk as r201351, having done the following: * rebased against trunk * renamed class pipeline and file pipeline.h to class pass_manager and file pass_manager.h * replaced uses of references with pointers * context.c (context::context): Fixed missing space in pass_manager constructor invocation noted by Martin Jambor in http://gcc.gnu.org/ml/gcc-patches/2013-07/msg01155.html * successfully bootstrapped the new patch on x86_64-unknown-linux-gnu and reran the testsuite: all testcases showed the same results as an unpatched build (relative to r201317). * verified that the patch builds on an updated svn checkout. Dave
>From d396b8c8d4382fb0337ad7813fca03dc563b96d2 Mon Sep 17 00:00:00 2001 From: David Malcolm <dmalc...@redhat.com> Date: Mon, 22 Jul 2013 14:06:26 -0400 Subject: [PATCH 01/14] Introduce beginnings of a pass_manager class. This patch introduces a gcc::pass_manager class and moves various non-GTY globals relating to pass management into it. The gcc::context gains its first field: a pointer to the gcc::pass_manager instance. It was previously sent as: http://gcc.gnu.org/ml/gcc-patches/2013-07/msg01090.html as part of: http://gcc.gnu.org/ml/gcc-patches/2013-07/msg01088.html and Martin Jambor raised some stylistic concerns about it: http://gcc.gnu.org/ml/gcc-patches/2013-07/msg01155.html I'm reposting it here so that people can see how it fits into the later patches. gcc/ * Makefile.in (PASS_MANAGER_H): New. (lto-cgraph.o): Depend on CONTEXT_H and PASS_MANAGER_H. (passes.o): Likewise. (statistics.o): Likewise. (cgraphunit.o): Likewise. (context.o): Depend on PASS_MANAGER_H. * pass_manager.h: New. * cgraphunit.c (cgraph_add_new_function): Update for moves of globals to fields of pass_manager. (analyze_function): Likewise. (expand_function): Likewise. (ipa_passes): Likewise. (compile): Likewise. * context.c (context::context): New. * context.h (context::context): New. (context::get_passes): New. (context::passes_): New. * lto-cgraph.c (input_node): Update for moves of globals to fields of pass_manager. * passes.c (all_passes): Remove, in favor of a field of the same name within the new class pass_manager. (all_small_ipa_passes): Likewise. (all_lowering_passes): Likewise. (all_regular_ipa_passes): Likewise. (all_late_ipa_passes): Likewise. (all_lto_gen_passes): Likewise. (passes_by_id): Likewise. (passes_by_id_size): Likewise. (gcc_pass_lists): Remove, in favor of "pass_lists" field within the new class pass_manager. (set_pass_for_id): Convert to... (pass_manager::set_pass_for_id): ...method. (get_pass_for_id): Convert to... (pass_manager::get_pass_for_id): ...method. (register_one_dump_file): Move body of implementation into... (pass_manager::register_one_dump_file): ...here. (register_dump_files_1): Convert to... (pass_manager::register_dump_files_1): ...method. (register_dump_files): Convert to... (pass_manager::register_dump_files): ...method. (create_pass_tab): Update for moves of globals to fields of pass_manager. (dump_passes): Move body of implementation into... (pass_manager::dump_passes): ...here. (register_pass): Move body of implementation into... (pass_manager::register_pass): ...here. (init_optimization_passes): Convert into... (pass_manager::pass_manager): ...constructor for new pass_manager class, and initialize the pass_lists array. (check_profile_consistency): Update for moves of globals to fields of pass_manager. (dump_profile_report): Move body of implementation into... (pass_manager::dump_profile_report): ...here. (ipa_write_summaries_1): Update for moves of pass lists from being globals to fields of pass_manager. (ipa_write_optimization_summaries): Likewise. (ipa_read_summaries): Likewise. (ipa_read_optimization_summaries): Likewise. (execute_all_ipa_stmt_fixups): Likewise. * statistics.c (statistics_fini): Update for moves of globals to fields of pass_manager. * toplev.c (general_init): Replace call to init_optimization_passes with construction of the pass_manager instance. * tree-pass.h (all_passes): Remove, in favor of a field of the same name within the new class pass_manager. (all_small_ipa_passes): Likewise. (all_lowering_passes): Likewise. (all_regular_ipa_passes): Likewise. (all_lto_gen_passes): Likewise. (all_late_ipa_passes): Likewise. (passes_by_id): Likewise. (passes_by_id_size): Likewise. (gcc_pass_lists): Remove, in favor of "pass_lists" field within the new class pass_manager. (get_pass_for_id): Remove. gcc/lto/ * Make-lang.in (lto/lto.o:): Depend on CONTEXT_H and PASS_MANAGER_H. * lto.c (do_whole_program_analysis): Update for move of all_regular_ipa_passes from a global to a field of class pass_manager. --- gcc/Makefile.in | 15 +++++--- gcc/cgraphunit.c | 22 +++++++----- gcc/context.c | 6 ++++ gcc/context.h | 11 +++++- gcc/lto-cgraph.c | 7 ++-- gcc/lto/Make-lang.in | 3 +- gcc/lto/lto.c | 4 ++- gcc/pass_manager.h | 89 ++++++++++++++++++++++++++++++++++++++++++++++ gcc/passes.c | 99 +++++++++++++++++++++++++++++++++++----------------- gcc/statistics.c | 7 ++-- gcc/toplev.c | 4 +-- gcc/tree-pass.h | 29 --------------- 12 files changed, 213 insertions(+), 83 deletions(-) create mode 100644 gcc/pass_manager.h diff --git a/gcc/Makefile.in b/gcc/Makefile.in index fb0cb4b..3f8bd70 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -987,6 +987,7 @@ PLUGIN_VERSION_H = plugin-version.h configargs.h LIBFUNCS_H = libfuncs.h $(HASHTAB_H) GRAPHITE_HTAB_H = graphite-htab.h graphite-clast-to-gimple.h $(HASH_TABLE_H) CONTEXT_H = context.h +PASS_MANAGER_H = pass_manager.h # # Now figure out from those variables how to compile and link. @@ -2183,7 +2184,8 @@ lto-cgraph.o: lto-cgraph.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(HASHTAB_H) langhooks.h $(BASIC_BLOCK_H) \ $(TREE_FLOW_H) $(CGRAPH_H) $(FUNCTION_H) $(GGC_H) $(DIAGNOSTIC_CORE_H) \ $(EXCEPT_H) $(TIMEVAR_H) pointer-set.h $(LTO_STREAMER_H) \ - $(GCOV_IO_H) $(DATA_STREAMER_H) $(TREE_STREAMER_H) $(TREE_PASS_H) profile.h + $(GCOV_IO_H) $(DATA_STREAMER_H) $(TREE_STREAMER_H) $(TREE_PASS_H) \ + profile.h $(CONTEXT_H) $(PASS_MANAGER_H) lto-streamer-in.o: lto-streamer-in.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(TM_H) toplev.h $(DIAGNOSTIC_CORE_H) $(EXPR_H) $(FLAGS_H) $(PARAMS_H) \ input.h $(HASHTAB_H) $(BASIC_BLOCK_H) $(TREE_FLOW_H) $(TREE_PASS_H) \ @@ -2745,7 +2747,8 @@ passes.o : passes.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ hosthooks.h $(CGRAPH_H) $(COVERAGE_H) $(TREE_PASS_H) $(TREE_DUMP_H) \ $(GGC_H) $(OPTS_H) $(TREE_FLOW_H) $(TREE_INLINE_H) \ gt-passes.h $(DF_H) $(PREDICT_H) $(LTO_STREAMER_H) \ - $(PLUGIN_H) $(IPA_UTILS_H) passes.def + $(PLUGIN_H) $(IPA_UTILS_H) passes.def \ + $(CONTEXT_H) $(PASS_MANAGER_H) plugin.o : plugin.c $(PLUGIN_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(HASH_TABLE_H) $(DIAGNOSTIC_CORE_H) $(TREE_H) $(TREE_PASS_H) \ @@ -2786,7 +2789,8 @@ function.o : function.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_ERROR_ $(TREE_PASS_H) $(DF_H) $(PARAMS_H) bb-reorder.h \ $(COMMON_TARGET_H) statistics.o : statistics.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ - $(TREE_PASS_H) $(TREE_DUMP_H) $(HASH_TABLE_H) statistics.h $(FUNCTION_H) + $(TREE_PASS_H) $(TREE_DUMP_H) $(HASH_TABLE_H) statistics.h \ + $(FUNCTION_H) $(CONTEXT_H) $(PASS_MANAGER_H) stmt.o : stmt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(DUMPFILE_H) $(TM_H) \ $(RTL_H) \ $(TREE_H) $(FLAGS_H) $(FUNCTION_H) insn-config.h hard-reg-set.h $(EXPR_H) \ @@ -2908,7 +2912,8 @@ cgraphunit.o : cgraphunit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(FIBHEAP_H) output.h $(PARAMS_H) $(RTL_H) $(IPA_PROP_H) \ gt-cgraphunit.h tree-iterator.h $(COVERAGE_H) $(TREE_DUMP_H) \ $(GIMPLE_PRETTY_PRINT_H) $(IPA_INLINE_H) $(IPA_UTILS_H) $(CFGLOOP_H) \ - $(LTO_STREAMER_H) output.h $(REGSET_H) $(EXCEPT_H) $(GCC_PLUGIN_H) plugin.h + $(LTO_STREAMER_H) output.h $(REGSET_H) $(EXCEPT_H) $(GCC_PLUGIN_H) \ + plugin.h $(CONTEXT_H) $(PASS_MANAGER_H) cgraphclones.o : cgraphclones.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(TREE_H) langhooks.h $(TREE_INLINE_H) toplev.h $(DIAGNOSTIC_CORE_H) $(FLAGS_H) $(GGC_H) \ $(TARGET_H) $(CGRAPH_H) intl.h pointer-set.h $(FUNCTION_H) $(GIMPLE_H) \ @@ -3490,7 +3495,7 @@ $(out_object_file): $(out_file) $(CONFIG_H) coretypes.h $(TM_H) $(TREE_H) \ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) \ $(out_file) $(OUTPUT_OPTION) context.o: context.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(GGC_H) \ - $(CONTEXT_H) + $(CONTEXT_H) $(PASS_MANAGER_H) $(common_out_object_file): $(common_out_file) $(CONFIG_H) $(SYSTEM_H) \ coretypes.h $(COMMON_TARGET_H) $(COMMON_TARGET_DEF_H) $(PARAMS_H) \ diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index b82c2e0..ca36937 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -194,6 +194,8 @@ along with GCC; see the file COPYING3. If not see #include "except.h" #include "cfgloop.h" #include "regset.h" /* FIXME: For reg_obstack. */ +#include "context.h" +#include "pass_manager.h" /* Queue of cgraph nodes scheduled to be added into cgraph. This is a secondary queue used during optimization to accommodate passes that @@ -478,6 +480,7 @@ cgraph_finalize_function (tree decl, bool nested) void cgraph_add_new_function (tree fndecl, bool lowered) { + gcc::pass_manager *passes = g->get_passes (); struct cgraph_node *node; switch (cgraph_state) { @@ -508,7 +511,7 @@ cgraph_add_new_function (tree fndecl, bool lowered) push_cfun (DECL_STRUCT_FUNCTION (fndecl)); gimple_register_cfg_hooks (); bitmap_obstack_initialize (NULL); - execute_pass_list (all_lowering_passes); + execute_pass_list (passes->all_lowering_passes); execute_pass_list (pass_early_local_passes.pass.sub); bitmap_obstack_release (NULL); pop_cfun (); @@ -640,7 +643,7 @@ analyze_function (struct cgraph_node *node) gimple_register_cfg_hooks (); bitmap_obstack_initialize (NULL); - execute_pass_list (all_lowering_passes); + execute_pass_list (g->get_passes ()->all_lowering_passes); free_dominance_info (CDI_POST_DOMINATORS); free_dominance_info (CDI_DOMINATORS); compact_blocks (); @@ -1588,7 +1591,7 @@ expand_function (struct cgraph_node *node) /* Signal the start of passes. */ invoke_plugin_callbacks (PLUGIN_ALL_PASSES_START, NULL); - execute_pass_list (all_passes); + execute_pass_list (g->get_passes ()->all_passes); /* Signal the end of passes. */ invoke_plugin_callbacks (PLUGIN_ALL_PASSES_END, NULL); @@ -1807,6 +1810,8 @@ output_in_order (void) static void ipa_passes (void) { + gcc::pass_manager *passes = g->get_passes (); + set_cfun (NULL); current_function_decl = NULL; gimple_register_cfg_hooks (); @@ -1816,7 +1821,7 @@ ipa_passes (void) if (!in_lto_p) { - execute_ipa_pass_list (all_small_ipa_passes); + execute_ipa_pass_list (passes->all_small_ipa_passes); if (seen_error ()) return; } @@ -1843,14 +1848,15 @@ ipa_passes (void) cgraph_process_new_functions (); execute_ipa_summary_passes - ((struct ipa_opt_pass_d *) all_regular_ipa_passes); + ((struct ipa_opt_pass_d *) passes->all_regular_ipa_passes); } /* Some targets need to handle LTO assembler output specially. */ if (flag_generate_lto) targetm.asm_out.lto_start (); - execute_ipa_summary_passes ((struct ipa_opt_pass_d *) all_lto_gen_passes); + execute_ipa_summary_passes ((struct ipa_opt_pass_d *) + passes->all_lto_gen_passes); if (!in_lto_p) ipa_write_summaries (); @@ -1859,7 +1865,7 @@ ipa_passes (void) targetm.asm_out.lto_end (); if (!flag_ltrans && (in_lto_p || !flag_lto || flag_fat_lto_objects)) - execute_ipa_pass_list (all_regular_ipa_passes); + execute_ipa_pass_list (passes->all_regular_ipa_passes); invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_END, NULL); bitmap_obstack_release (NULL); @@ -1985,7 +1991,7 @@ compile (void) cgraph_materialize_all_clones (); bitmap_obstack_initialize (NULL); - execute_ipa_pass_list (all_late_ipa_passes); + execute_ipa_pass_list (g->get_passes ()->all_late_ipa_passes); symtab_remove_unreachable_nodes (true, dump_file); #ifdef ENABLE_CHECKING verify_symtab (); diff --git a/gcc/context.c b/gcc/context.c index 76e0dde..b515241 100644 --- a/gcc/context.c +++ b/gcc/context.c @@ -22,6 +22,12 @@ along with GCC; see the file COPYING3. If not see #include "coretypes.h" #include "ggc.h" #include "context.h" +#include "pass_manager.h" /* The singleton holder of global state: */ gcc::context *g; + +gcc::context::context() +{ + passes_ = new gcc::pass_manager (this); +} diff --git a/gcc/context.h b/gcc/context.h index 3caf02f..66260cd 100644 --- a/gcc/context.h +++ b/gcc/context.h @@ -22,14 +22,23 @@ along with GCC; see the file COPYING3. If not see namespace gcc { +class pass_manager; + /* GCC's internal state can be divided into zero or more "parallel universe" of state; an instance of this class is one such context of state. */ class context { public: + context(); + + /* Pass-management. */ + + pass_manager *get_passes () { gcc_assert (passes_); return passes_; } - /* Currently empty. */ +private: + /* Pass-management. */ + pass_manager *passes_; }; // class context diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c index d60213a..19a5de8 100644 --- a/gcc/lto-cgraph.c +++ b/gcc/lto-cgraph.c @@ -47,6 +47,8 @@ along with GCC; see the file COPYING3. If not see #include "gcov-io.h" #include "tree-pass.h" #include "profile.h" +#include "context.h" +#include "pass_manager.h" static void output_cgraph_opt_summary (void); static void input_cgraph_opt_summary (vec<symtab_node> nodes); @@ -936,6 +938,7 @@ input_node (struct lto_file_decl_data *file_data, enum LTO_symtab_tags tag, vec<symtab_node> nodes) { + gcc::pass_manager *passes = g->get_passes (); tree fn_decl; struct cgraph_node *node; struct bitpack_d bp; @@ -981,8 +984,8 @@ input_node (struct lto_file_decl_data *file_data, struct opt_pass *pass; int pid = streamer_read_hwi (ib); - gcc_assert (pid < passes_by_id_size); - pass = passes_by_id[pid]; + gcc_assert (pid < passes->passes_by_id_size); + pass = passes->passes_by_id[pid]; node->ipa_transforms_to_apply.safe_push ((struct ipa_opt_pass_d *) pass); } diff --git a/gcc/lto/Make-lang.in b/gcc/lto/Make-lang.in index 5f2f475..1acd176 100644 --- a/gcc/lto/Make-lang.in +++ b/gcc/lto/Make-lang.in @@ -85,7 +85,8 @@ lto/lto.o: lto/lto.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(OPTS_H) \ langhooks.h $(VEC_H) $(BITMAP_H) pointer-set.h $(IPA_PROP_H) \ $(COMMON_H) debug.h $(GIMPLE_H) $(LTO_H) $(LTO_TREE_H) \ $(LTO_TAGS_H) $(LTO_STREAMER_H) $(SPLAY_TREE_H) gt-lto-lto.h \ - $(TREE_STREAMER_H) $(DATA_STREAMER_H) lto/lto-partition.h + $(TREE_STREAMER_H) $(DATA_STREAMER_H) lto/lto-partition.h \ + $(CONTEXT_H) $(PIPELINE_H) lto/lto-partition.o: lto/lto-partition.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ toplev.h $(TREE_H) $(TM_H) \ $(CGRAPH_H) $(TIMEVAR_H) \ diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c index c0f9328..32f8326 100644 --- a/gcc/lto/lto.c +++ b/gcc/lto/lto.c @@ -46,6 +46,8 @@ along with GCC; see the file COPYING3. If not see #include "splay-tree.h" #include "lto-partition.h" #include "data-streamer.h" +#include "context.h" +#include "pass_manager.h" static GTY(()) tree first_personality_decl; @@ -3694,7 +3696,7 @@ do_whole_program_analysis (void) bitmap_obstack_initialize (NULL); cgraph_state = CGRAPH_STATE_IPA_SSA; - execute_ipa_pass_list (all_regular_ipa_passes); + execute_ipa_pass_list (g->get_passes ()->all_regular_ipa_passes); symtab_remove_unreachable_nodes (false, dump_file); if (cgraph_dump_file) diff --git a/gcc/pass_manager.h b/gcc/pass_manager.h new file mode 100644 index 0000000..f66cd80 --- /dev/null +++ b/gcc/pass_manager.h @@ -0,0 +1,89 @@ +/* pass_manager.h - The pipeline of optimization passes + Copyright (C) 2013 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#ifndef GCC_PASS_MANAGER_H +#define GCC_PASS_MANAGER_H + +class opt_pass; +struct register_pass_info; + +/* Define a list of pass lists so that both passes.c and plugins can easily + find all the pass lists. */ +#define GCC_PASS_LISTS \ + DEF_PASS_LIST (all_lowering_passes) \ + DEF_PASS_LIST (all_small_ipa_passes) \ + DEF_PASS_LIST (all_regular_ipa_passes) \ + DEF_PASS_LIST (all_lto_gen_passes) \ + DEF_PASS_LIST (all_passes) + +#define DEF_PASS_LIST(LIST) PASS_LIST_NO_##LIST, +enum pass_list +{ + GCC_PASS_LISTS + PASS_LIST_NUM +}; +#undef DEF_PASS_LIST + +namespace gcc { + +class context; + +class pass_manager +{ +public: + pass_manager(context *ctxt); + + void register_pass (struct register_pass_info *pass_info); + void register_one_dump_file (struct opt_pass *pass); + + opt_pass *get_pass_for_id (int id) const; + + void dump_passes () const; + + void dump_profile_report () const; + +public: + /* The root of the compilation pass tree, once constructed. */ + opt_pass *all_passes; + opt_pass *all_small_ipa_passes; + opt_pass *all_lowering_passes; + opt_pass *all_regular_ipa_passes; + opt_pass *all_lto_gen_passes; + opt_pass *all_late_ipa_passes; + + /* A map from static pass id to optimization pass. */ + opt_pass **passes_by_id; + int passes_by_id_size; + + opt_pass **pass_lists[PASS_LIST_NUM]; + +private: + void set_pass_for_id (int id, opt_pass *pass); + int register_dump_files_1 (struct opt_pass *pass, int properties); + void register_dump_files (struct opt_pass *pass, int properties); + +private: + context *ctxt_; + +}; // class pass_manager + +} // namespace gcc + +#endif /* ! GCC_PASS_MANAGER_H */ + diff --git a/gcc/passes.c b/gcc/passes.c index 94fb586..b8ab1e8 100644 --- a/gcc/passes.c +++ b/gcc/passes.c @@ -70,6 +70,10 @@ along with GCC; see the file COPYING3. If not see #include "plugin.h" #include "ipa-utils.h" #include "tree-pretty-print.h" /* for dump_function_header */ +#include "context.h" +#include "pass_manager.h" + +using namespace gcc; /* This is used for debugging. It allows the current pass to printed from anywhere in compilation. @@ -439,23 +443,11 @@ static 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_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, -struct opt_pass **gcc_pass_lists[] = { GCC_PASS_LISTS NULL }; -#undef DEF_PASS_LIST - -/* A map from static pass id to optimization pass. */ -struct opt_pass **passes_by_id; -int passes_by_id_size; - /* Set the static pass number of pass PASS to ID and record that in the mapping from static pass number to pass. */ -static void +void +pass_manager:: set_pass_for_id (int id, struct opt_pass *pass) { pass->static_pass_number = id; @@ -472,7 +464,7 @@ set_pass_for_id (int id, struct opt_pass *pass) /* Return the pass with the static pass number ID. */ struct opt_pass * -get_pass_for_id (int id) +pass_manager::get_pass_for_id (int id) const { if (id >= passes_by_id_size) return NULL; @@ -486,6 +478,12 @@ get_pass_for_id (int id) void register_one_dump_file (struct opt_pass *pass) { + g->get_passes ()->register_one_dump_file (pass); +} + +void +pass_manager::register_one_dump_file (struct opt_pass *pass) +{ char *dot_name, *flag_name, *glob_name; const char *name, *full_name, *prefix; char num[10]; @@ -535,7 +533,8 @@ register_one_dump_file (struct opt_pass *pass) /* Recursive worker function for register_dump_files. */ -static int +int +pass_manager:: register_dump_files_1 (struct opt_pass *pass, int properties) { do @@ -563,11 +562,12 @@ register_dump_files_1 (struct opt_pass *pass, int properties) return properties; } -/* Register the dump files for the pipeline starting at PASS. +/* Register the dump files for the pass_manager starting at PASS. PROPERTIES reflects the properties that are guaranteed to be available at the beginning of the pipeline. */ -static void +void +pass_manager:: register_dump_files (struct opt_pass *pass,int properties) { pass->properties_required |= properties; @@ -663,7 +663,7 @@ create_pass_tab (void) if (!flag_dump_passes) return; - pass_tab.safe_grow_cleared (passes_by_id_size + 1); + pass_tab.safe_grow_cleared (g->get_passes ()->passes_by_id_size + 1); name_to_pass_map.traverse <void *, passes_pass_traverse> (NULL); } @@ -714,6 +714,12 @@ dump_pass_list (struct opt_pass *pass, int indent) void dump_passes (void) { + g->get_passes ()->dump_passes (); +} + +void +pass_manager::dump_passes () const +{ struct cgraph_node *n, *node = NULL; create_pass_tab(); @@ -1188,6 +1194,13 @@ position_pass (struct register_pass_info *new_pass_info, void register_pass (struct register_pass_info *pass_info) { + g->get_passes ()->register_pass (pass_info); + +} + +void +pass_manager::register_pass (struct register_pass_info *pass_info) +{ bool all_instances, success; /* The checks below could fail in buggy plugins. Existing GCC @@ -1277,11 +1290,21 @@ register_pass (struct register_pass_info *pass_info) -> all_passes */ -void -init_optimization_passes (void) +pass_manager::pass_manager (context *ctxt) +: all_passes(NULL), all_small_ipa_passes(NULL), all_lowering_passes(NULL), + all_regular_ipa_passes(NULL), all_lto_gen_passes(NULL), + all_late_ipa_passes(NULL), passes_by_id(NULL), passes_by_id_size(0), + ctxt_(ctxt) { struct opt_pass **p; + /* Initialize the pass_lists array. */ +#define DEF_PASS_LIST(LIST) pass_lists[PASS_LIST_NO_##LIST] = &LIST; + GCC_PASS_LISTS +#undef DEF_PASS_LIST + + /* Build the tree of passes. */ + #define INSERT_PASSES_AFTER(PASS) \ p = &(PASS); @@ -1432,12 +1455,13 @@ static struct profile_record *profile_record; static void check_profile_consistency (int index, int subpass, bool run) { + pass_manager *passes = g->get_passes (); if (index == -1) return; if (!profile_record) profile_record = XCNEWVEC (struct profile_record, - passes_by_id_size); - gcc_assert (index < passes_by_id_size && index >= 0); + passes->passes_by_id_size); + gcc_assert (index < passes->passes_by_id_size && index >= 0); gcc_assert (subpass < 2); profile_record[index].run |= run; account_profile_record (&profile_record[index], subpass); @@ -1448,6 +1472,12 @@ check_profile_consistency (int index, int subpass, bool run) void dump_profile_report (void) { + g->get_passes ()->dump_profile_report (); +} + +void +pass_manager::dump_profile_report () const +{ int i, j; int last_freq_in = 0, last_count_in = 0, last_freq_out = 0, last_count_out = 0; gcov_type last_time = 0, last_size = 0; @@ -2067,14 +2097,15 @@ ipa_write_summaries_2 (struct opt_pass *pass, struct lto_out_decl_state *state) static void ipa_write_summaries_1 (lto_symtab_encoder_t encoder) { + pass_manager *passes = g->get_passes (); struct lto_out_decl_state *state = lto_new_out_decl_state (); state->symtab_node_encoder = encoder; lto_push_out_decl_state (state); gcc_assert (!flag_wpa); - ipa_write_summaries_2 (all_regular_ipa_passes, state); - ipa_write_summaries_2 (all_lto_gen_passes, state); + ipa_write_summaries_2 (passes->all_regular_ipa_passes, state); + ipa_write_summaries_2 (passes->all_lto_gen_passes, state); gcc_assert (lto_get_out_decl_state () == state); lto_pop_out_decl_state (); @@ -2205,8 +2236,9 @@ ipa_write_optimization_summaries (lto_symtab_encoder_t encoder) } gcc_assert (flag_wpa); - ipa_write_optimization_summaries_1 (all_regular_ipa_passes, state); - ipa_write_optimization_summaries_1 (all_lto_gen_passes, state); + pass_manager *passes = g->get_passes (); + ipa_write_optimization_summaries_1 (passes->all_regular_ipa_passes, state); + ipa_write_optimization_summaries_1 (passes->all_lto_gen_passes, state); gcc_assert (lto_get_out_decl_state () == state); lto_pop_out_decl_state (); @@ -2259,8 +2291,9 @@ ipa_read_summaries_1 (struct opt_pass *pass) void ipa_read_summaries (void) { - ipa_read_summaries_1 (all_regular_ipa_passes); - ipa_read_summaries_1 (all_lto_gen_passes); + pass_manager *passes = g->get_passes (); + ipa_read_summaries_1 (passes->all_regular_ipa_passes); + ipa_read_summaries_1 (passes->all_lto_gen_passes); } /* Same as execute_pass_list but assume that subpasses of IPA passes @@ -2308,8 +2341,9 @@ ipa_read_optimization_summaries_1 (struct opt_pass *pass) void ipa_read_optimization_summaries (void) { - ipa_read_optimization_summaries_1 (all_regular_ipa_passes); - ipa_read_optimization_summaries_1 (all_lto_gen_passes); + pass_manager *passes = g->get_passes (); + ipa_read_optimization_summaries_1 (passes->all_regular_ipa_passes); + ipa_read_optimization_summaries_1 (passes->all_lto_gen_passes); } /* Same as execute_pass_list but assume that subpasses of IPA passes @@ -2384,7 +2418,8 @@ execute_ipa_stmt_fixups (struct opt_pass *pass, void execute_all_ipa_stmt_fixups (struct cgraph_node *node, gimple *stmts) { - execute_ipa_stmt_fixups (all_regular_ipa_passes, node, stmts); + pass_manager *passes = g->get_passes (); + execute_ipa_stmt_fixups (passes->all_regular_ipa_passes, node, stmts); } diff --git a/gcc/statistics.c b/gcc/statistics.c index 3077cc0..b198b34 100644 --- a/gcc/statistics.c +++ b/gcc/statistics.c @@ -26,6 +26,8 @@ along with GCC; see the file COPYING3. If not see #include "statistics.h" #include "hash-table.h" #include "function.h" +#include "context.h" +#include "pass_manager.h" static int statistics_dump_nr; static int statistics_dump_flags; @@ -235,6 +237,7 @@ statistics_fini_1 (statistics_counter_t **slot, opt_pass *pass) void statistics_fini (void) { + gcc::pass_manager *passes = g->get_passes (); if (!statistics_dump_file) return; @@ -243,10 +246,10 @@ statistics_fini (void) unsigned i; for (i = 0; i < nr_statistics_hashes; ++i) if (statistics_hashes[i].is_created () - && get_pass_for_id (i) != NULL) + && passes->get_pass_for_id (i) != NULL) statistics_hashes[i] .traverse_noresize <opt_pass *, statistics_fini_1> - (get_pass_for_id (i)); + (passes->get_pass_for_id (i)); } dump_end (statistics_dump_nr, statistics_dump_file); diff --git a/gcc/toplev.c b/gcc/toplev.c index de28a2d..9187529 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -1158,10 +1158,10 @@ general_init (const char *argv0) processing. */ init_ggc_heuristics(); - /* Create the singleton holder for global state. */ + /* Create the singleton holder for global state. + Doing so also creates the pass manager and with it the passes. */ g = new gcc::context(); - init_optimization_passes (); statistics_early_init (); finish_params (); } diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h index 547f355..16442ed 100644 --- a/gcc/tree-pass.h +++ b/gcc/tree-pass.h @@ -489,35 +489,9 @@ extern struct gimple_opt_pass pass_inline_parameters; extern struct gimple_opt_pass pass_update_address_taken; extern struct gimple_opt_pass pass_convert_switch; -/* The root of the compilation pass tree, once constructed. */ -extern struct opt_pass *all_passes, *all_small_ipa_passes, *all_lowering_passes, - *all_regular_ipa_passes, *all_lto_gen_passes, *all_late_ipa_passes; - -/* Define a list of pass lists so that both passes.c and plugins can easily - find all the pass lists. */ -#define GCC_PASS_LISTS \ - DEF_PASS_LIST (all_lowering_passes) \ - DEF_PASS_LIST (all_small_ipa_passes) \ - DEF_PASS_LIST (all_regular_ipa_passes) \ - DEF_PASS_LIST (all_lto_gen_passes) \ - DEF_PASS_LIST (all_passes) - -#define DEF_PASS_LIST(LIST) PASS_LIST_NO_##LIST, -enum -{ - GCC_PASS_LISTS - PASS_LIST_NUM -}; -#undef DEF_PASS_LIST - -/* This is used by plugins, and should also be used in - passes.c:register_pass. */ -extern struct opt_pass **gcc_pass_lists[]; - /* Current optimization pass. */ extern struct opt_pass *current_pass; -extern struct opt_pass * get_pass_for_id (int); extern bool execute_one_pass (struct opt_pass *); extern void execute_pass_list (struct opt_pass *); extern void execute_ipa_pass_list (struct opt_pass *); @@ -547,9 +521,6 @@ extern void register_pass (struct register_pass_info *); directly in jump threading, and avoid peeling them next time. */ extern bool first_pass_instance; -extern struct opt_pass **passes_by_id; -extern int passes_by_id_size; - /* Declare for plugins. */ extern void do_per_function_toporder (void (*) (void *), void *); -- 1.7.11.7