aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2013-08-05 20:01:43 +0000
committerDavid Malcolm <dmalcolm@gcc.gnu.org>2013-08-05 20:01:43 +0000
commitf7695dbf402847104b2330126a3c61fae199cc1a (patch)
treecdd5686bbad14a7a9b7c4e8de621c8b7b8826c56 /gcc
parentd0b2f8311e5e1917464aa4f65d506fbe4e580eb1 (diff)
downloadgcc-f7695dbf402847104b2330126a3c61fae199cc1a.zip
gcc-f7695dbf402847104b2330126a3c61fae199cc1a.tar.gz
gcc-f7695dbf402847104b2330126a3c61fae199cc1a.tar.bz2
Handwritten part of conversion of passes to C++ classes
gcc/ * Makefile.in (PASS_MANAGER_H): Add dep on pass-instances.def. (toplev.o): Add dep on PASS_MANAGER_H. * cgraphunit.c (cgraph_process_new_functions): Rework invocation of early local pases to reflect this moving from a global to a member of gcc::pass_manager. (cgraph_add_new_function): Likewise. * lto-cgraph.c (lto_output_node): Update for conversion of struct ipa_opt_pass_d to a C++ subclass of opt_pass. * passes.c (opt_pass::clone): New. (opt_pass::gate): New. (opt_pass::execute): New. (opt_pass::opt_pass): New. (pass_manager::execute_early_local_passes): New. (pass_manager::execute_pass_mode_switching): new. (finish_optimization_passes): Convert to... (pass_manager::finish_optimization_passes): ...this. (finish_optimization_passes): Update for conversion of passes to C++ classes. (register_dump_files_1): Use has_gate since we cannot portably check a vtable entry against NULL. (dump_one_pass): Likewise. (ipa_write_summaries_2): Likewise. (ipa_write_optimization_summaries_1): Likewise. (ipa_read_summaries_1): Likewise. (ipa_read_optimization_summaries_1): Likewise. (execute_ipa_stmt_fixups): Likewise. (pass_manager::pass_manager): Rewrite pass-creation, invoking pass-creation functions rather than wiring up globals, and storing the results in fields of pass_manager generated using pass-instances.def. (pass_manager::dump_profile_report): Update for conversion of passes to C++ classes. (pass_manager::execute_ipa_summary_passes): Likewise. (execute_one_ipa_transform_pass): Likewise. (execute_one_pass): Use has_gate and has_execute since we cannot portably check a vtable entry against NULL. * pass_manager.h (pass_manager::finish_optimization_passes): New. (pass_manager): Use pass-instances.def to add fields for the various pass instances. * toplev.c (finalize): Update for move of finish_optimization_passes to a method of gcc::pass_manager. * toplev.h (finish_optimization_passes): Move to method of class pass_manager. * tree-pass.h (struct pass_data): New. (opt_pass): Convert to C++ class, make it a subclass of pass_data. (opt_pass::gate): Convert to virtual function. (opt_pass::~opt_pass): New. (opt_pass::clone): New. (opt_pass::execute): Convert to virtual function. (opt_pass::opt_pass): New. (opt_pass::ctxt_): new. (gimple_opt_pass): Convert to subclass of opt_pass. (gimple_opt_pass::gimple_opt_pass): New. (rtl_opt_pass): Convert to subclass of opt_pass. (rtl_opt_pass::rtl_opt_pass): New. (ipa_opt_pass_d): Convert to subclass of opt_pass. (ipa_opt_pass_d::ipa_opt_pass_d): New. (simple_ipa_opt_pass): Convert to subclass of opt_pass. (simple_ipa_opt_pass::simple_ipa_opt_pass): New. * config/i386/i386.c (rest_of_handle_insert_vzeroupper): Rework invocation of pass_mode_switching to reflect this moving from a global to a member of gcc::pass_manager. (ix86_option_override): Rework how pass_insert_vzeroupper is added to the pass_manager to reflect autogenerated changes. * config/i386/t-i386 (i386.o) Add deps on CONTEXT_H and PASS_MANAGER_H. gcc/testsuite/ * g++.dg/plugin/dumb_plugin.c (plugin_init): Rework how the pass is created and added to the pass_manager to reflect autogenerated changes. * g++.dg/plugin/selfassign.c (plugin_init): Likewise. * gcc.dg/plugin/one_time_plugin.c (plugin_init): Likewise. * gcc.dg/plugin/selfassign.c (plugin_init): Likewise. From-SVN: r201505
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog72
-rw-r--r--gcc/Makefile.in4
-rw-r--r--gcc/cgraphunit.c6
-rw-r--r--gcc/config/i386/i386.c7
-rw-r--r--gcc/config/i386/t-i3862
-rw-r--r--gcc/lto-cgraph.c2
-rw-r--r--gcc/pass_manager.h37
-rw-r--r--gcc/passes.c102
-rw-r--r--gcc/testsuite/ChangeLog9
-rw-r--r--gcc/testsuite/g++.dg/plugin/dumb_plugin.c3
-rw-r--r--gcc/testsuite/g++.dg/plugin/selfassign.c3
-rw-r--r--gcc/testsuite/gcc.dg/plugin/one_time_plugin.c3
-rw-r--r--gcc/testsuite/gcc.dg/plugin/selfassign.c3
-rw-r--r--gcc/toplev.c3
-rw-r--r--gcc/toplev.h1
-rw-r--r--gcc/tree-pass.h129
16 files changed, 322 insertions, 64 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index eece522..ffa880b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,75 @@
+2013-08-05 David Malcolm <dmalcolm@redhat.com>
+
+ Handwritten part of conversion of passes to C++ classes.
+
+ * Makefile.in (PASS_MANAGER_H): Add dep on pass-instances.def.
+ (toplev.o): Add dep on PASS_MANAGER_H.
+ * cgraphunit.c (cgraph_process_new_functions): Rework invocation
+ of early local pases to reflect this moving from a global to a
+ member of gcc::pass_manager.
+ (cgraph_add_new_function): Likewise.
+ * lto-cgraph.c (lto_output_node): Update for conversion of
+ struct ipa_opt_pass_d to a C++ subclass of opt_pass.
+ * passes.c (opt_pass::clone): New.
+ (opt_pass::gate): New.
+ (opt_pass::execute): New.
+ (opt_pass::opt_pass): New.
+ (pass_manager::execute_early_local_passes): New.
+ (pass_manager::execute_pass_mode_switching): new.
+ (finish_optimization_passes): Convert to...
+ (pass_manager::finish_optimization_passes): ...this.
+ (finish_optimization_passes): Update for conversion of passes to
+ C++ classes.
+ (register_dump_files_1): Use has_gate since we cannot portably
+ check a vtable entry against NULL.
+ (dump_one_pass): Likewise.
+ (ipa_write_summaries_2): Likewise.
+ (ipa_write_optimization_summaries_1): Likewise.
+ (ipa_read_summaries_1): Likewise.
+ (ipa_read_optimization_summaries_1): Likewise.
+ (execute_ipa_stmt_fixups): Likewise.
+ (pass_manager::pass_manager): Rewrite pass-creation, invoking
+ pass-creation functions rather than wiring up globals, and
+ storing the results in fields of pass_manager generated using
+ pass-instances.def.
+ (pass_manager::dump_profile_report): Update for conversion of
+ passes to C++ classes.
+ (pass_manager::execute_ipa_summary_passes): Likewise.
+ (execute_one_ipa_transform_pass): Likewise.
+ (execute_one_pass): Use has_gate and has_execute since we cannot
+ portably check a vtable entry against NULL.
+ * pass_manager.h (pass_manager::finish_optimization_passes): New.
+ (pass_manager): Use pass-instances.def to add fields for the
+ various pass instances.
+ * toplev.c (finalize): Update for move of
+ finish_optimization_passes to a method of gcc::pass_manager.
+ * toplev.h (finish_optimization_passes): Move to method of class
+ pass_manager.
+ * tree-pass.h (struct pass_data): New.
+ (opt_pass): Convert to C++ class, make it a subclass of
+ pass_data.
+ (opt_pass::gate): Convert to virtual function.
+ (opt_pass::~opt_pass): New.
+ (opt_pass::clone): New.
+ (opt_pass::execute): Convert to virtual function.
+ (opt_pass::opt_pass): New.
+ (opt_pass::ctxt_): new.
+ (gimple_opt_pass): Convert to subclass of opt_pass.
+ (gimple_opt_pass::gimple_opt_pass): New.
+ (rtl_opt_pass): Convert to subclass of opt_pass.
+ (rtl_opt_pass::rtl_opt_pass): New.
+ (ipa_opt_pass_d): Convert to subclass of opt_pass.
+ (ipa_opt_pass_d::ipa_opt_pass_d): New.
+ (simple_ipa_opt_pass): Convert to subclass of opt_pass.
+ (simple_ipa_opt_pass::simple_ipa_opt_pass): New.
+ * config/i386/i386.c (rest_of_handle_insert_vzeroupper): Rework
+ invocation of pass_mode_switching to reflect this moving from a
+ global to a member of gcc::pass_manager.
+ (ix86_option_override): Rework how pass_insert_vzeroupper is
+ added to the pass_manager to reflect autogenerated changes.
+ * config/i386/t-i386 (i386.o) Add deps on CONTEXT_H and
+ PASS_MANAGER_H.
+
2013-08-05 Richard Earnshaw <rearnsha@arm.com>
PR rtl-optimization/57708
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 40ad19d..afce540 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -987,7 +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
+PASS_MANAGER_H = pass_manager.h pass-instances.def
#
# Now figure out from those variables how to compile and link.
@@ -2733,7 +2733,7 @@ toplev.o : toplev.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
$(OPTS_H) params.def tree-mudflap.h $(TREE_PASS_H) $(GIMPLE_H) \
tree-ssa-alias.h $(PLUGIN_H) realmpfr.h tree-diagnostic.h \
$(TREE_PRETTY_PRINT_H) opts-diagnostic.h $(COMMON_TARGET_H) \
- tsan.h diagnostic-color.h $(CONTEXT_H)
+ tsan.h diagnostic-color.h $(CONTEXT_H) $(PASS_MANAGER_H)
hwint.o : hwint.c $(CONFIG_H) $(SYSTEM_H) $(DIAGNOSTIC_CORE_H)
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index e308b52..ad91117 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -325,7 +325,7 @@ cgraph_process_new_functions (void)
push_cfun (DECL_STRUCT_FUNCTION (fndecl));
if (cgraph_state == CGRAPH_STATE_IPA_SSA
&& !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
- execute_pass_list (pass_early_local_passes.pass.sub);
+ g->get_passes ()->execute_early_local_passes ();
else if (inline_summary_vec != NULL)
compute_inline_parameters (node, true);
free_dominance_info (CDI_POST_DOMINATORS);
@@ -509,7 +509,7 @@ cgraph_add_new_function (tree fndecl, bool lowered)
gimple_register_cfg_hooks ();
bitmap_obstack_initialize (NULL);
execute_pass_list (passes->all_lowering_passes);
- execute_pass_list (pass_early_local_passes.pass.sub);
+ passes->execute_early_local_passes ();
bitmap_obstack_release (NULL);
pop_cfun ();
@@ -534,7 +534,7 @@ cgraph_add_new_function (tree fndecl, bool lowered)
gimple_register_cfg_hooks ();
bitmap_obstack_initialize (NULL);
if (!gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
- execute_pass_list (pass_early_local_passes.pass.sub);
+ g->get_passes ()->execute_early_local_passes ();
bitmap_obstack_release (NULL);
pop_cfun ();
expand_function (node);
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index df79eac..cce3c9c 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -62,6 +62,8 @@ along with GCC; see the file COPYING3. If not see
#include "dumpfile.h"
#include "tree-pass.h"
#include "tree-flow.h"
+#include "context.h"
+#include "pass_manager.h"
static rtx legitimize_dllimport_symbol (rtx, bool);
static rtx legitimize_pe_coff_extern_decl (rtx, bool);
@@ -2596,7 +2598,7 @@ rest_of_handle_insert_vzeroupper (void)
ix86_optimize_mode_switching[AVX_U128] = 1;
/* Call optimize_mode_switching. */
- pass_mode_switching.pass.execute ();
+ g->get_passes ()->execute_pass_mode_switching ();
return 0;
}
@@ -4028,8 +4030,9 @@ ix86_option_override_internal (bool main_args_p)
static void
ix86_option_override (void)
{
+ opt_pass *pass_insert_vzeroupper = make_pass_insert_vzeroupper (g);
static struct register_pass_info insert_vzeroupper_info
- = { &pass_insert_vzeroupper.pass, "reload",
+ = { pass_insert_vzeroupper, "reload",
1, PASS_POS_INSERT_AFTER
};
diff --git a/gcc/config/i386/t-i386 b/gcc/config/i386/t-i386
index 3a77e14..f10d570 100644
--- a/gcc/config/i386/t-i386
+++ b/gcc/config/i386/t-i386
@@ -24,7 +24,7 @@ i386.o: $(CONFIG_H) $(SYSTEM_H) coretypes.h dumpfile.h $(TM_H) \
$(GGC_H) $(TARGET_H) $(TARGET_DEF_H) langhooks.h $(CGRAPH_H) \
$(TREE_GIMPLE_H) $(DWARF2_H) $(DF_H) tm-constrs.h $(PARAMS_H) \
i386-builtin-types.inc debug.h dwarf2out.h sbitmap.h $(FIBHEAP_H) \
- $(OPTS_H) $(DIAGNOSTIC_H) $(COMMON_TARGET_H)
+ $(OPTS_H) $(DIAGNOSTIC_H) $(COMMON_TARGET_H) $(CONTEXT_H) $(PIPELINE_H)
i386-c.o: $(srcdir)/config/i386/i386-c.c \
$(srcdir)/config/i386/i386-protos.h $(CONFIG_H) $(SYSTEM_H) coretypes.h \
diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c
index c3c393f..0dde03a 100644
--- a/gcc/lto-cgraph.c
+++ b/gcc/lto-cgraph.c
@@ -438,7 +438,7 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
streamer_write_hwi_stream (ob->main_stream,
node->ipa_transforms_to_apply.length ());
FOR_EACH_VEC_ELT (node->ipa_transforms_to_apply, i, pass)
- streamer_write_hwi_stream (ob->main_stream, pass->pass.static_pass_number);
+ streamer_write_hwi_stream (ob->main_stream, pass->static_pass_number);
if (tag == LTO_symtab_analyzed_node)
{
diff --git a/gcc/pass_manager.h b/gcc/pass_manager.h
index f66cd80..ea078a5 100644
--- a/gcc/pass_manager.h
+++ b/gcc/pass_manager.h
@@ -58,6 +58,12 @@ public:
void dump_profile_report () const;
+ void finish_optimization_passes ();
+
+ /* Access to specific passes, so that the majority can be private. */
+ void execute_early_local_passes ();
+ unsigned int execute_pass_mode_switching ();
+
public:
/* The root of the compilation pass tree, once constructed. */
opt_pass *all_passes;
@@ -81,6 +87,37 @@ private:
private:
context *ctxt_;
+ /* References to all of the individual passes.
+ These fields are generated via macro expansion.
+
+ For example:
+ NEXT_PASS (pass_build_cfg, 1);
+ within pass-instances.def means that there is a field:
+ opt_pass *pass_build_cfg_1;
+
+ Similarly, the various:
+ NEXT_PASS (pass_copy_prop, 1);
+ ...
+ NEXT_PASS (pass_copy_prop, 8);
+ in pass-instances.def lead to fields:
+ opt_pass *pass_copy_prop_1;
+ ...
+ opt_pass *pass_copy_prop_8; */
+
+#define INSERT_PASSES_AFTER(PASS)
+#define PUSH_INSERT_PASSES_WITHIN(PASS)
+#define POP_INSERT_PASSES()
+#define NEXT_PASS(PASS, NUM) opt_pass *PASS ## _ ## NUM
+#define TERMINATE_PASS_LIST()
+
+#include "pass-instances.def"
+
+#undef INSERT_PASSES_AFTER
+#undef PUSH_INSERT_PASSES_WITHIN
+#undef POP_INSERT_PASSES
+#undef NEXT_PASS
+#undef TERMINATE_PASS_LIST
+
}; // class pass_manager
} // namespace gcc
diff --git a/gcc/passes.c b/gcc/passes.c
index a43a588..fcbd630 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -82,6 +82,54 @@ struct opt_pass *current_pass;
static void register_pass_name (struct opt_pass *, const char *);
+/* Most passes are single-instance (within their context) and thus don't
+ need to implement cloning, but passes that support multiple instances
+ *must* provide their own implementation of the clone method.
+
+ Handle this by providing a default implemenation, but make it a fatal
+ error to call it. */
+
+opt_pass *
+opt_pass::clone ()
+{
+ internal_error ("pass %s does not support cloning", name);
+}
+
+bool
+opt_pass::gate ()
+{
+ return true;
+}
+
+unsigned int
+opt_pass::execute ()
+{
+ return 0;
+}
+
+opt_pass::opt_pass(const pass_data &data, context *ctxt)
+ : pass_data(data),
+ sub(NULL),
+ next(NULL),
+ static_pass_number(0),
+ ctxt_(ctxt)
+{
+}
+
+
+void
+pass_manager::execute_early_local_passes ()
+{
+ execute_pass_list (pass_early_local_passes_1->sub);
+}
+
+unsigned int
+pass_manager::execute_pass_mode_switching ()
+{
+ return pass_mode_switching_1->execute ();
+}
+
+
/* Call from anywhere to find out what pass this is. Useful for
printing out debugging information deep inside an service
routine. */
@@ -224,6 +272,7 @@ rest_of_type_compilation (tree type, int toplev)
void
+pass_manager::
finish_optimization_passes (void)
{
int i;
@@ -233,16 +282,16 @@ finish_optimization_passes (void)
timevar_push (TV_DUMP);
if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
{
- dump_start (pass_profile.pass.static_pass_number, NULL);
+ dump_start (pass_profile_1->static_pass_number, NULL);
end_branch_prob ();
- dump_finish (pass_profile.pass.static_pass_number);
+ dump_finish (pass_profile_1->static_pass_number);
}
if (optimize > 0)
{
- dump_start (pass_profile.pass.static_pass_number, NULL);
+ dump_start (pass_profile_1->static_pass_number, NULL);
print_combine_total_stats ();
- dump_finish (pass_profile.pass.static_pass_number);
+ dump_finish (pass_profile_1->static_pass_number);
}
/* Do whatever is necessary to finish printing the graphs. */
@@ -550,7 +599,7 @@ register_dump_files_1 (struct opt_pass *pass, int properties)
/* If we have a gate, combine the properties that we could have with
and without the pass being examined. */
- if (pass->gate)
+ if (pass->has_gate)
properties &= new_properties;
else
properties = new_properties;
@@ -679,7 +728,7 @@ dump_one_pass (struct opt_pass *pass, int pass_indent)
const char *pn;
bool is_on, is_really_on;
- is_on = (pass->gate == NULL) ? true : pass->gate();
+ is_on = pass->has_gate ? pass->gate() : true;
is_really_on = override_gate_status (pass, current_function_decl, is_on);
if (pass->static_pass_number <= 0)
@@ -1310,12 +1359,23 @@ pass_manager::pass_manager (context *ctxt)
#define PUSH_INSERT_PASSES_WITHIN(PASS) \
{ \
- struct opt_pass **p = &(PASS).pass.sub;
+ struct opt_pass **p = &(PASS ## _1)->sub;
#define POP_INSERT_PASSES() \
}
-#define NEXT_PASS(PASS, NUM) (p = next_pass_1 (p, &((PASS).pass)))
+#define NEXT_PASS(PASS, NUM) \
+ do { \
+ gcc_assert (NULL == PASS ## _ ## NUM); \
+ if ((NUM) == 1) \
+ PASS ## _1 = make_##PASS (ctxt_); \
+ else \
+ { \
+ gcc_assert (PASS ## _1); \
+ PASS ## _ ## NUM = PASS ## _1->clone (); \
+ } \
+ p = next_pass_1 (p, PASS ## _ ## NUM); \
+ } while (0)
#define TERMINATE_PASS_LIST() \
*p = NULL;
@@ -1541,7 +1601,7 @@ pass_manager::dump_profile_report () const
fprintf (stderr, " ");
/* Size/time units change across gimple and RTL. */
- if (i == pass_expand.pass.static_pass_number)
+ if (i == pass_expand_1->static_pass_number)
fprintf (stderr, "|----------");
else
{
@@ -1778,11 +1838,11 @@ execute_ipa_summary_passes (struct ipa_opt_pass_d *ipa_pass)
{
while (ipa_pass)
{
- struct opt_pass *pass = &ipa_pass->pass;
+ struct opt_pass *pass = ipa_pass;
/* Execute all of the IPA_PASSes in the list. */
- if (ipa_pass->pass.type == IPA_PASS
- && (!pass->gate || pass->gate ())
+ if (ipa_pass->type == IPA_PASS
+ && ((!pass->has_gate) || pass->gate ())
&& ipa_pass->generate_summary)
{
pass_init_dump_file (pass);
@@ -1799,7 +1859,7 @@ execute_ipa_summary_passes (struct ipa_opt_pass_d *ipa_pass)
pass_fini_dump_file (pass);
}
- ipa_pass = (struct ipa_opt_pass_d *)ipa_pass->pass.next;
+ ipa_pass = (struct ipa_opt_pass_d *)ipa_pass->next;
}
}
@@ -1809,7 +1869,7 @@ static void
execute_one_ipa_transform_pass (struct cgraph_node *node,
struct ipa_opt_pass_d *ipa_pass)
{
- struct opt_pass *pass = &ipa_pass->pass;
+ struct opt_pass *pass = ipa_pass;
unsigned int todo_after = 0;
current_pass = pass;
@@ -1933,7 +1993,7 @@ execute_one_pass (struct opt_pass *pass)
/* Check whether gate check should be avoided.
User controls the value of the gate through the parameter "gate_status". */
- gate_status = (pass->gate == NULL) ? true : pass->gate();
+ gate_status = pass->has_gate ? pass->gate() : true;
gate_status = override_gate_status (pass, current_function_decl, gate_status);
/* Override gate with plugin. */
@@ -1990,7 +2050,7 @@ execute_one_pass (struct opt_pass *pass)
timevar_push (pass->tv_id);
/* Do it! */
- if (pass->execute)
+ if (pass->has_execute)
{
todo_after = pass->execute ();
do_per_function (clear_last_verified, NULL);
@@ -2066,7 +2126,7 @@ ipa_write_summaries_2 (struct opt_pass *pass, struct lto_out_decl_state *state)
gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
if (pass->type == IPA_PASS
&& ipa_pass->write_summary
- && (!pass->gate || pass->gate ()))
+ && ((!pass->has_gate) || pass->gate ()))
{
/* If a timevar is present, start it. */
if (pass->tv_id)
@@ -2182,7 +2242,7 @@ ipa_write_optimization_summaries_1 (struct opt_pass *pass, struct lto_out_decl_s
gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
if (pass->type == IPA_PASS
&& ipa_pass->write_optimization_summary
- && (!pass->gate || pass->gate ()))
+ && ((!pass->has_gate) || pass->gate ()))
{
/* If a timevar is present, start it. */
if (pass->tv_id)
@@ -2259,7 +2319,7 @@ ipa_read_summaries_1 (struct opt_pass *pass)
gcc_assert (!cfun);
gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
- if (pass->gate == NULL || pass->gate ())
+ if ((!pass->has_gate) || pass->gate ())
{
if (pass->type == IPA_PASS && ipa_pass->read_summary)
{
@@ -2310,7 +2370,7 @@ ipa_read_optimization_summaries_1 (struct opt_pass *pass)
gcc_assert (!cfun);
gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
- if (pass->gate == NULL || pass->gate ())
+ if ((!pass->has_gate) || pass->gate ())
{
if (pass->type == IPA_PASS && ipa_pass->read_optimization_summary)
{
@@ -2388,7 +2448,7 @@ execute_ipa_stmt_fixups (struct opt_pass *pass,
{
/* Execute all of the IPA_PASSes in the list. */
if (pass->type == IPA_PASS
- && (!pass->gate || pass->gate ()))
+ && ((!pass->has_gate) || pass->gate ()))
{
struct ipa_opt_pass_d *ipa_pass = (struct ipa_opt_pass_d *) pass;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index f356d55..387006e 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,12 @@
+2013-08-05 David Malcolm <dmalcolm@redhat.com>
+
+ * g++.dg/plugin/dumb_plugin.c (plugin_init): Rework how the pass
+ is created and added to the pass_manager to reflect
+ autogenerated changes.
+ * g++.dg/plugin/selfassign.c (plugin_init): Likewise.
+ * gcc.dg/plugin/one_time_plugin.c (plugin_init): Likewise.
+ * gcc.dg/plugin/selfassign.c (plugin_init): Likewise.
+
2013-08-04 Ed Smith-Rowland <3dw4rd@verizon.net>
PR c++/58072
diff --git a/gcc/testsuite/g++.dg/plugin/dumb_plugin.c b/gcc/testsuite/g++.dg/plugin/dumb_plugin.c
index 0f15140..ab69c14 100644
--- a/gcc/testsuite/g++.dg/plugin/dumb_plugin.c
+++ b/gcc/testsuite/g++.dg/plugin/dumb_plugin.c
@@ -11,6 +11,7 @@
#include "intl.h"
#include "toplev.h"
#include "diagnostic.h"
+#include "context.h"
int plugin_is_GPL_compatible;
@@ -124,7 +125,7 @@ plugin_init (struct plugin_name_args *plugin_info,
return 1;
}
- pass_info.pass = &pass_dumb_plugin_example.pass;
+ pass_info.pass = make_pass_dumb_plugin_example (g);
pass_info.reference_pass_name = ref_pass_name;
pass_info.ref_pass_instance_number = ref_instance_number;
pass_info.pos_op = PASS_POS_INSERT_AFTER;
diff --git a/gcc/testsuite/g++.dg/plugin/selfassign.c b/gcc/testsuite/g++.dg/plugin/selfassign.c
index 37a0a97..3e0b38e 100644
--- a/gcc/testsuite/g++.dg/plugin/selfassign.c
+++ b/gcc/testsuite/g++.dg/plugin/selfassign.c
@@ -15,6 +15,7 @@
#include "intl.h"
#include "plugin-version.h"
#include "diagnostic.h"
+#include "context.h"
int plugin_is_GPL_compatible;
@@ -309,7 +310,7 @@ plugin_init (struct plugin_name_args *plugin_info,
return 1;
/* Self-assign detection should happen after SSA is constructed. */
- pass_info.pass = &pass_warn_self_assign.pass;
+ pass_info.pass = make_pass_warn_self_assign (g);
pass_info.reference_pass_name = "ssa";
pass_info.ref_pass_instance_number = 1;
pass_info.pos_op = PASS_POS_INSERT_AFTER;
diff --git a/gcc/testsuite/gcc.dg/plugin/one_time_plugin.c b/gcc/testsuite/gcc.dg/plugin/one_time_plugin.c
index 45e6257..31dfe69 100644
--- a/gcc/testsuite/gcc.dg/plugin/one_time_plugin.c
+++ b/gcc/testsuite/gcc.dg/plugin/one_time_plugin.c
@@ -8,6 +8,7 @@
#include "gimple.h"
#include "tree-pass.h"
#include "intl.h"
+#include "context.h"
int plugin_is_GPL_compatible;
@@ -53,7 +54,7 @@ int plugin_init (struct plugin_name_args *plugin_info,
{
struct register_pass_info p;
- p.pass = &one_pass.pass;
+ p.pass = make_one_pass (g);
p.reference_pass_name = "cfg";
p.ref_pass_instance_number = 1;
p.pos_op = PASS_POS_INSERT_AFTER;
diff --git a/gcc/testsuite/gcc.dg/plugin/selfassign.c b/gcc/testsuite/gcc.dg/plugin/selfassign.c
index 37a0a97..3e0b38e 100644
--- a/gcc/testsuite/gcc.dg/plugin/selfassign.c
+++ b/gcc/testsuite/gcc.dg/plugin/selfassign.c
@@ -15,6 +15,7 @@
#include "intl.h"
#include "plugin-version.h"
#include "diagnostic.h"
+#include "context.h"
int plugin_is_GPL_compatible;
@@ -309,7 +310,7 @@ plugin_init (struct plugin_name_args *plugin_info,
return 1;
/* Self-assign detection should happen after SSA is constructed. */
- pass_info.pass = &pass_warn_self_assign.pass;
+ pass_info.pass = make_pass_warn_self_assign (g);
pass_info.reference_pass_name = "ssa";
pass_info.ref_pass_instance_number = 1;
pass_info.pos_op = PASS_POS_INSERT_AFTER;
diff --git a/gcc/toplev.c b/gcc/toplev.c
index 9187529..53f53fd 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -76,6 +76,7 @@ along with GCC; see the file COPYING3. If not see
#include "plugin.h"
#include "diagnostic-color.h"
#include "context.h"
+#include "pass_manager.h"
#if defined(DBX_DEBUGGING_INFO) || defined(XCOFF_DEBUGGING_INFO)
#include "dbxout.h"
@@ -1818,7 +1819,7 @@ finalize (bool no_backend)
{
statistics_fini ();
- finish_optimization_passes ();
+ g->get_passes ()->finish_optimization_passes ();
ira_finish_once ();
}
diff --git a/gcc/toplev.h b/gcc/toplev.h
index fff452c..84ffdb0 100644
--- a/gcc/toplev.h
+++ b/gcc/toplev.h
@@ -28,7 +28,6 @@ extern int toplev_main (int, char **);
extern void rest_of_decl_compilation (tree, int, int);
extern void rest_of_type_compilation (tree, int);
extern void init_optimization_passes (void);
-extern void finish_optimization_passes (void);
extern bool enable_rtl_dump_file (void);
/* In except.c. Initialize exception handling. This is used by the Ada
diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
index 16442ed..41f7d17 100644
--- a/gcc/tree-pass.h
+++ b/gcc/tree-pass.h
@@ -34,9 +34,8 @@ enum opt_pass_type
IPA_PASS
};
-/* Describe one pass; this is the common part shared across different pass
- types. */
-struct opt_pass
+/* Metadata for a pass, non-varying across all instances of a pass. */
+struct pass_data
{
/* Optimization pass type. */
enum opt_pass_type type;
@@ -48,23 +47,13 @@ struct opt_pass
/* The -fopt-info optimization group flags as defined in dumpfile.h. */
unsigned int optinfo_flags;
- /* If non-null, this pass and all sub-passes are executed only if
- the function returns true. */
- bool (*gate) (void);
+ /* If true, this pass has its own implementation of the opt_pass::gate
+ method. */
+ bool has_gate;
- /* This is the code to run. If null, then there should be sub-passes
- otherwise this pass does nothing. The return value contains
- TODOs to execute in addition to those in TODO_flags_finish. */
- unsigned int (*execute) (void);
-
- /* A list of sub-passes to run, dependent on gate predicate. */
- struct opt_pass *sub;
-
- /* Next in the list of passes to run, independent of gate predicate. */
- struct opt_pass *next;
-
- /* Static pass number, used as a fragment of the dump file name. */
- int static_pass_number;
+ /* If true, this pass has its own implementation of the opt_pass::execute
+ method. */
+ bool has_execute;
/* The timevar id associated with this pass. */
/* ??? Ideally would be dynamically assigned. */
@@ -80,16 +69,72 @@ struct opt_pass
unsigned int todo_flags_finish;
};
+namespace gcc
+{
+ class context;
+} // namespace gcc
+
+/* An instance of a pass. This is also "pass_data" to minimize the
+ changes in existing code. */
+class opt_pass : public pass_data
+{
+public:
+ virtual ~opt_pass () { }
+
+ /* Create a copy of this pass.
+
+ Passes that can have multiple instances must provide their own
+ implementation of this, to ensure that any sharing of state between
+ this instance and the copy is "wired up" correctly.
+
+ The default implementation prints an error message and aborts. */
+ virtual opt_pass *clone ();
+
+ /* If has_gate is set, this pass and all sub-passes are executed only if
+ the function returns true. */
+ virtual bool gate ();
+
+ /* This is the code to run. If has_execute is false, then there should
+ be sub-passes otherwise this pass does nothing.
+ The return value contains TODOs to execute in addition to those in
+ TODO_flags_finish. */
+ virtual unsigned int execute ();
+
+protected:
+ opt_pass(const pass_data&, gcc::context *);
+
+public:
+ /* A list of sub-passes to run, dependent on gate predicate. */
+ struct opt_pass *sub;
+
+ /* Next in the list of passes to run, independent of gate predicate. */
+ struct opt_pass *next;
+
+ /* Static pass number, used as a fragment of the dump file name. */
+ int static_pass_number;
+
+protected:
+ gcc::context *ctxt_;
+};
+
/* Description of GIMPLE pass. */
-struct gimple_opt_pass
+class gimple_opt_pass : public opt_pass
{
- struct opt_pass pass;
+protected:
+ gimple_opt_pass(const pass_data& data, gcc::context *ctxt)
+ : opt_pass(data, ctxt)
+ {
+ }
};
/* Description of RTL pass. */
-struct rtl_opt_pass
+class rtl_opt_pass : public opt_pass
{
- struct opt_pass pass;
+protected:
+ rtl_opt_pass(const pass_data& data, gcc::context *ctxt)
+ : opt_pass(data, ctxt)
+ {
+ }
};
struct varpool_node;
@@ -98,10 +143,9 @@ struct lto_symtab_encoder_d;
/* Description of IPA pass with generate summary, write, execute, read and
transform stages. */
-struct ipa_opt_pass_d
+class ipa_opt_pass_d : public opt_pass
{
- struct opt_pass pass;
-
+public:
/* IPA passes can analyze function body and variable initializers
using this hook and produce summary. */
void (*generate_summary) (void);
@@ -127,13 +171,42 @@ struct ipa_opt_pass_d
unsigned int function_transform_todo_flags_start;
unsigned int (*function_transform) (struct cgraph_node *);
void (*variable_transform) (struct varpool_node *);
+
+protected:
+ ipa_opt_pass_d(const pass_data& data, gcc::context *ctxt,
+ void (*generate_summary) (void),
+ void (*write_summary) (void),
+ void (*read_summary) (void),
+ void (*write_optimization_summary) (void),
+ void (*read_optimization_summary) (void),
+ void (*stmt_fixup) (struct cgraph_node *, gimple *),
+ unsigned int function_transform_todo_flags_start,
+ unsigned int (*function_transform) (struct cgraph_node *),
+ void (*variable_transform) (struct varpool_node *))
+ : opt_pass(data, ctxt),
+ generate_summary(generate_summary),
+ write_summary(write_summary),
+ read_summary(read_summary),
+ write_optimization_summary(write_optimization_summary),
+ read_optimization_summary(read_optimization_summary),
+ stmt_fixup(stmt_fixup),
+ function_transform_todo_flags_start(
+ function_transform_todo_flags_start),
+ function_transform(function_transform),
+ variable_transform(variable_transform)
+ {
+ }
};
/* Description of simple IPA pass. Simple IPA passes have just one execute
hook. */
-struct simple_ipa_opt_pass
+class simple_ipa_opt_pass : public opt_pass
{
- struct opt_pass pass;
+protected:
+ simple_ipa_opt_pass(const pass_data& data, gcc::context *ctxt)
+ : opt_pass(data, ctxt)
+ {
+ }
};
/* Pass properties. */