aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorSriraman Tallam <tmsriram@google.com>2009-09-28 23:15:35 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2009-09-28 23:15:35 +0000
commitb80b0fd9c7f6206708bc423d131b0365a7296736 (patch)
tree35f1885df6f021b7379543790ddaa2f2def2a72f /gcc
parentef6ed66d16e433f5d77e8eda02768a691a42bfd7 (diff)
downloadgcc-b80b0fd9c7f6206708bc423d131b0365a7296736.zip
gcc-b80b0fd9c7f6206708bc423d131b0365a7296736.tar.gz
gcc-b80b0fd9c7f6206708bc423d131b0365a7296736.tar.bz2
tree-pass.h (register_pass_info): New structure.
* 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. From-SVN: r152257
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog20
-rw-r--r--gcc/gcc-plugin.h18
-rw-r--r--gcc/passes.c188
-rw-r--r--gcc/plugin.c189
-rw-r--r--gcc/tree-pass.h22
5 files changed, 221 insertions, 216 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 38ac22c..9826735 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/gcc-plugin.h b/gcc/gcc-plugin.h
index 84f0aed..1792c03 100644
--- a/gcc/gcc-plugin.h
+++ b/gcc/gcc-plugin.h
@@ -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
diff --git a/gcc/passes.c b/gcc/passes.c
index bcc966c..5b91698 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -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:
diff --git a/gcc/plugin.c b/gcc/plugin.c
index 7d6e85f..414d578 100644
--- a/gcc/plugin.c
+++ b/gcc/plugin.c
@@ -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);
diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
index 97f1d340..3241ee1 100644
--- a/gcc/tree-pass.h
+++ b/gcc/tree-pass.h
@@ -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