diff options
author | Sriraman Tallam <tmsriram@google.com> | 2009-09-28 23:15:35 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2009-09-28 23:15:35 +0000 |
commit | b80b0fd9c7f6206708bc423d131b0365a7296736 (patch) | |
tree | 35f1885df6f021b7379543790ddaa2f2def2a72f /gcc | |
parent | ef6ed66d16e433f5d77e8eda02768a691a42bfd7 (diff) | |
download | gcc-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/ChangeLog | 20 | ||||
-rw-r--r-- | gcc/gcc-plugin.h | 18 | ||||
-rw-r--r-- | gcc/passes.c | 188 | ||||
-rw-r--r-- | gcc/plugin.c | 189 | ||||
-rw-r--r-- | gcc/tree-pass.h | 22 |
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 |