From 44f01098dab113e97b492caa0643f2bad3d9b90a Mon Sep 17 00:00:00 2001 From: amylaar Date: Fri, 20 Nov 2009 12:29:36 +0000 Subject: [PATCH] Move get_current_pass_name to ici.c . Consolidate plugin event name definitions to plugin.def . Change PLUGIN_ALL_IPA_PASSES_EXECUTION, PLUGIN_ALL_PASSES_EXECUTION, PLUGIN_AVOID_GATE and PLUGIN_PASS_EXECUTION to use simple argument passing. Make static events treated equally in register_callback / invoke_plugin_callbacks, and mark end of static plugin events with PLUGIN_EVENT_FIRST_DYNAMIC. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/ici-20091108-branch@154362 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/Makefile.in | 3 +- gcc/cgraphunit.c | 11 ++---- gcc/gcc-plugin.h | 39 +++----------------- gcc/ici/events.c | 47 ++++++++++++++++++++++-- gcc/ici/ici.c | 10 +++++ gcc/passes.c | 27 +++----------- gcc/plugin.c | 73 +++++++++++++++++++------------------ gcc/plugin.def | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++ gcc/tree-optimize.c | 9 ++--- 9 files changed, 215 insertions(+), 107 deletions(-) create mode 100644 gcc/plugin.def diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 68a8fd7f344..257b60d39de 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -2720,7 +2720,8 @@ pass-manager.o : ici/pass-manager.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ ici/feature-internal.h ici/pass-manager.h events.o : ici/events.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(HASHTAB_H) \ - $(TOPLEV_H) errors.h $(GCC_PLUGIN_H) ici/highlev-plugin-internal.h + $(TOPLEV_H) errors.h $(GCC_PLUGIN_H) ici/highlev-plugin-internal.h \ + $(TREE_PASS_H) feature.o : ici/feature.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(HASHTAB_H) \ $(TOPLEV_H) ici/feature-internal.h diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index fa8893ee93d..493ceb7e626 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -1354,7 +1354,7 @@ cgraph_preserve_function_body_p (tree decl) static void ipa_passes (void) { - static int ici_ipa_passes_substitute_status; + int substitute_status = 0; set_cfun (NULL); current_function_decl = NULL; @@ -1362,12 +1362,9 @@ ipa_passes (void) bitmap_obstack_initialize (NULL); invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_START, NULL); - if ((invoke_plugin_va_callbacks - (PLUGIN_ALL_IPA_PASSES_EXECUTION, - "substitute_status", EP_SILENT, &ici_ipa_passes_substitute_status, - NULL) - != PLUGEVT_SUCCESS) - || ici_ipa_passes_substitute_status == 0) + + invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_EXECUTION, &substitute_status); + if (substitute_status == 0) { if (!in_lto_p) execute_ipa_pass_list (all_small_ipa_passes); diff --git a/gcc/gcc-plugin.h b/gcc/gcc-plugin.h index 4cedd225436..da5eb725662 100644 --- a/gcc/gcc-plugin.h +++ b/gcc/gcc-plugin.h @@ -28,42 +28,13 @@ along with GCC; see the file COPYING3. If not see #include "system.h" #include "highlev-plugin-common.h" -/* Event names. Keep in sync with plugin_event_name[]. */ +/* Event names. */ enum plugin_event { - PLUGIN_PASS_MANAGER_SETUP, /* To hook into pass manager. */ - PLUGIN_FINISH_TYPE, /* After finishing parsing a type. */ - PLUGIN_FINISH_UNIT, /* Useful for summary processing. */ - PLUGIN_CXX_CP_PRE_GENERICIZE, /* Allows to see low level AST in C++ FE. */ - PLUGIN_FINISH, /* Called before GCC exits. */ - PLUGIN_INFO, /* Information about the plugin. */ - PLUGIN_GGC_START, /* Called at start of GCC Garbage Collection. */ - PLUGIN_GGC_MARKING, /* Extend the GGC marking. */ - PLUGIN_GGC_END, /* Called at end of GGC. */ - PLUGIN_REGISTER_GGC_ROOTS, /* Register an extra GGC root table. */ - PLUGIN_REGISTER_GGC_CACHES, /* Register an extra GGC cache table. */ - PLUGIN_ATTRIBUTES, /* Called during attribute registration. */ - PLUGIN_START_UNIT, /* Called before processing a translation unit. */ - PLUGIN_PRAGMAS, /* Called during pragma registration. */ - - /* The following events might be subject to change or deletion without - prior notice. High-level plugins should only use them by name. */ - PLUGIN_FIRST_EXPERIMENTAL, - PLUGIN_UNROLL_PARAMETER_HANDLER = PLUGIN_FIRST_EXPERIMENTAL, - PLUGIN_ALL_PASSES_START, - PLUGIN_ALL_PASSES_EXECUTION, - PLUGIN_ALL_PASSES_END, - PLUGIN_ALL_IPA_PASSES_START, - PLUGIN_ALL_IPA_PASSES_EXECUTION, - PLUGIN_ALL_IPA_PASSES_END, - PLUGIN_AVOID_GATE, - PLUGIN_PASS_EXECUTION, - PLUGIN_EARLY_GIMPLE_PASSES_START, - PLUGIN_EARLY_GIMPLE_PASSES_END, - PLUGIN_NEW_PASS, /* Called when a pass is first instantiated. */ - - PLUGIN_EVENT_LAST /* Dummy event used for indexing callback - array. */ +# define DEFEVENT(NAME) NAME, +# include "plugin.def" +# undef DEFEVENT + PLUGIN_EVENT_FIRST_DYNAMIC }; extern const char **plugin_event_name; diff --git a/gcc/ici/events.c b/gcc/ici/events.c index 7157c467f24..e2dd1cb2f03 100644 --- a/gcc/ici/events.c +++ b/gcc/ici/events.c @@ -28,14 +28,15 @@ along with GCC; see the file COPYING3. If not see #include "hashtab.h" #include "toplev.h" #include "gcc-plugin.h" +#include "tree-pass.h" #include "highlev-plugin-internal.h" /* Event structure. */ struct hl_plugin_event { - int event; /* Number of the event */ event_callback_t run; /* Callback function */ + const char *param_name; }; @@ -117,19 +118,57 @@ hash_param_callback (void *gcc_data, void *user_data) } } +static void +status_callback (void *gcc_data, void *user_data) +{ + struct hl_plugin_event *ev = (struct hl_plugin_event *) user_data; + + register_event_parameter (ev->param_name, gcc_data, EP_INT); + ev->run (); + unregister_event_parameter (ev->param_name); +} + +static void +pass_execution_callback (void *gcc_data, void *user_data) +{ + struct hl_plugin_event *ev = (struct hl_plugin_event *) user_data; + struct opt_pass *pass = (struct opt_pass *) gcc_data; + + register_event_parameter ("_pass_type", &(pass->type), EP_INT); + ev->run (); + unregister_event_parameter ("_pass_type"); +} + /* Register a new event into hash table. */ void register_plugin_event (const char *event_name, event_callback_t func) { + int event; struct hl_plugin_event *ev = XCNEW (struct hl_plugin_event); if (event_name == NULL) internal_error ("Event cannot be registered with NULL name string\n"); - ev->event = get_named_event_id (event_name, INSERT); + event = get_named_event_id (event_name, INSERT); ev->run = func; - register_callback ("ICI", ev->event, hash_param_callback, ev); - ici_refresh_internal_callbacks (ev->event); + switch (event) + { + case PLUGIN_ALL_IPA_PASSES_EXECUTION: + case PLUGIN_ALL_PASSES_EXECUTION: + ev->param_name = "substitute_status"; + register_callback ("ICI", event, status_callback, ev); + break; + case PLUGIN_AVOID_GATE: + ev->param_name = "gate_status"; + register_callback ("ICI", event, status_callback, ev); + break; + case PLUGIN_PASS_EXECUTION: + register_callback ("ICI", event, pass_execution_callback, ev); + break; + default: + register_callback ("ICI", event, hash_param_callback, ev); + } + ici_refresh_internal_callbacks (event); } diff --git a/gcc/ici/ici.c b/gcc/ici/ici.c index 8caa95d2def..26c67f66750 100644 --- a/gcc/ici/ici.c +++ b/gcc/ici/ici.c @@ -343,3 +343,13 @@ invoke_named_callbacks (const char *name, ...) va_end (va); return retval; } + +/* Return current pass name if known, and NULL otherwise */ +const char * +get_current_pass_name (void) +{ + if (current_pass) + return current_pass->name; /* can be NULL if name is not set */ + else + return NULL; +} diff --git a/gcc/passes.c b/gcc/passes.c index d5b613af66e..a379ebc1550 100644 --- a/gcc/passes.c +++ b/gcc/passes.c @@ -105,21 +105,10 @@ along with GCC; see the file COPYING3. If not see #endif /* This is used for debugging. It allows the current pass to printed - from anywhere in compilation. */ + from anywhere in compilation. + The variable current_pass is also used for statistics and plugins. */ struct opt_pass *current_pass; - -/* Return current pass name if known, and NULL otherwise */ -const char * -get_current_pass_name (void) -{ - if (current_pass) - return current_pass->name; /* can be NULL if name is not set */ - else - return NULL; -} - - /* Call from anywhere to find out what pass this is. Useful for printing out debugging information deep inside an service routine. */ @@ -1507,8 +1496,7 @@ execute_one_pass (struct opt_pass *pass) bool initializing_dump; unsigned int todo_after = 0; - /* ICI: FGG: Important to make gate_status static to pass reference to ICI */ - static bool gate_status; + bool gate_status; /* IPA passes are executed on whole program, so cfun should be NULL. Other passes need function context set. */ @@ -1524,8 +1512,7 @@ execute_one_pass (struct opt_pass *pass) gate_status = (pass->gate == NULL) ? true : pass->gate(); /* Override gate with plugin. */ - invoke_plugin_va_callbacks (PLUGIN_AVOID_GATE, - "gate_status", EP_INT, &gate_status, NULL); + invoke_plugin_callbacks (PLUGIN_AVOID_GATE, &gate_status); if (!gate_status) { current_pass = NULL; @@ -1533,10 +1520,8 @@ execute_one_pass (struct opt_pass *pass) } /* Pass execution event trigger: useful to identify passes being - executed. Pass name is accessible as a feature (it is a constant object - in GCC.) */ - invoke_plugin_va_callbacks (PLUGIN_PASS_EXECUTION, - "_pass_type", EP_INT, &(pass->type), NULL); + executed. */ + invoke_plugin_callbacks (PLUGIN_PASS_EXECUTION, pass); if (!quiet_flag && !cfun) fprintf (stderr, " <%s>", pass->name ? pass->name : ""); diff --git a/gcc/plugin.c b/gcc/plugin.c index 6a1207ce604..0e7ee7f232b 100644 --- a/gcc/plugin.c +++ b/gcc/plugin.c @@ -44,36 +44,15 @@ along with GCC; see the file COPYING3. If not see #include "plugin-version.h" #endif +#define GCC_PLUGIN_STRINGIFY0(X) #X +#define GCC_PLUGIN_STRINGIFY1(X) GCC_PLUGIN_STRINGIFY0 (X) + /* Event names as strings. Keep in sync with enum plugin_event. */ static const char *plugin_event_name_init[] = { - "PLUGIN_PASS_MANAGER_SETUP", - "PLUGIN_FINISH_TYPE", - "PLUGIN_FINISH_UNIT", - "PLUGIN_CXX_CP_PRE_GENERICIZE", - "PLUGIN_FINISH", - "PLUGIN_INFO", - "PLUGIN_GGC_START", - "PLUGIN_GGC_MARKING", - "PLUGIN_GGC_END", - "PLUGIN_REGISTER_GGC_ROOTS", - "PLUGIN_REGISTER_GGC_CACHES", - "PLUGIN_ATTRIBUTES", - "PLUGIN_START_UNIT", - "PLUGIN_PRAGMAS", - "PLUGIN_UNROLL_PARAMETER_HANDLER", - "PLUGIN_ALL_PASSES_START", - "PLUGIN_ALL_PASSES_EXECUTION", - "PLUGIN_ALL_PASSES_END", - "PLUGIN_ALL_IPA_PASSES_START", - "PLUGIN_ALL_IPA_PASSES_EXECUTION", - "PLUGIN_ALL_IPA_PASSES_END", - "PLUGIN_AVOID_GATE", - "PLUGIN_PASS_EXECUTION", - "PLUGIN_EARLY_GIMPLE_PASSES_START", - "PLUGIN_EARLY_GIMPLE_PASSES_END", - "PLUGIN_NEW_PASS", - "PLUGIN_EVENT_LAST", +# define DEFEVENT(NAME) GCC_PLUGIN_STRINGIFY1 (NAME), +# include "plugin.def" +# undef DEFEVENT }; const char **plugin_event_name = plugin_event_name_init; @@ -84,8 +63,8 @@ static htab_t event_tab; /* Keep track of the limit of allocated events and space ready for allocating events. */ -int event_last = PLUGIN_EVENT_LAST; -static int event_horizon = PLUGIN_EVENT_LAST; +int event_last = PLUGIN_EVENT_FIRST_DYNAMIC; +static int event_horizon = PLUGIN_EVENT_FIRST_DYNAMIC; /* Hash table for the plugin_name_args objects created during command-line parsing. */ @@ -101,7 +80,7 @@ struct callback_info }; /* An array of lists of 'callback_info' objects indexed by the event id. */ -static struct callback_info *plugin_callbacks_init[PLUGIN_EVENT_LAST]; +static struct callback_info *plugin_callbacks_init[PLUGIN_EVENT_FIRST_DYNAMIC]; static struct callback_info **plugin_callbacks = plugin_callbacks_init; @@ -333,7 +312,7 @@ get_named_event_id (const char *name, enum insert_option insert) int i; event_tab = htab_create (150, htab_hash_string, htab_event_eq, NULL); - for (i = 0; i < PLUGIN_EVENT_LAST; i++) + for (i = 0; i < PLUGIN_EVENT_FIRST_DYNAMIC; i++) { slot = htab_find_slot (event_tab, plugin_event_name[i], INSERT); gcc_assert (*slot == HTAB_EMPTY_ENTRY); @@ -407,9 +386,9 @@ register_callback (const char *plugin_name, gcc_assert (!callback); ggc_register_cache_tab ((const struct ggc_cache_tab*) user_data); break; - case PLUGIN_EVENT_LAST: + case PLUGIN_EVENT_FIRST_DYNAMIC: default: - if (event < PLUGIN_FIRST_EXPERIMENTAL || event >= event_last) + if (event < PLUGIN_EVENT_FIRST_DYNAMIC || event >= event_last) { error ("Unknown callback event registered by plugin %s", plugin_name); @@ -426,6 +405,18 @@ register_callback (const char *plugin_name, case PLUGIN_ATTRIBUTES: case PLUGIN_PRAGMAS: case PLUGIN_FINISH: + case PLUGIN_UNROLL_PARAMETER_HANDLER: + case PLUGIN_ALL_PASSES_START: + case PLUGIN_ALL_PASSES_EXECUTION: + case PLUGIN_ALL_PASSES_END: + case PLUGIN_ALL_IPA_PASSES_START: + case PLUGIN_ALL_IPA_PASSES_EXECUTION: + case PLUGIN_ALL_IPA_PASSES_END: + case PLUGIN_AVOID_GATE: + case PLUGIN_PASS_EXECUTION: + case PLUGIN_EARLY_GIMPLE_PASSES_START: + case PLUGIN_EARLY_GIMPLE_PASSES_END: + case PLUGIN_NEW_PASS: { struct callback_info *new_callback; if (!callback) @@ -477,9 +468,9 @@ invoke_plugin_callbacks (int event, void *gcc_data) switch (event) { - case PLUGIN_EVENT_LAST: + case PLUGIN_EVENT_FIRST_DYNAMIC: default: - gcc_assert (event >= PLUGIN_FIRST_EXPERIMENTAL); + gcc_assert (event >= PLUGIN_EVENT_FIRST_DYNAMIC); gcc_assert (event < event_last); /* Fall through. */ case PLUGIN_FINISH_TYPE: @@ -492,6 +483,18 @@ invoke_plugin_callbacks (int event, void *gcc_data) case PLUGIN_GGC_START: case PLUGIN_GGC_MARKING: case PLUGIN_GGC_END: + case PLUGIN_UNROLL_PARAMETER_HANDLER: + case PLUGIN_ALL_PASSES_START: + case PLUGIN_ALL_PASSES_EXECUTION: + case PLUGIN_ALL_PASSES_END: + case PLUGIN_ALL_IPA_PASSES_START: + case PLUGIN_ALL_IPA_PASSES_EXECUTION: + case PLUGIN_ALL_IPA_PASSES_END: + case PLUGIN_AVOID_GATE: + case PLUGIN_PASS_EXECUTION: + case PLUGIN_EARLY_GIMPLE_PASSES_START: + case PLUGIN_EARLY_GIMPLE_PASSES_END: + case PLUGIN_NEW_PASS: { /* Iterate over every callback registered with this event and call it. */ diff --git a/gcc/plugin.def b/gcc/plugin.def new file mode 100644 index 00000000000..551131947fc --- /dev/null +++ b/gcc/plugin.def @@ -0,0 +1,103 @@ +/* This file contains the definitions for plugin events in GCC. + Copyright (C) 2009 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + + +/* To hook into pass manager. */ +DEFEVENT (PLUGIN_PASS_MANAGER_SETUP) + +/* After finishing parsing a type. */ +DEFEVENT (PLUGIN_FINISH_TYPE) + +/* Useful for summary processing. */ +DEFEVENT (PLUGIN_FINISH_UNIT) + +/* Allows to see low level AST in C++ FE. */ +DEFEVENT (PLUGIN_CXX_CP_PRE_GENERICIZE) + +/* Called before GCC exits. */ +DEFEVENT (PLUGIN_FINISH) + +/* Information about the plugin. */ +DEFEVENT (PLUGIN_INFO) + +/* Called at start of GCC Garbage Collection. */ +DEFEVENT (PLUGIN_GGC_START) + +/* Extend the GGC marking. */ +DEFEVENT (PLUGIN_GGC_MARKING) + +/* Called at end of GGC. */ +DEFEVENT (PLUGIN_GGC_END) + +/* Register an extra GGC root table. */ +DEFEVENT (PLUGIN_REGISTER_GGC_ROOTS) + +/* Register an extra GGC cache table. */ +DEFEVENT (PLUGIN_REGISTER_GGC_CACHES) + +/* Called during attribute registration. */ +DEFEVENT (PLUGIN_ATTRIBUTES) + +/* Called before processing a translation unit. */ +DEFEVENT (PLUGIN_START_UNIT) + +/* Called during pragma registration. */ +DEFEVENT (PLUGIN_PRAGMAS) + +/* Called to allow inspection and/or modification of unroll parameters. */ +DEFEVENT (PLUGIN_UNROLL_PARAMETER_HANDLER) + +/* Called before first pass. */ +DEFEVENT (PLUGIN_ALL_PASSES_START) + +/* Allows pass execution to be substituted. */ +DEFEVENT (PLUGIN_ALL_PASSES_EXECUTION) + +/* Called after last pass. */ +DEFEVENT (PLUGIN_ALL_PASSES_END) + +/* Called before first ipa pass. */ +DEFEVENT (PLUGIN_ALL_IPA_PASSES_START) + +/* Allows ipa pass execution to be substituted. */ +DEFEVENT (PLUGIN_ALL_IPA_PASSES_EXECUTION) + +/* Called after last ipa pass. */ +DEFEVENT (PLUGIN_ALL_IPA_PASSES_END) + +/* Allows to override pass gate decision for current_pass. */ +DEFEVENT (PLUGIN_AVOID_GATE) + +/* Called before executing a pass. */ +DEFEVENT (PLUGIN_PASS_EXECUTION) + +/* Called before executing subpasses of a GIMPLE_PASS in + execute_ipa_pass_list. */ +DEFEVENT (PLUGIN_EARLY_GIMPLE_PASSES_START) + +/* Called after executing subpasses of a GIMPLE_PASS in + execute_ipa_pass_list. */ +DEFEVENT (PLUGIN_EARLY_GIMPLE_PASSES_END) + +/* Called when a pass is first instantiated. */ +DEFEVENT (PLUGIN_NEW_PASS) + +/* After the hard-coded events above, plugins can dynamically allocate events + at run time. + PLUGIN_EVENT_FIRST_DYNAMIC only appears as last enum element. */ diff --git a/gcc/tree-optimize.c b/gcc/tree-optimize.c index da59fdf7511..8742f3b0cc0 100644 --- a/gcc/tree-optimize.c +++ b/gcc/tree-optimize.c @@ -360,7 +360,7 @@ tree_rest_of_compilation (tree fndecl) { location_t saved_loc; struct cgraph_node *node; - static int ici_passes_substitute_status = 0; + int substitute_status; timevar_push (TV_EXPAND); @@ -397,10 +397,9 @@ tree_rest_of_compilation (tree fndecl) /* ICI Event: Substitution of pass manager. */ /* Try calling the event - if not successful, or if the plugin did not manipulate passes, fall back on the default pass ordering. */ - if (invoke_plugin_va_callbacks - (PLUGIN_ALL_PASSES_EXECUTION, - "substitute_status", EP_SILENT, &ici_passes_substitute_status, NULL) - != PLUGEVT_SUCCESS || ici_passes_substitute_status == 0) + substitute_status = 0; + invoke_plugin_callbacks (PLUGIN_ALL_PASSES_EXECUTION, &substitute_status); + if (substitute_status == 0) execute_pass_list (all_passes); /* Signal the end of passes. */ -- 2.11.4.GIT