OSDN Git Service

* tree-pass.h (register_pass_info): New structure.
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 28 Sep 2009 23:15:35 +0000 (23:15 +0000)
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 28 Sep 2009 23:15:35 +0000 (23:15 +0000)
(pass_positioning_ops): Move enum from gcc-plugin.h.
(register_pass): New function.
* gcc-plugin.h (plugin_pass): Delete structure.
(pass_positioning_ops): Delete enum.
* plugin.c (regsiter_pass): Delete function.
(position_pass): Delete function.
(added_pass_nodes): Delete variable.
(prev_added_pass_nodes): Delete variable.
(pass_list_node): Delete structure.
* passes.c (make_pass_instance): New function.
(next_pass_1): Change to call make_pass_instance.
(pass_list_node): Move structure from gcc-plugin.h.
(added_pass_nodes): Move variable from plugin.c.
(prev_added_pass_nodes): Move variable from plugin.c.
(position_pass): New function.
(register_pass): New function.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@152257 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/gcc-plugin.h
gcc/passes.c
gcc/plugin.c
gcc/tree-pass.h

index 38ac22c..9826735 100644 (file)
@@ -1,3 +1,23 @@
+2009-09-28  Sriraman Tallam  <tmsriram@google.com>
+
+       * tree-pass.h (register_pass_info): New structure.      
+       (pass_positioning_ops): Move enum from gcc-plugin.h.
+       (register_pass): New function.
+       * gcc-plugin.h (plugin_pass): Delete structure.
+       (pass_positioning_ops): Delete enum.
+       * plugin.c (regsiter_pass): Delete function.
+       (position_pass): Delete function.
+       (added_pass_nodes): Delete variable.
+       (prev_added_pass_nodes): Delete variable.
+       (pass_list_node): Delete structure.
+       * passes.c (make_pass_instance): New function.
+       (next_pass_1): Change to call make_pass_instance.
+       (pass_list_node): Move structure from gcc-plugin.h.
+       (added_pass_nodes): Move variable from plugin.c.
+       (prev_added_pass_nodes): Move variable from plugin.c.
+       (position_pass): New function.
+       (register_pass): New function.
+
 2009-09-28  Easwaran Raman  <eraman@google.com>
 
        * ifcvt.c (noce_try_abs): Recognize pattern and call
index 84f0aed..1792c03 100644 (file)
@@ -55,24 +55,6 @@ struct plugin_argument
   char *value;  /* value is optional and can be NULL.  */
 };
 
-enum pass_positioning_ops
-{
-  PASS_POS_INSERT_AFTER,  /* Insert after the reference pass.  */
-  PASS_POS_INSERT_BEFORE, /* Insert before the reference pass.  */
-  PASS_POS_REPLACE        /* Replace the reference pass.  */
-};
-
-struct plugin_pass
-{
-  struct opt_pass *pass;            /* New pass provided by the plugin.  */
-  const char *reference_pass_name;  /* Name of the reference pass for hooking
-                                       up the new pass.  */
-  int ref_pass_instance_number;     /* Insert the pass at the specified
-                                       instance number of the reference pass.
-                                       Do it for every instance if it is 0.  */
-  enum pass_positioning_ops pos_op; /* how to insert the new pass.  */
-};
-
 /* Additional information about the plugin. Used by --help and --version. */
 
 struct plugin_info
index bcc966c..5b91698 100644 (file)
@@ -437,11 +437,11 @@ register_dump_files (struct opt_pass *pass,int properties)
   register_dump_files_1 (pass, properties);
 }
 
-/* Add a pass to the pass list. Duplicate the pass if it's already
-   in the list.  */
+/* Look at the static_pass_number and duplicate the pass
+   if it is already added to a list. */
 
