Handwritten part of conversion of passes to C++ classes
authorDavid Malcolm <dmalcolm@redhat.com>
Mon, 5 Aug 2013 20:01:43 +0000 (20:01 +0000)
committerDavid Malcolm <dmalcolm@gcc.gnu.org>
Mon, 5 Aug 2013 20:01:43 +0000 (20:01 +0000)
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

16 files changed:
gcc/ChangeLog
gcc/Makefile.in
gcc/cgraphunit.c
gcc/config/i386/i386.c
gcc/config/i386/t-i386
gcc/lto-cgraph.c
gcc/pass_manager.h
gcc/passes.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/plugin/dumb_plugin.c
gcc/testsuite/g++.dg/plugin/selfassign.c
gcc/testsuite/gcc.dg/plugin/one_time_plugin.c
gcc/testsuite/gcc.dg/plugin/selfassign.c
gcc/toplev.c
gcc/toplev.h
gcc/tree-pass.h

index eece522af1a229e6da0f7308cd41764a36897884..ffa880bac65be067ef173815d117acadbafd68d7 100644 (file)
@@ -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
index 40ad19da085feb579356dfcb6388bfa7b38e3f27..afce540eed9fc9a47c79aa6dc547568ed40286b7 100644 (file)
@@ -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
 
 #\f
 # 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)
 
index e308b5248504036562e6c6d1fa916af4c77a2e6d..ad91117d6b1c7f56ada64c4e8d99a24ee0587abb 100644 (file)
@@ -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);
index df79eac71e4edca7483a4bbf571024a4ec01ba9f..cce3c9c80e850d440079360f791e24d30bdcbba8 100644 (file)
@@ -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
       };
 
index 3a77e14f5cab1707f8e991267d9967ca82f1856e..f10d570c8676231d49fcd91cabfd6f295a59f288 100644 (file)
@@ -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 \
index c3c393f6ec91c39d20cc4232a00cb6ed1190a62c..0dde03a7b78bf74848018d34211ebb6c12e5264c 100644 (file)
@@ -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)
     {
index f66cd80408f2f583aa7425451864031ece0f5c5d..ea078a5eb66d612ff0f4146978f3c319c287f6b5 100644 (file)
@@ -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
index a43a58809af38fc35ca641197b7b6509a8aee037..fcbd630dd8811023deb23707c8bb8d53ebe3864b 100644 (file)
@@ -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)
 \f
 
 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;
 
index f356d55c9901286efeeb9ba99f22706301876ab1..387006e2e3d7a3d78f6c9030c71fa9ed405dd7f0 100644 (file)
@@ -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
index 0f15140068c6e245c90b3596b2fd4dc2bfc18084..ab69c14294e24a682089011a8591398071b94428 100644 (file)
@@ -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;
index 37a0a979cb7cfc45ac4c7ad9d1f82f8476d6413b..3e0b38ec3413cf8d20085965f6cec2deaee3ed6a 100644 (file)
@@ -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;
index 45e6257c070ba808e71c25950a9d948c5926c582..31dfe69b1fbe9b915522a2fab7a3f90cfa3144a0 100644 (file)
@@ -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;
index 37a0a979cb7cfc45ac4c7ad9d1f82f8476d6413b..3e0b38ec3413cf8d20085965f6cec2deaee3ed6a 100644 (file)
@@ -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;
index 9187529119dd012916ad3d6a6e0d564bba93899a..53f53fd95df93352a725eca6be4936455d67aba9 100644 (file)
@@ -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 ();
     }
index fff452c8ba6a5600b3906595792eeff72f3f20d1..84ffdb0e28b5ad243b8d03616ef3a8e91f46846f 100644 (file)
@@ -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
index 16442ed4ed210cf7f19fb41bad2ee091b0a2a4a8..41f7d176c40ee60a981e392ea7a85ff034615cda 100644 (file)
@@ -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.  */