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

Reply via email to