-static struct opt_pass **
-next_pass_1 (struct opt_pass **list, struct opt_pass *pass)
+static struct opt_pass *
+make_pass_instance (struct opt_pass *pass, bool track_duplicates)
 {
   /* A nonzero static_pass_number indicates that the
      pass is already in the list.  */
@@ -459,25 +459,193 @@ next_pass_1 (struct opt_pass **list, struct opt_pass *pass)
          and so it should rename the dump file.  The first instance will
          be -1, and be number of duplicates = -static_pass_number - 1.
          Subsequent instances will be > 0 and just the duplicate number.  */
-      if (pass->name)
+      if (pass->name || track_duplicates)
         {
           pass->static_pass_number -= 1;
           new_pass->static_pass_number = -pass->static_pass_number;
        }
-      
-      *list = new_pass;
+      return new_pass;
     }
   else
     {
       pass->todo_flags_start |= TODO_mark_first_instance;
       pass->static_pass_number = -1;
-      *list = pass;
-    }  
+    } 
+  return pass; 
+}
+
+/* Add a pass to the pass list. Duplicate the pass if it's already
+   in the list.  */
+
+static struct opt_pass **
+next_pass_1 (struct opt_pass **list, struct opt_pass *pass)
+{
+  *list = make_pass_instance (pass, false);
   
   return &(*list)->next;
-          
 }
 
+/* List node for an inserted pass instance. We need to keep track of all
+   the newly-added pass instances (with 'added_pass_nodes' defined below)
+   so that we can register their dump files after pass-positioning is finished.
+   Registering dumping files needs to be post-processed or the
+   static_pass_number of the opt_pass object would be modified and mess up
+   the dump file names of future pass instances to be added.  */
+
+struct pass_list_node
+{
+  struct opt_pass *pass;
+  struct pass_list_node *next;
+};
+
+static struct pass_list_node *added_pass_nodes = NULL;
+static struct pass_list_node *prev_added_pass_node;
+
+/* Insert the pass at the proper position. Return true if the pass 
+   is successfully added.
+
+   NEW_PASS_INFO - new pass to be inserted
+   PASS_LIST - root of the pass list to insert the new pass to  */
+
+static bool
+position_pass (struct register_pass_info *new_pass_info,
+               struct opt_pass **pass_list)
+{
+  struct opt_pass *pass = *pass_list, *prev_pass = NULL;
+  bool success = false;
+
+  for ( ; pass; prev_pass = pass, pass = pass->next)
+    {
+      /* Check if the current pass is of the same type as the new pass and
+         matches the name and the instance number of the reference pass.  */
+      if (pass->type == new_pass_info->pass->type
+          && pass->name
+          && !strcmp (pass->name, new_pass_info->reference_pass_name)
+          && ((new_pass_info->ref_pass_instance_number == 0)
+              || (new_pass_info->ref_pass_instance_number ==
+                  pass->static_pass_number)
+              || (new_pass_info->ref_pass_instance_number == 1
+                  && pass->todo_flags_start & TODO_mark_first_instance)))
+        {
+          struct opt_pass *new_pass;
+          struct pass_list_node *new_pass_node;
+
+         new_pass = make_pass_instance (new_pass_info->pass, true);
+  
+          /* Insert the new pass instance based on the positioning op.  */
+          switch (new_pass_info->pos_op)
+            {
+              case PASS_POS_INSERT_AFTER:
+                new_pass->next = pass->next;
+                pass->next = new_pass;
+
+               /* Skip newly inserted pass to avoid repeated
+                  insertions in the case where the new pass and the
+                  existing one have the same name.  */
+                pass = new_pass; 
+                break;
+              case PASS_POS_INSERT_BEFORE:
+                new_pass->next = pass;
+                if (prev_pass)
+                  prev_pass->next = new_pass;
+                else
+                  *pass_list = new_pass;
+                break;
+              case PASS_POS_REPLACE:
+                new_pass->next = pass->next;
+                if (prev_pass)
+                  prev_pass->next = new_pass;
+                else
+                  *pass_list = new_pass;
+                new_pass->sub = pass->sub;
+                new_pass->tv_id = pass->tv_id;
+                pass = new_pass;
+                break;
+              default:
+                error ("Invalid pass positioning operation");
+                return false;
+            }
+
+          /* Save the newly added pass (instance) in the added_pass_nodes
+             list so that we can register its dump file later. Note that
+             we cannot register the dump file now because doing so will modify
+             the static_pass_number of the opt_pass object and therefore
+             mess up the dump file name of future instances.  */
+          new_pass_node = XCNEW (struct pass_list_node);
+          new_pass_node->pass = new_pass;
+          if (!added_pass_nodes)
+            added_pass_nodes = new_pass_node;
+          else
+            prev_added_pass_node->next = new_pass_node;
+          prev_added_pass_node = new_pass_node;
+
+          success = true;
+        }
+
+      if (pass->sub && position_pass (new_pass_info, &pass->sub))
+        success = true;
+    }
+
+  return success;
+}
+
+/* Hooks a new pass into the pass lists.
+
+   PASS_INFO   - pass information that specifies the opt_pass object,
+                 reference pass, instance number, and how to position
+                 the pass  */
+
+void
+register_pass (struct register_pass_info *pass_info)
+{
+  if (!pass_info->pass)
+    {
+      gcc_unreachable ();
+    } 
+
+  if (!pass_info->reference_pass_name)
+    {
+      gcc_unreachable ();
+    }
+
+  /* Try to insert the new pass to the pass lists. We need to check all
+     three lists as the reference pass could be in one (or all) of them.  */
+  if (!position_pass (pass_info, &all_lowering_passes)
+      && !position_pass (pass_info, &all_ipa_passes)
+      && !position_pass (pass_info, &all_passes))
+    gcc_unreachable ();
+  else
+    {
+      /* OK, we have successfully inserted the new pass. We need to register
+         the dump files for the newly added pass and its duplicates (if any).
+         Because the registration of plugin/backend passes happens after the
+         command-line options are parsed, the options that specify single
+         pass dumping (e.g. -fdump-tree-PASSNAME) cannot be used for new
+         passes. Therefore we currently can only enable dumping of
+         new passes when the 'dump-all' flags (e.g. -fdump-tree-all)
+         are specified. While doing so, we also delete the pass_list_node
+         objects created during pass positioning.  */
+      while (added_pass_nodes)
+        {
+          struct pass_list_node *next_node = added_pass_nodes->next;
+          enum tree_dump_index tdi;
+          register_one_dump_file (added_pass_nodes->pass);
+          if (added_pass_nodes->pass->type == SIMPLE_IPA_PASS
+              || added_pass_nodes->pass->type == IPA_PASS)
+            tdi = TDI_ipa_all;
+          else if (added_pass_nodes->pass->type == GIMPLE_PASS)
+            tdi = TDI_tree_all;
+          else
+            tdi = TDI_rtl_all;
+          /* Check if dump-all flag is specified.  */
+          if (get_dump_file_info (tdi)->state)
+            get_dump_file_info (added_pass_nodes->pass->static_pass_number)
+                ->state = get_dump_file_info (tdi)->state;
+          XDELETE (added_pass_nodes);
+          added_pass_nodes = next_node;
+        }
+    }
+}
 
 /* Construct the pass tree.  The sequencing of passes is driven by
    the cgraph routines:
index 7d6e85f..414d578 100644 (file)
@@ -78,20 +78,6 @@ struct callback_info
 /* An array of lists of 'callback_info' objects indexed by the event id.  */
 static struct callback_info *plugin_callbacks[PLUGIN_EVENT_LAST] = { NULL };
 
