aboutsummaryrefslogtreecommitdiff
path: root/gcc/passes.c
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/passes.c
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/passes.c')
-rw-r--r--gcc/passes.c102
1 files changed, 81 insertions, 21 deletions
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;