cgraphunit.c (plugin.h): Include.
2009-12-01 Grigori Fursin <grigori.fursin@inria.fr> Joern Rennecke <amylaar@spamcop.net> * cgraphunit.c (plugin.h): Include. (ipa_passes): Invoke PLUGIN_ALL_IPA_PASSES_START / PLUGIN_ALL_IPA_PASSES_END at start / end of processing. * gcc-plugin.h (highlev-plugin-common.h, hashtab.h): Include. (enum plugin_event): Define by including plugin.def. Last enumerator is now called PLUGIN_EVENT_FIRST_DYNAMIC. (plugin_event_name): Change type to const char **. (get_event_last, get_named_event_id, unregister_callback): Declare. (register_callback): Change type of event argument to int. (highlev-plugin-common.h): New file. * Makefile.in (GCC_PLUGIN_H): Add highlev-plugin-common.h and $(HASHTAB_H) (tree-optimize.o passes.o): Depend on $(PLUGIN_H). (PLUGIN_HEADERS): Add opts.h, $(PARAMS_H) and plugin.def. (s-header-vars): New rule. (install-plugin): Depend on s-header-vars. Install b-header-vars. * params.c (get_num_compiler_params): New function. * params.h (get_num_compiler_params): Declare. * passes.c (plugin.h): Include. (make_pass_instance): Invoke PLUGIN_NEW_PASS. (do_per_function_toporder, pass_init_dump_file): No longer static. (pass_fini_dump_file): Likewise. (execute_one_pass): Likewise. Invoke PLUGIN_OVERRIDE_GATE and PLUGIN_PASS_EXECUTION. (execute_ipa_pass_list): Invoke PLUGIN_EARLY_GIMPLE_PASSES_START and PLUGIN_EARLY_GIMPLE_PASSES_END. * plugin.c (plugin_event_name_init): New array, defined by including plugin.def. (FMT_FOR_PLUGIN_EVENT): Update. (plugin_event_name): Change type to const char ** and initialize to plugin_event_name_init. (event_tab, event_last, event_horizon): New variable. (get_event_last): New function. (plugin_callbacks_init): New array. (plugin_callbacks: Change type to struct callback_info **. Initialize to plugin_callbacks_init. (htab_event_eq, get_named_event_id, unregister_callback): New function. (invoke_plugin_va_callbacks): Likewise. (register_callback): Change type of event argument to int. Handle new events. Allow dynamic events. (invoke_plugin_callbacks): Likewise. Return success status. (plugins_active_p): Allow dynamic callbacks. * plugin.def: New file. * plugin.h (invoke_plugin_callbacks): Update prototype. (invoke_plugin_va_callbacks): Declare. * tree-optimize.c (plugin.h): Include. (tree_rest_of_compilation): Invoke PLUGIN_ALL_PASSES_START and PLUGIN_ALL_PASSES_END. * tree-pass.h (execute_one_pass, pass_init_dump_file): Declare. (pass_fini_dump_file, do_per_function_toporder): Likewise. * doc/plugin.texi: Document new event types. Co-Authored-By: Joern Rennecke <amylaar@spamcop.net> From-SVN: r154877
This commit is contained in:
parent
d0d565e1b0
commit
090fa0ab61
|
@ -1,3 +1,58 @@
|
|||
2009-12-01 Grigori Fursin <grigori.fursin@inria.fr>
|
||||
Joern Rennecke <amylaar@spamcop.net>
|
||||
|
||||
* cgraphunit.c (plugin.h): Include.
|
||||
(ipa_passes): Invoke PLUGIN_ALL_IPA_PASSES_START /
|
||||
PLUGIN_ALL_IPA_PASSES_END at start / end of processing.
|
||||
* gcc-plugin.h (highlev-plugin-common.h, hashtab.h): Include.
|
||||
(enum plugin_event): Define by including plugin.def.
|
||||
Last enumerator is now called PLUGIN_EVENT_FIRST_DYNAMIC.
|
||||
(plugin_event_name): Change type to const char **.
|
||||
(get_event_last, get_named_event_id, unregister_callback): Declare.
|
||||
(register_callback): Change type of event argument to int.
|
||||
(highlev-plugin-common.h): New file.
|
||||
* Makefile.in (GCC_PLUGIN_H): Add highlev-plugin-common.h and
|
||||
$(HASHTAB_H)
|
||||
(tree-optimize.o passes.o): Depend on $(PLUGIN_H).
|
||||
(PLUGIN_HEADERS): Add opts.h, $(PARAMS_H) and plugin.def.
|
||||
(s-header-vars): New rule.
|
||||
(install-plugin): Depend on s-header-vars. Install b-header-vars.
|
||||
* params.c (get_num_compiler_params): New function.
|
||||
* params.h (get_num_compiler_params): Declare.
|
||||
* passes.c (plugin.h): Include.
|
||||
(make_pass_instance): Invoke PLUGIN_NEW_PASS.
|
||||
(do_per_function_toporder, pass_init_dump_file): No longer static.
|
||||
(pass_fini_dump_file): Likewise.
|
||||
(execute_one_pass): Likewise. Invoke PLUGIN_OVERRIDE_GATE and
|
||||
PLUGIN_PASS_EXECUTION.
|
||||
(execute_ipa_pass_list): Invoke PLUGIN_EARLY_GIMPLE_PASSES_START and
|
||||
PLUGIN_EARLY_GIMPLE_PASSES_END.
|
||||
* plugin.c (plugin_event_name_init): New array, defined by
|
||||
including plugin.def.
|
||||
(FMT_FOR_PLUGIN_EVENT): Update.
|
||||
(plugin_event_name): Change type to const char ** and initialize
|
||||
to plugin_event_name_init.
|
||||
(event_tab, event_last, event_horizon): New variable.
|
||||
(get_event_last): New function.
|
||||
(plugin_callbacks_init): New array.
|
||||
(plugin_callbacks: Change type to struct callback_info **.
|
||||
Initialize to plugin_callbacks_init.
|
||||
(htab_event_eq, get_named_event_id, unregister_callback): New function.
|
||||
(invoke_plugin_va_callbacks): Likewise.
|
||||
(register_callback): Change type of event argument to int.
|
||||
Handle new events. Allow dynamic events.
|
||||
(invoke_plugin_callbacks): Likewise. Return success status.
|
||||
(plugins_active_p): Allow dynamic callbacks.
|
||||
* plugin.def: New file.
|
||||
* plugin.h (invoke_plugin_callbacks): Update prototype.
|
||||
(invoke_plugin_va_callbacks): Declare.
|
||||
* tree-optimize.c (plugin.h): Include.
|
||||
(tree_rest_of_compilation): Invoke PLUGIN_ALL_PASSES_START and
|
||||
PLUGIN_ALL_PASSES_END.
|
||||
* tree-pass.h (execute_one_pass, pass_init_dump_file): Declare.
|
||||
(pass_fini_dump_file, do_per_function_toporder): Likewise.
|
||||
* doc/plugin.texi: Document new event types.
|
||||
|
||||
2009-12-01 Martin Jambor <mjambor@suse.cz>
|
||||
|
||||
PR tree-optimization/42237
|
||||
|
|
|
@ -943,7 +943,8 @@ TREE_VECTORIZER_H = tree-vectorizer.h $(TREE_DATA_REF_H)
|
|||
IPA_PROP_H = ipa-prop.h $(TREE_H) vec.h $(CGRAPH_H)
|
||||
GSTAB_H = gstab.h stab.def
|
||||
BITMAP_H = bitmap.h $(HASHTAB_H) statistics.h
|
||||
GCC_PLUGIN_H = gcc-plugin.h $(CONFIG_H) $(SYSTEM_H)
|
||||
GCC_PLUGIN_H = gcc-plugin.h highlev-plugin-common.h $(CONFIG_H) $(SYSTEM_H) \
|
||||
$(HASHTAB_H)
|
||||
PLUGIN_H = plugin.h $(GCC_PLUGIN_H)
|
||||
PLUGIN_VERSION_H = plugin-version.h configargs.h
|
||||
|
||||
|
@ -2503,8 +2504,9 @@ tree-ssa-reassoc.o : tree-ssa-reassoc.c $(TREE_FLOW_H) $(CONFIG_H) \
|
|||
langhooks.h alloc-pool.h pointer-set.h $(CFGLOOP_H)
|
||||
tree-optimize.o : tree-optimize.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
|
||||
$(RTL_H) $(TREE_H) $(TM_P_H) hard-reg-set.h $(EXPR_H) $(GGC_H) output.h \
|
||||
$(DIAGNOSTIC_H) $(BASIC_BLOCK_H) $(FLAGS_H) $(TIMEVAR_H) $(TM_H) coretypes.h \
|
||||
$(TREE_DUMP_H) $(TOPLEV_H) $(FUNCTION_H) langhooks.h $(FLAGS_H) $(CGRAPH_H) \
|
||||
$(DIAGNOSTIC_H) $(BASIC_BLOCK_H) $(FLAGS_H) $(TIMEVAR_H) $(TM_H) \
|
||||
coretypes.h $(TREE_DUMP_H) $(TOPLEV_H) $(FUNCTION_H) langhooks.h \
|
||||
$(FLAGS_H) $(CGRAPH_H) $(PLUGIN_H) \
|
||||
$(TREE_INLINE_H) tree-mudflap.h $(GGC_H) graph.h $(CGRAPH_H) \
|
||||
$(TREE_PASS_H) $(CFGLOOP_H) $(EXCEPT_H)
|
||||
|
||||
|
@ -2725,7 +2727,8 @@ passes.o : passes.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
|
|||
langhooks.h insn-flags.h $(CFGLAYOUT_H) $(REAL_H) $(CFGLOOP_H) \
|
||||
hosthooks.h $(CGRAPH_H) $(COVERAGE_H) $(TREE_PASS_H) $(TREE_DUMP_H) \
|
||||
$(GGC_H) $(INTEGRATE_H) $(CPPLIB_H) opts.h $(TREE_FLOW_H) $(TREE_INLINE_H) \
|
||||
gt-passes.h $(DF_H) $(PREDICT_H) $(LTO_HEADER_H) $(LTO_SECTION_OUT_H)
|
||||
gt-passes.h $(DF_H) $(PREDICT_H) $(LTO_HEADER_H) $(LTO_SECTION_OUT_H) \
|
||||
$(PLUGIN_H)
|
||||
|
||||
plugin.o : plugin.c $(PLUGIN_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h \
|
||||
$(TOPLEV_H) $(TREE_H) $(TREE_PASS_H) intl.h $(PLUGIN_VERSION_H) $(GGC_H)
|
||||
|
@ -4264,7 +4267,7 @@ installdirs:
|
|||
|
||||
PLUGIN_HEADERS = $(TREE_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
|
||||
$(TOPLEV_H) $(BASIC_BLOCK_H) $(GIMPLE_H) $(TREE_PASS_H) $(GCC_PLUGIN_H) \
|
||||
$(GGC_H) $(TREE_DUMP_H) $(PRETTY_PRINT_H) \
|
||||
$(GGC_H) $(TREE_DUMP_H) $(PRETTY_PRINT_H) opts.h $(PARAMS_H) plugin.def \
|
||||
$(tm_file_list) $(tm_include_list) $(tm_p_file_list) $(tm_p_include_list) \
|
||||
$(host_xm_file_list) $(host_xm_include_list) $(xm_include_list) \
|
||||
intl.h $(PLUGIN_VERSION_H) $(DIAGNOSTIC_H) $(C_COMMON_H) $(C_PRETTY_PRINT_H) \
|
||||
|
@ -4273,8 +4276,15 @@ PLUGIN_HEADERS = $(TREE_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
|
|||
$(C_PRAGMA_H) $(CPPLIB_H) $(FUNCTION_H) \
|
||||
cppdefault.h flags.h $(MD5_H) params.def params.h prefix.h tree-inline.h
|
||||
|
||||
# generate the 'build fragment' b-header-vars
|
||||
s-header-vars: Makefile
|
||||
rm -f tmp-header-vars
|
||||
$(foreach header_var,$(shell sed < Makefile -e 's/^\([A-Z0-9_]*_H\)[ ]*=.*/\1/p' -e d),echo $(header_var)=$(shell echo $($(header_var):$(srcdir)/%=.../%) | sed -e 's~\.\.\./config/~config/~' -e 's~\.\.\..*/~~') >> tmp-header-vars;) \
|
||||
$(SHELL) $(srcdir)/../move-if-change tmp-header-vars b-header-vars
|
||||
$(STAMP) s-header-vars
|
||||
|
||||
# Install the headers needed to build a plugin.
|
||||
install-plugin: installdirs lang.install-plugin
|
||||
install-plugin: installdirs lang.install-plugin s-header-vars
|
||||
# We keep the directory structure for files in config and .def files. All
|
||||
# other files are flattened to a single directory.
|
||||
$(mkinstalldirs) $(DESTDIR)$(plugin_includedir)
|
||||
|
@ -4298,6 +4308,7 @@ install-plugin: installdirs lang.install-plugin
|
|||
$(mkinstalldirs) $(DESTDIR)$$dir; \
|
||||
$(INSTALL_DATA) $$path $(DESTDIR)$$dest; \
|
||||
done
|
||||
$(INSTALL_DATA) b-header-vars $(DESTDIR)$(plugin_includedir)/b-header-vars
|
||||
|
||||
# Install the compiler executables built during cross compilation.
|
||||
install-common: native lang.install-common installdirs
|
||||
|
|
|
@ -135,6 +135,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "tree-dump.h"
|
||||
#include "output.h"
|
||||
#include "coverage.h"
|
||||
#include "plugin.h"
|
||||
|
||||
static void cgraph_expand_all_functions (void);
|
||||
static void cgraph_mark_functions_to_output (void);
|
||||
|
@ -1712,6 +1713,8 @@ ipa_passes (void)
|
|||
gimple_register_cfg_hooks ();
|
||||
bitmap_obstack_initialize (NULL);
|
||||
|
||||
invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_START, NULL);
|
||||
|
||||
if (!in_lto_p)
|
||||
execute_ipa_pass_list (all_small_ipa_passes);
|
||||
|
||||
|
@ -1730,7 +1733,8 @@ ipa_passes (void)
|
|||
current_function_decl = NULL;
|
||||
cgraph_process_new_functions ();
|
||||
|
||||
execute_ipa_summary_passes ((struct ipa_opt_pass_d *) all_regular_ipa_passes);
|
||||
execute_ipa_summary_passes
|
||||
((struct ipa_opt_pass_d *) all_regular_ipa_passes);
|
||||
}
|
||||
execute_ipa_summary_passes ((struct ipa_opt_pass_d *) all_lto_gen_passes);
|
||||
|
||||
|
@ -1739,6 +1743,7 @@ ipa_passes (void)
|
|||
|
||||
if (!flag_ltrans)
|
||||
execute_ipa_pass_list (all_regular_ipa_passes);
|
||||
invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_END, NULL);
|
||||
|
||||
bitmap_obstack_release (NULL);
|
||||
}
|
||||
|
|
|
@ -156,18 +156,42 @@ enum plugin_event
|
|||
PLUGIN_ATTRIBUTES, /* Called during attribute registration */
|
||||
PLUGIN_START_UNIT, /* Called before processing a translation unit. */
|
||||
PLUGIN_PRAGMAS, /* Called during pragma registration. */
|
||||
PLUGIN_EVENT_LAST /* Dummy event used for indexing callback
|
||||
/* Called before first pass from all_passes. */
|
||||
PLUGIN_ALL_PASSES_START,
|
||||
/* Called after last pass from all_passes. */
|
||||
PLUGIN_ALL_PASSES_END,
|
||||
/* Called before first ipa pass. */
|
||||
PLUGIN_ALL_IPA_PASSES_START,
|
||||
/* Called after last ipa pass. */
|
||||
PLUGIN_ALL_IPA_PASSES_END,
|
||||
/* Allows to override pass gate decision for current_pass. */
|
||||
PLUGIN_OVERRIDE_GATE,
|
||||
/* Called before executing a pass. */
|
||||
PLUGIN_PASS_EXECUTION,
|
||||
/* Called before executing subpasses of a GIMPLE_PASS in
|
||||
execute_ipa_pass_list. */
|
||||
PLUGIN_EARLY_GIMPLE_PASSES_START,
|
||||
/* Called after executing subpasses of a GIMPLE_PASS in
|
||||
execute_ipa_pass_list. */
|
||||
PLUGIN_EARLY_GIMPLE_PASSES_END,
|
||||
/* Called when a pass is first instantiated. */
|
||||
PLUGIN_NEW_PASS,
|
||||
|
||||
PLUGIN_EVENT_FIRST_DYNAMIC /* Dummy event used for indexing callback
|
||||
array. */
|
||||
@};
|
||||
@end smallexample
|
||||
|
||||
In addition, plugins can also look up the enumerator of a named event,
|
||||
and / or generate new events dynamically, by calling the function
|
||||
@code{get_named_event_id}.
|
||||
|
||||
To register a callback, the plugin calls @code{register_callback} with
|
||||
the arguments:
|
||||
|
||||
@itemize
|
||||
@item @code{char *name}: Plugin name.
|
||||
@item @code{enum plugin_event event}: The event code.
|
||||
@item @code{int event}: The event code.
|
||||
@item @code{plugin_callback_func callback}: The function that handles @code{event}.
|
||||
@item @code{void *user_data}: Pointer to plugin-specific data.
|
||||
@end itemize
|
||||
|
@ -337,6 +361,41 @@ It is suggested to pass @code{"GCCPLUGIN"} (or a short name identifying
|
|||
your plugin) as the ``space'' argument of your pragma.
|
||||
|
||||
|
||||
@section Recording information about pass execution
|
||||
|
||||
The event PLUGIN_PASS_EXECUTION passes the pointer to the executed pass
|
||||
(the same as current_pass) as @code{gcc_data} to the callback. You can also
|
||||
inspect cfun to find out about which function this pass is executed for.
|
||||
Note that this event will only be invoked if the gate check (if
|
||||
applicable, modified by PLUGIN_OVERRIDE_GATE) succeeds.
|
||||
You can use other hooks, like @code{PLUGIN_ALL_PASSES_START},
|
||||
@code{PLUGIN_ALL_PASSES_END}, @code{PLUGIN_ALL_IPA_PASSES_START},
|
||||
@code{PLUGIN_ALL_IPA_PASSES_END}, @code{PLUGIN_EARLY_GIMPLE_PASSES_START},
|
||||
and/or @code{PLUGIN_EARLY_GIMPLE_PASSES_END} to manipulate global state
|
||||
in your plugin(s) in order to get context for the pass execution.
|
||||
|
||||
|
||||
@section Controlling which passes are being run
|
||||
|
||||
After the original gate function for a pass is called, its result
|
||||
- the gate status - is stored as an integer.
|
||||
Then the event @code{PLUGIN_OVERRIDE_GATE} is invoked, with a pointer
|
||||
to the gate status in the @code{gcc_data} parameter to the callback function.
|
||||
A nonzero value of the gate status means that the pass is to be executed.
|
||||
You can both read and write the gate status via the passed pointer.
|
||||
|
||||
|
||||
@section Keeping track of available passes
|
||||
|
||||
When your plugin is loaded, you can inspect the various
|
||||
pass lists to determine what passes are available. However, other
|
||||
plugins might add new passes. Also, future changes to GCC might cause
|
||||
generic passes to be added after plugin loading.
|
||||
When a pass is first added to one of the pass lists, the event
|
||||
@code{PLUGIN_NEW_PASS} is invoked, with the callback parameter
|
||||
@code{gcc_data} pointing to the new pass.
|
||||
|
||||
|
||||
@section Building GCC plugins
|
||||
|
||||
If plugins are enabled, GCC installs the headers needed to build a
|
||||
|
|
|
@ -26,29 +26,19 @@ along with GCC; see the file COPYING3. If not see
|
|||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "highlev-plugin-common.h"
|
||||
#include "hashtab.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. */
|
||||
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[];
|
||||
extern const char **plugin_event_name;
|
||||
|
||||
struct plugin_argument
|
||||
{
|
||||
|
@ -127,14 +117,22 @@ typedef void (*plugin_callback_func) (void *gcc_data, void *user_data);
|
|||
USER_DATA - plugin-provided data.
|
||||
*/
|
||||
|
||||
/* Number of event ids / names registered so far. */
|
||||
|
||||
extern int get_event_last (void);
|
||||
|
||||
int get_named_event_id (const char *name, enum insert_option insert);
|
||||
|
||||
/* This is also called without a callback routine for the
|
||||
PLUGIN_PASS_MANAGER_SETUP, PLUGIN_INFO, PLUGIN_REGISTER_GGC_ROOTS and
|
||||
PLUGIN_REGISTER_GGC_CACHES pseudo-events, with a specific user_data.
|
||||
*/
|
||||
|
||||
extern void register_callback (const char *plugin_name,
|
||||
enum plugin_event event,
|
||||
int event,
|
||||
plugin_callback_func callback,
|
||||
void *user_data);
|
||||
|
||||
extern int unregister_callback (const char *plugin_name, int event);
|
||||
|
||||
#endif /* GCC_PLUGIN_H */
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
/* Interface for high-level plugins in GCC - Parts common between GCC,
|
||||
ICI and high-level plugins.
|
||||
|
||||
Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
|
||||
Contributed by INRIA.
|
||||
|
||||
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
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef HIGHLEV_PLUGIN_COMMON_H
|
||||
#define HIGHLEV_PLUGIN_COMMON_H
|
||||
|
||||
/* Return codes for invoke_plugin_callbacks / call_plugin_event . */
|
||||
#define PLUGEVT_SUCCESS 0
|
||||
#define PLUGEVT_NO_EVENTS 1
|
||||
#define PLUGEVT_NO_SUCH_EVENT 2
|
||||
#define PLUGEVT_NO_CALLBACK 3
|
||||
|
||||
#endif /* HIGHLEV_PLUGIN_COMMON_H */
|
10
gcc/params.c
10
gcc/params.c
|
@ -32,7 +32,6 @@ along with GCC; see the file COPYING3. If not see
|
|||
param_info *compiler_params;
|
||||
|
||||
/* The number of entries in the table. */
|
||||
|
||||
static size_t num_compiler_params;
|
||||
|
||||
/* Add the N PARAMS to the current list of compiler parameters. */
|
||||
|
@ -85,3 +84,12 @@ set_param_value (const char *name, int value)
|
|||
/* If we didn't find this parameter, issue an error message. */
|
||||
error ("invalid parameter %qs", name);
|
||||
}
|
||||
|
||||
/* Return the current value of num_compiler_params, for the benefit of
|
||||
plugins that use parameters as features. */
|
||||
|
||||
size_t
|
||||
get_num_compiler_params (void)
|
||||
{
|
||||
return num_compiler_params;
|
||||
}
|
||||
|
|
|
@ -65,6 +65,9 @@ typedef struct param_info
|
|||
|
||||
extern param_info *compiler_params;
|
||||
|
||||
/* Returns the number of entries in the table, for the use by plugins. */
|
||||
extern size_t get_num_compiler_params (void);
|
||||
|
||||
/* Add the N PARAMS to the current list of compiler parameters. */
|
||||
|
||||
extern void add_params (const param_info params[], size_t n);
|
||||
|
|
49
gcc/passes.c
49
gcc/passes.c
|
@ -85,6 +85,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "df.h"
|
||||
#include "predict.h"
|
||||
#include "lto-streamer.h"
|
||||
#include "plugin.h"
|
||||
|
||||
#if defined (DWARF2_UNWIND_INFO) || defined (DWARF2_DEBUGGING_INFO)
|
||||
#include "dwarf2out.h"
|
||||
|
@ -104,7 +105,8 @@ 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;
|
||||
|
||||
/* Call from anywhere to find out what pass this is. Useful for
|
||||
|
@ -479,6 +481,8 @@ make_pass_instance (struct opt_pass *pass, bool track_duplicates)
|
|||
{
|
||||
pass->todo_flags_start |= TODO_mark_first_instance;
|
||||
pass->static_pass_number = -1;
|
||||
|
||||
invoke_plugin_callbacks (PLUGIN_NEW_PASS, pass);
|
||||
}
|
||||
return pass;
|
||||
}
|
||||
|
@ -1090,9 +1094,9 @@ static GTY ((length ("nnodes"))) struct cgraph_node **order;
|
|||
|
||||
/* If we are in IPA mode (i.e., current_function_decl is NULL), call
|
||||
function CALLBACK for every function in the call graph. Otherwise,
|
||||
call CALLBACK on the current function. */
|
||||
|
||||
static void
|
||||
call CALLBACK on the current function.
|
||||
This function is global so that plugins can use it. */
|
||||
void
|
||||
do_per_function_toporder (void (*callback) (void *data), void *data)
|
||||
{
|
||||
int i;
|
||||
|
@ -1317,8 +1321,9 @@ verify_curr_properties (void *data)
|
|||
#endif
|
||||
|
||||
/* Initialize pass dump file. */
|
||||
/* This is non-static so that the plugins can use it. */
|
||||
|
||||
static bool
|
||||
bool
|
||||
pass_init_dump_file (struct opt_pass *pass)
|
||||
{
|
||||
/* If a dump file name is present, open it if enabled. */
|
||||
|
@ -1347,8 +1352,9 @@ pass_init_dump_file (struct opt_pass *pass)
|
|||
}
|
||||
|
||||
/* Flush PASS dump file. */
|
||||
/* This is non-static so that plugins can use it. */
|
||||
|
||||
static void
|
||||
void
|
||||
pass_fini_dump_file (struct opt_pass *pass)
|
||||
{
|
||||
/* Flush and close dump file. */
|
||||
|
@ -1476,12 +1482,14 @@ execute_all_ipa_transforms (void)
|
|||
|
||||
/* Execute PASS. */
|
||||
|
||||
static bool
|
||||
bool
|
||||
execute_one_pass (struct opt_pass *pass)
|
||||
{
|
||||
bool initializing_dump;
|
||||
unsigned int todo_after = 0;
|
||||
|
||||
bool gate_status;
|
||||
|
||||
/* IPA passes are executed on whole program, so cfun should be NULL.
|
||||
Other passes need function context set. */
|
||||
if (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS)
|
||||
|
@ -1491,9 +1499,22 @@ execute_one_pass (struct opt_pass *pass)
|
|||
|
||||
current_pass = pass;
|
||||
|
||||
/* See if we're supposed to run this pass. */
|
||||
if (pass->gate && !pass->gate ())
|
||||
return false;
|
||||
/* 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();
|
||||
|
||||
/* Override gate with plugin. */
|
||||
invoke_plugin_callbacks (PLUGIN_OVERRIDE_GATE, &gate_status);
|
||||
|
||||
if (!gate_status)
|
||||
{
|
||||
current_pass = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Pass execution event trigger: useful to identify passes being
|
||||
executed. */
|
||||
invoke_plugin_callbacks (PLUGIN_PASS_EXECUTION, pass);
|
||||
|
||||
if (!quiet_flag && !cfun)
|
||||
fprintf (stderr, " <%s>", pass->name ? pass->name : "");
|
||||
|
@ -1756,8 +1777,12 @@ execute_ipa_pass_list (struct opt_pass *pass)
|
|||
if (execute_one_pass (pass) && pass->sub)
|
||||
{
|
||||
if (pass->sub->type == GIMPLE_PASS)
|
||||
do_per_function_toporder ((void (*)(void *))execute_pass_list,
|
||||
pass->sub);
|
||||
{
|
||||
invoke_plugin_callbacks (PLUGIN_EARLY_GIMPLE_PASSES_START, NULL);
|
||||
do_per_function_toporder ((void (*)(void *))execute_pass_list,
|
||||
pass->sub);
|
||||
invoke_plugin_callbacks (PLUGIN_EARLY_GIMPLE_PASSES_END, NULL);
|
||||
}
|
||||
else if (pass->sub->type == SIMPLE_IPA_PASS
|
||||
|| pass->sub->type == IPA_PASS)
|
||||
execute_ipa_pass_list (pass->sub);
|
||||
|
|
190
gcc/plugin.c
190
gcc/plugin.c
|
@ -44,28 +44,30 @@ 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. */
|
||||
const char *plugin_event_name[] =
|
||||
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_EVENT_LAST"
|
||||
# define DEFEVENT(NAME) GCC_PLUGIN_STRINGIFY1 (NAME),
|
||||
# include "plugin.def"
|
||||
# undef DEFEVENT
|
||||
};
|
||||
|
||||
/* A printf format large enough for the largest event above. */
|
||||
#define FMT_FOR_PLUGIN_EVENT "%-26s"
|
||||
#define FMT_FOR_PLUGIN_EVENT "%-32s"
|
||||
|
||||
const char **plugin_event_name = plugin_event_name_init;
|
||||
|
||||
/* A hash table to map event names to the position of the names in the
|
||||
plugin_event_name table. */
|
||||
static htab_t event_tab;
|
||||
|
||||
/* Keep track of the limit of allocated events and space ready for
|
||||
allocating events. */
|
||||
static 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. */
|
||||
|
@ -81,7 +83,8 @@ 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 };
|
||||
static struct callback_info *plugin_callbacks_init[PLUGIN_EVENT_FIRST_DYNAMIC];
|
||||
static struct callback_info **plugin_callbacks = plugin_callbacks_init;
|
||||
|
||||
|
||||
#ifdef ENABLE_PLUGIN
|
||||
|
@ -290,6 +293,71 @@ register_plugin_info (const char* name, struct plugin_info *info)
|
|||
plugin->help = info->help;
|
||||
}
|
||||
|
||||
/* Helper function for the event hash table that compares the name of an
|
||||
existing entry (E1) with the given string (S2). */
|
||||
|
||||
static int
|
||||
htab_event_eq (const void *e1, const void *s2)
|
||||
{
|
||||
const char *s1= *(const char * const *) e1;
|
||||
return !strcmp (s1, (const char *) s2);
|
||||
}
|
||||
|
||||
/* Look up the event id for NAME. If the name is not found, return -1
|
||||
if INSERT is NO_INSERT. */
|
||||
|
||||
int
|
||||
get_named_event_id (const char *name, enum insert_option insert)
|
||||
{
|
||||
void **slot;
|
||||
|
||||
if (!event_tab)
|
||||
{
|
||||
int i;
|
||||
|
||||
event_tab = htab_create (150, htab_hash_string, htab_event_eq, NULL);
|
||||
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);
|
||||
*slot = &plugin_event_name[i];
|
||||
}
|
||||
}
|
||||
slot = htab_find_slot (event_tab, name, insert);
|
||||
if (slot == NULL)
|
||||
return -1;
|
||||
if (*slot != HTAB_EMPTY_ENTRY)
|
||||
return (const char **) *slot - &plugin_event_name[0];
|
||||
|
||||
if (event_last >= event_horizon)
|
||||
{
|
||||
event_horizon = event_last * 2;
|
||||
if (plugin_event_name == plugin_event_name_init)
|
||||
{
|
||||
plugin_event_name = XNEWVEC (const char *, event_horizon);
|
||||
memcpy (plugin_event_name, plugin_event_name_init,
|
||||
sizeof plugin_event_name_init);
|
||||
plugin_callbacks = XNEWVEC (struct callback_info *, event_horizon);
|
||||
memcpy (plugin_callbacks, plugin_callbacks_init,
|
||||
sizeof plugin_callbacks_init);
|
||||
}
|
||||
else
|
||||
{
|
||||
plugin_event_name
|
||||
= XRESIZEVEC (const char *, plugin_event_name, event_horizon);
|
||||
plugin_callbacks = XRESIZEVEC (struct callback_info *,
|
||||
plugin_callbacks, event_horizon);
|
||||
}
|
||||
/* All the pointers in the hash table will need to be updated. */
|
||||
htab_delete (event_tab);
|
||||
event_tab = NULL;
|
||||
}
|
||||
else
|
||||
*slot = &plugin_event_name[event_last];
|
||||
plugin_event_name[event_last] = name;
|
||||
return event_last++;
|
||||
}
|
||||
|
||||
/* Called from the plugin's initialization code. Register a single callback.
|
||||
This function can be called multiple times.
|
||||
|
||||
|
@ -300,7 +368,7 @@ register_plugin_info (const char* name, struct plugin_info *info)
|
|||
|
||||
void
|
||||
register_callback (const char *plugin_name,
|
||||
enum plugin_event event,
|
||||
int event,
|
||||
plugin_callback_func callback,
|
||||
void *user_data)
|
||||
{
|
||||
|
@ -322,6 +390,15 @@ register_callback (const char *plugin_name,
|
|||
gcc_assert (!callback);
|
||||
ggc_register_cache_tab ((const struct ggc_cache_tab*) user_data);
|
||||
break;
|
||||
case PLUGIN_EVENT_FIRST_DYNAMIC:
|
||||
default:
|
||||
if (event < PLUGIN_EVENT_FIRST_DYNAMIC || event >= event_last)
|
||||
{
|
||||
error ("Unknown callback event registered by plugin %s",
|
||||
plugin_name);
|
||||
return;
|
||||
}
|
||||
/* Fall through. */
|
||||
case PLUGIN_FINISH_TYPE:
|
||||
case PLUGIN_START_UNIT:
|
||||
case PLUGIN_FINISH_UNIT:
|
||||
|
@ -332,6 +409,15 @@ register_callback (const char *plugin_name,
|
|||
case PLUGIN_ATTRIBUTES:
|
||||
case PLUGIN_PRAGMAS:
|
||||
case PLUGIN_FINISH:
|
||||
case PLUGIN_ALL_PASSES_START:
|
||||
case PLUGIN_ALL_PASSES_END:
|
||||
case PLUGIN_ALL_IPA_PASSES_START:
|
||||
case PLUGIN_ALL_IPA_PASSES_END:
|
||||
case PLUGIN_OVERRIDE_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)
|
||||
|
@ -348,27 +434,52 @@ register_callback (const char *plugin_name,
|
|||
plugin_callbacks[event] = new_callback;
|
||||
}
|
||||
break;
|
||||
case PLUGIN_EVENT_LAST:
|
||||
default:
|
||||
error ("Unknown callback event registered by plugin %s",
|
||||
plugin_name);
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove a callback for EVENT which has been registered with for a plugin
|
||||
PLUGIN_NAME. Return PLUGEVT_SUCCESS if a matching callback was
|
||||
found & removed, PLUGEVT_NO_CALLBACK if the event does not have a matching
|
||||
callback, and PLUGEVT_NO_SUCH_EVENT if EVENT is invalid. */
|
||||
int
|
||||
unregister_callback (const char *plugin_name, int event)
|
||||
{
|
||||
struct callback_info *callback, **cbp;
|
||||
|
||||
if (event >= event_last)
|
||||
return PLUGEVT_NO_SUCH_EVENT;
|
||||
|
||||
for (cbp = &plugin_callbacks[event]; (callback = *cbp); cbp = &callback->next)
|
||||
if (strcmp (callback->plugin_name, plugin_name) == 0)
|
||||
{
|
||||
*cbp = callback->next;
|
||||
return PLUGEVT_SUCCESS;
|
||||
}
|
||||
return PLUGEVT_NO_CALLBACK;
|
||||
}
|
||||
|
||||
/* Called from inside GCC. Invoke all plug-in callbacks registered with
|
||||
the specified event.
|
||||
Return PLUGEVT_SUCCESS if at least one callback was called,
|
||||
PLUGEVT_NO_CALLBACK if there was no callback.
|
||||
|
||||
EVENT - the event identifier
|
||||
GCC_DATA - event-specific data provided by the compiler */
|
||||
|
||||
void
|
||||
invoke_plugin_callbacks (enum plugin_event event, void *gcc_data)
|
||||
int
|
||||
invoke_plugin_callbacks (int event, void *gcc_data)
|
||||
{
|
||||
int retval = PLUGEVT_SUCCESS;
|
||||
|
||||
timevar_push (TV_PLUGIN_RUN);
|
||||
|
||||
switch (event)
|
||||
{
|
||||
case PLUGIN_EVENT_FIRST_DYNAMIC:
|
||||
default:
|
||||
gcc_assert (event >= PLUGIN_EVENT_FIRST_DYNAMIC);
|
||||
gcc_assert (event < event_last);
|
||||
/* Fall through. */
|
||||
case PLUGIN_FINISH_TYPE:
|
||||
case PLUGIN_START_UNIT:
|
||||
case PLUGIN_FINISH_UNIT:
|
||||
|
@ -379,24 +490,35 @@ invoke_plugin_callbacks (enum plugin_event event, void *gcc_data)
|
|||
case PLUGIN_GGC_START:
|
||||
case PLUGIN_GGC_MARKING:
|
||||
case PLUGIN_GGC_END:
|
||||
case PLUGIN_ALL_PASSES_START:
|
||||
case PLUGIN_ALL_PASSES_END:
|
||||
case PLUGIN_ALL_IPA_PASSES_START:
|
||||
case PLUGIN_ALL_IPA_PASSES_END:
|
||||
case PLUGIN_OVERRIDE_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. */
|
||||
struct callback_info *callback = plugin_callbacks[event];
|
||||
|
||||
if (!callback)
|
||||
retval = PLUGEVT_NO_CALLBACK;
|
||||
for ( ; callback; callback = callback->next)
|
||||
(*callback->func) (gcc_data, callback->user_data);
|
||||
}
|
||||
break;
|
||||
|
||||
case PLUGIN_PASS_MANAGER_SETUP:
|
||||
case PLUGIN_EVENT_LAST:
|
||||
case PLUGIN_REGISTER_GGC_ROOTS:
|
||||
case PLUGIN_REGISTER_GGC_CACHES:
|
||||
default:
|
||||
gcc_assert (false);
|
||||
}
|
||||
|
||||
timevar_pop (TV_PLUGIN_RUN);
|
||||
return retval;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_PLUGIN
|
||||
|
@ -621,7 +743,7 @@ plugins_active_p (void)
|
|||
{
|
||||
int event;
|
||||
|
||||
for (event = PLUGIN_PASS_MANAGER_SETUP; event < PLUGIN_EVENT_LAST; event++)
|
||||
for (event = PLUGIN_PASS_MANAGER_SETUP; event < event_last; event++)
|
||||
if (plugin_callbacks[event])
|
||||
return true;
|
||||
|
||||
|
@ -641,7 +763,7 @@ dump_active_plugins (FILE *file)
|
|||
return;
|
||||
|
||||
fprintf (file, FMT_FOR_PLUGIN_EVENT " | %s\n", _("Event"), _("Plugins"));
|
||||
for (event = PLUGIN_PASS_MANAGER_SETUP; event < PLUGIN_EVENT_LAST; event++)
|
||||
for (event = PLUGIN_PASS_MANAGER_SETUP; event < event_last; event++)
|
||||
if (plugin_callbacks[event])
|
||||
{
|
||||
struct callback_info *ci;
|
||||
|
@ -686,3 +808,13 @@ plugin_default_version_check (struct plugin_gcc_version *gcc_version,
|
|||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Return the current value of event_last, so that plugins which provide
|
||||
additional functionality for events for the benefit of high-level plugins
|
||||
know how many valid entries plugin_event_name holds. */
|
||||
|
||||
int
|
||||
get_event_last (void)
|
||||
{
|
||||
return event_last;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
/* 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
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
|
||||
/* 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 before first pass from all_passes. */
|
||||
DEFEVENT (PLUGIN_ALL_PASSES_START)
|
||||
|
||||
/* Called after last pass from all_passes. */
|
||||
DEFEVENT (PLUGIN_ALL_PASSES_END)
|
||||
|
||||
/* Called before first ipa pass. */
|
||||
DEFEVENT (PLUGIN_ALL_IPA_PASSES_START)
|
||||
|
||||
/* Called after last ipa pass. */
|
||||
DEFEVENT (PLUGIN_ALL_IPA_PASSES_END)
|
||||
|
||||
/* Allows to override pass gate decision for current_pass. */
|
||||
DEFEVENT (PLUGIN_OVERRIDE_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. */
|
|
@ -26,7 +26,7 @@ struct attribute_spec;
|
|||
|
||||
extern void add_new_plugin (const char *);
|
||||
extern void parse_plugin_arg_opt (const char *);
|
||||
extern void invoke_plugin_callbacks (enum plugin_event, void *);
|
||||
extern int invoke_plugin_callbacks (int, void *);
|
||||
extern void initialize_plugins (void);
|
||||
extern bool plugins_active_p (void);
|
||||
extern void dump_active_plugins (FILE *);
|
||||
|
|
|
@ -49,6 +49,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "graph.h"
|
||||
#include "cfgloop.h"
|
||||
#include "except.h"
|
||||
#include "plugin.h"
|
||||
|
||||
|
||||
/* Gate: execute, or not, all of the non-trivial optimizations. */
|
||||
|
@ -405,8 +406,15 @@ tree_rest_of_compilation (tree fndecl)
|
|||
execute_all_ipa_transforms ();
|
||||
|
||||
/* Perform all tree transforms and optimizations. */
|
||||
|
||||
/* Signal the start of passes. */
|
||||
invoke_plugin_callbacks (PLUGIN_ALL_PASSES_START, NULL);
|
||||
|
||||
execute_pass_list (all_passes);
|
||||
|
||||
/* Signal the end of passes. */
|
||||
invoke_plugin_callbacks (PLUGIN_ALL_PASSES_END, NULL);
|
||||
|
||||
bitmap_obstack_release (®_obstack);
|
||||
|
||||
/* Release the default bitmap obstack. */
|
||||
|
|
|
@ -566,12 +566,16 @@ extern struct opt_pass *all_passes, *all_small_ipa_passes, *all_lowering_passes,
|
|||
extern struct opt_pass *current_pass;
|
||||
|
||||
extern struct opt_pass * get_pass_for_id (int);
|
||||
extern bool execute_one_pass (struct opt_pass *);
|
||||
extern void execute_pass_list (struct opt_pass *);
|
||||
extern void execute_ipa_pass_list (struct opt_pass *);
|
||||
extern void execute_ipa_summary_passes (struct ipa_opt_pass_d *);
|
||||
extern void execute_all_ipa_transforms (void);
|
||||
extern void execute_all_ipa_stmt_fixups (struct cgraph_node *, gimple *);
|
||||
extern bool pass_init_dump_file (struct opt_pass *);
|
||||
extern void pass_fini_dump_file (struct opt_pass *);
|
||||
|
||||
extern const char *get_current_pass_name (void);
|
||||
extern void print_current_pass (FILE *);
|
||||
extern void debug_pass (void);
|
||||
extern void ipa_write_summaries (void);
|
||||
|
@ -591,4 +595,7 @@ extern void register_pass (struct register_pass_info *);
|
|||
directly in jump threading, and avoid peeling them next time. */
|
||||
extern bool first_pass_instance;
|
||||
|
||||
/* Declare for plugins. */
|
||||
extern void do_per_function_toporder (void (*) (void *), void *);
|
||||
|
||||
#endif /* GCC_TREE_PASS_H */
|
||||
|
|
Loading…
Reference in New Issue