From patchwork Wed Jul 24 15:09:04 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Malcolm X-Patchwork-Id: 261435 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "localhost", Issuer "www.qmailtoaster.com" (not verified)) by ozlabs.org (Postfix) with ESMTPS id 1ACE42C009A for ; Thu, 25 Jul 2013 01:10:02 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:in-reply-to:references; q=dns; s= default; b=OdftV2IefQeiKDMTXICLnn3otuzWppLaT5SW5QBzfNkXe3S197Bq4 PfqPA3I7eU5NVEW9B5khknxeR+ENasS30/FeEJtrso1ICc0gGQjk2fkiICa5V33Y YNASlTbf2wIQcM2tiEfuHWiuEIrlIuxud+GqWBPm5yc5UgvzO6veb8= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:in-reply-to:references; s= default; bh=cLmNlbWTm++FMth7dTJRoxu27sg=; b=HMRqLvVMUx/gbxdhvnQD EQVDYi79jTLGwFJETYz895hPsIVboypvzaD3D2NceeG7GtJ+k6k5XX41/f6VOHPX 4PlYxsVTGWkOLX4zFexAV68kB1uMbc8bH1usICO49/nil1QY9miukULQOGETd8TN GdFr+HLe0UuFHhtpPjUfeM4= Received: (qmail 19539 invoked by alias); 24 Jul 2013 15:09:20 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 19420 invoked by uid 89); 24 Jul 2013 15:09:19 -0000 X-Spam-SWARE-Status: No, score=-4.5 required=5.0 tests=AWL, BAYES_50, KHOP_THREADED, RCVD_IN_HOSTKARMA_W, RCVD_IN_HOSTKARMA_WL, RDNS_NONE, SPF_HELO_PASS, SPF_PASS autolearn=no version=3.3.1 Received: from Unknown (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Wed, 24 Jul 2013 15:09:17 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r6OF9947016307 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Wed, 24 Jul 2013 11:09:09 -0400 Received: from surprise.bos.redhat.com ([10.18.25.132]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id r6OF97Z2011154; Wed, 24 Jul 2013 11:09:09 -0400 From: David Malcolm To: gcc-patches@gcc.gnu.org Cc: David Malcolm Subject: [PATCH 2/2] Introduce beginnings of a pipeline class. Date: Wed, 24 Jul 2013 11:09:04 -0400 Message-Id: <1374678544-8678-3-git-send-email-dmalcolm@redhat.com> In-Reply-To: <1374678544-8678-1-git-send-email-dmalcolm@redhat.com> References: <1374678544-8678-1-git-send-email-dmalcolm@redhat.com> gcc/ * Makefile.in (PIPELINE_H): New. (lto-cgraph.o): Depend on CONTEXT_H and PIPELINE_H. (passes.o): Likewise. (statistics.o): Likewise. (cgraphunit.o): Likewise. (context.o): Depend on PIPELINE_H. * pipeline.h: New. * cgraphunit.c (cgraph_add_new_function): Update for moves of globals to fields of pipeline. (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 pipeline. * passes.c (all_passes): Remove, in favor of a field of the same name within the new class pipeline. (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 pipeline. (set_pass_for_id): Convert to... (pipeline::set_pass_for_id): ...method. (get_pass_for_id): Convert to... (pipeline::get_pass_for_id): ...method. (register_one_dump_file): Move body of implementation into... (pipeline::register_one_dump_file): ...here. (register_dump_files_1): Convert to... (pipeline::register_dump_files_1): ...method. (register_dump_files): Convert to... (pipeline::register_dump_files): ...method. (create_pass_tab): Update for moves of globals to fields of pipeline. (dump_passes): Move body of implementation into... (pipeline::dump_passes): ...here. (register_pass): Move body of implementation into... (pipeline::register_pass): ...here. (init_optimization_passes): Convert into... (pipeline::pipeline): ...constructor for new pipeline class, and initialize the pass_lists array. (check_profile_consistency): Update for moves of globals to fields of pipeline. (dump_profile_report): Move body of implementation into... (pipeline::dump_profile_report): ...here. (ipa_write_summaries_1): Update for moves of pass lists from being globals to fields of pipeline. (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 pipeline. * toplev.c (general_init): Replace call to init_optimization_passes with construction of the pipeline instance. * tree-pass.h (all_passes): Remove, in favor of a field of the same name within the new class pipeline. (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 pipeline. (get_pass_for_id): Remove. gcc/lto/ * Make-lang.in (lto/lto.o:): Depend on CONTEXT_H and PIPELINE_H. * lto.c (do_whole_program_analysis): Update for move of all_regular_ipa_passes from a global to a field of class pipeline. --- 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/passes.c | 97 +++++++++++++++++++++++++++++++++++----------------- gcc/pipeline.h | 89 +++++++++++++++++++++++++++++++++++++++++++++++ gcc/statistics.c | 7 ++-- gcc/toplev.c | 4 +-- gcc/tree-pass.h | 29 ---------------- 12 files changed, 212 insertions(+), 82 deletions(-) create mode 100644 gcc/pipeline.h diff --git a/gcc/Makefile.in b/gcc/Makefile.in index fb0cb4b..0b28c2d 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 +PIPELINE_H = pipeline.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) $(PIPELINE_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) $(PIPELINE_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) $(PIPELINE_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) $(PIPELINE_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) $(PIPELINE_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..dc489fb 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 "pipeline.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::pipeline &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::pipeline &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..8ec2e60 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 "pipeline.h" /* The singleton holder of global state: */ gcc::context *g; + +gcc::context::context() +{ + passes_ = new gcc::pipeline(this); +} diff --git a/gcc/context.h b/gcc/context.h index 3caf02f..a83f7b2 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 pipeline; + /* 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. */ + + pipeline &get_passes () { gcc_assert (passes_); return *passes_; } - /* Currently empty. */ +private: + /* Pass-management. */ + pipeline *passes_; }; // class context diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c index 4a287f6..d322d9a 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 "pipeline.h" static void output_cgraph_opt_summary (void); static void input_cgraph_opt_summary (vec nodes); @@ -936,6 +938,7 @@ input_node (struct lto_file_decl_data *file_data, enum LTO_symtab_tags tag, vec nodes) { + gcc::pipeline &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..e7ca937 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 "pipeline.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/passes.c b/gcc/passes.c index 94fb586..e625bf2 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 "pipeline.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 +pipeline:: 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) +pipeline::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 +pipeline::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 +pipeline:: register_dump_files_1 (struct opt_pass *pass, int properties) { do @@ -567,7 +566,8 @@ register_dump_files_1 (struct opt_pass *pass, int properties) PROPERTIES reflects the properties that are guaranteed to be available at the beginning of the pipeline. */ -static void +void +pipeline:: 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 (NULL); } @@ -714,6 +714,12 @@ dump_pass_list (struct opt_pass *pass, int indent) void dump_passes (void) { + g->get_passes ().dump_passes (); +} + +void +pipeline::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 +pipeline::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) +pipeline::pipeline (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) { + pipeline &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 +pipeline::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) { + pipeline &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); + pipeline &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); + pipeline &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); + pipeline &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); + pipeline &passes = g->get_passes (); + execute_ipa_stmt_fixups (passes.all_regular_ipa_passes, node, stmts); } diff --git a/gcc/pipeline.h b/gcc/pipeline.h new file mode 100644 index 0000000..37c90d7 --- /dev/null +++ b/gcc/pipeline.h @@ -0,0 +1,89 @@ +/* pipeline.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 +. */ + +#ifndef GCC_PIPELINE_H +#define GCC_PIPELINE_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 pipeline +{ +public: + pipeline(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 pipeline + +} // namespace gcc + +#endif /* ! GCC_PIPELINE_H */ + diff --git a/gcc/statistics.c b/gcc/statistics.c index 3077cc0..c7e6abd 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 "pipeline.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::pipeline &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 - (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..1cf98dc 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 pipeline of 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 *);