-/* List node for an inserted pass instance. We need to keep track of all
-   the newly-added pass instances (with 'added_pass_nodes' defined below)
-   so that we can register their dump files after pass-positioning is finished.
-   Registering dumping files needs to be post-processed or the
-   static_pass_number of the opt_pass object would be modified and mess up
-   the dump file names of future pass instances to be added.  */
-struct pass_list_node
-{
-  struct opt_pass *pass;
-  struct pass_list_node *next;
-};
-
-static struct pass_list_node *added_pass_nodes = NULL;
-static struct pass_list_node *prev_added_pass_node;
 
 #ifdef ENABLE_PLUGIN
 /* Each plugin should define an initialization function with exactly
@@ -287,179 +273,6 @@ parse_plugin_arg_opt (const char *arg)
   XDELETEVEC (name);
 }
 
-
-/* Insert the plugin pass at the proper position. Return true if the pass 
-   is successfully added.
-
-   PLUGIN_PASS_INFO - new pass to be inserted
-   PASS_LIST        - root of the pass list to insert the new pass to  */
-
-static bool
-position_pass (struct plugin_pass *plugin_pass_info,
-               struct opt_pass **pass_list)
-{
-  struct opt_pass *pass = *pass_list, *prev_pass = NULL;
-  bool success = false;
-
-  for ( ; pass; prev_pass = pass, pass = pass->next)
-    {
-      /* Check if the current pass is of the same type as the new pass and
-         matches the name and the instance number of the reference pass.  */
-      if (pass->type == plugin_pass_info->pass->type
-          && pass->name
-          && !strcmp (pass->name, plugin_pass_info->reference_pass_name)
-          && ((plugin_pass_info->ref_pass_instance_number == 0)
-              || (plugin_pass_info->ref_pass_instance_number ==
-                  pass->static_pass_number)
-              || (plugin_pass_info->ref_pass_instance_number == 1
-                  && pass->todo_flags_start & TODO_mark_first_instance)))
-        {
-          struct opt_pass *new_pass = plugin_pass_info->pass;
-          struct pass_list_node *new_pass_node;
-
-          /* The following code (if-statement) is adopted from next_pass_1.  */
-          if (new_pass->static_pass_number)
-            {
-              new_pass = XNEW (struct opt_pass);
-              memcpy (new_pass, plugin_pass_info->pass, sizeof (*new_pass));
-              new_pass->next = NULL;
-
-              new_pass->todo_flags_start &= ~TODO_mark_first_instance;
-
-              plugin_pass_info->pass->static_pass_number -= 1;
-              new_pass->static_pass_number =
-                  -plugin_pass_info->pass->static_pass_number;
-            }
-          else
-            {
-              new_pass->todo_flags_start |= TODO_mark_first_instance;
-              new_pass->static_pass_number = -1;
-            }
-
-          /* Insert the new pass instance based on the positioning op.  */
-          switch (plugin_pass_info->pos_op)
-            {
-              case PASS_POS_INSERT_AFTER:
-                new_pass->next = pass->next;
-                pass->next = new_pass;
-
-               /* Skip newly inserted pass to avoid repeated
-                  insertions in the case where the new pass and the
-                  existing one have the same name.  */
-                pass = new_pass; 
-                break;
-              case PASS_POS_INSERT_BEFORE:
-                new_pass->next = pass;
-                if (prev_pass)
-                  prev_pass->next = new_pass;
-                else
-                  *pass_list = new_pass;
-                break;
-              case PASS_POS_REPLACE:
-                new_pass->next = pass->next;
-                if (prev_pass)
-                  prev_pass->next = new_pass;
-                else
-                  *pass_list = new_pass;
-                new_pass->sub = pass->sub;
-                new_pass->tv_id = pass->tv_id;
-                pass = new_pass;
-                break;
-              default:
-                error ("Invalid pass positioning operation");
-                return false;
-            }
-
-          /* Save the newly added pass (instance) in the added_pass_nodes
-             list so that we can register its dump file later. Note that
-             we cannot register the dump file now because doing so will modify
-             the static_pass_number of the opt_pass object and therefore
-             mess up the dump file name of future instances.  */
-          new_pass_node = XCNEW (struct pass_list_node);
-          new_pass_node->pass = new_pass;
-          if (!added_pass_nodes)
-            added_pass_nodes = new_pass_node;
-          else
-            prev_added_pass_node->next = new_pass_node;
-          prev_added_pass_node = new_pass_node;
-
-          success = true;
-        }
-
-      if (pass->sub && position_pass (plugin_pass_info, &pass->sub))
-        success = true;
-    }
-
-  return success;
-}
-
-
-/* Hook into the pass lists (trees) a new pass registered by a plugin.
-
-   PLUGIN_NAME - display name for the plugin
-   PASS_INFO   - plugin pass information that specifies the opt_pass object,
-                 reference pass, instance number, and how to position
-                 the pass  */
-
-static void
-register_pass (const char *plugin_name, struct plugin_pass *pass_info)
-{
-  if (!pass_info->pass)
-    {
-      error ("No pass specified when registering a new pass in plugin %s",
-             plugin_name);
-      return;
-    }
-
-  if (!pass_info->reference_pass_name)
-    {
-      error ("No reference pass specified for positioning the pass "
-             " from plugin %s", plugin_name);
-      return;
-    }
-
-  /* Try to insert the new pass to the pass lists. We need to check all
-     three lists as the reference pass could be in one (or all) of them.  */
-  if (!position_pass (pass_info, &all_lowering_passes)
-      && !position_pass (pass_info, &all_ipa_passes)
-      && !position_pass (pass_info, &all_passes))
-    error ("Failed to position pass %s registered by plugin %s. "
-           "Cannot find the (specified instance of) reference pass %s",
-           pass_info->pass->name, plugin_name, pass_info->reference_pass_name);
-  else
-    {
-      /* OK, we have successfully inserted the new pass. We need to register
-         the dump files for the newly added pass and its duplicates (if any).
-         Because the registration of plugin passes happens after the
-         command-line options are parsed, the options that specify single
-         pass dumping (e.g. -fdump-tree-PASSNAME) cannot be used for new
-         plugin passes. Therefore we currently can only enable dumping of
-         new plugin passes when the 'dump-all' flags (e.g. -fdump-tree-all)
-         are specified. While doing so, we also delete the pass_list_node
-         objects created during pass positioning.  */
-      while (added_pass_nodes)
-        {
-          struct pass_list_node *next_node = added_pass_nodes->next;
-          enum tree_dump_index tdi;
-          register_one_dump_file (added_pass_nodes->pass);
-          if (added_pass_nodes->pass->type == SIMPLE_IPA_PASS
-              || added_pass_nodes->pass->type == IPA_PASS)
-            tdi = TDI_ipa_all;
-          else if (added_pass_nodes->pass->type == GIMPLE_PASS)
-            tdi = TDI_tree_all;
-          else
-            tdi = TDI_rtl_all;
-          /* Check if dump-all flag is specified.  */
-          if (get_dump_file_info (tdi)->state)
-            get_dump_file_info (added_pass_nodes->pass->static_pass_number)
-                ->state = get_dump_file_info (tdi)->state;
-          XDELETE (added_pass_nodes);
-          added_pass_nodes = next_node;
-        }
-    }
-}
-
-
 /* Register additional plugin information. NAME is the name passed to
    plugin_init. INFO is the information that should be registered. */
 
@@ -490,7 +303,7 @@ register_callback (const char *plugin_name,
     {
       case PLUGIN_PASS_MANAGER_SETUP:
        gcc_assert (!callback);
-        register_pass (plugin_name, (struct plugin_pass *) user_data);
+        register_pass ((struct register_pass_info *) user_data);
         break;
       case PLUGIN_INFO:
        gcc_assert (!callback);
index 97f1d34..3241ee1 100644 (file)
@@ -308,6 +308,27 @@ struct dump_file_info
 #define TODO_verify_all \
   (TODO_verify_ssa | TODO_verify_flow | TODO_verify_stmts)
 
+
+/* Register pass info. */
+
+enum pass_positioning_ops
+{
+  PASS_POS_INSERT_AFTER,  /* Insert after the reference pass.  */
+  PASS_POS_INSERT_BEFORE, /* Insert before the reference pass.  */
+  PASS_POS_REPLACE        /* Replace the reference pass.  */
+};
+
+struct register_pass_info
+{
+  struct opt_pass *pass;            /* New pass to register.  */
+  const char *reference_pass_name;  /* Name of the reference pass for hooking
+                                       up the new pass.  */
+  int ref_pass_instance_number;     /* Insert the pass at the specified
+                                       instance number of the reference pass.
+                                       Do it for every instance if it is 0.  */
+  enum pass_positioning_ops pos_op; /* how to insert the new pass.  */
+};
+
 extern void tree_lowering_passes (tree decl);
 
 extern struct gimple_opt_pass pass_mudflap_1;
@@ -545,6 +566,7 @@ extern void print_current_pass (FILE *);
 extern void debug_pass (void);
 extern void register_one_dump_file (struct opt_pass *);
 extern bool function_called_by_processed_nodes_p (void);
+extern void register_pass (struct register_pass_info *);
 
 /* Set to true if the pass is called the first time during compilation of the
    current function.  Note that using this information in the optimization