123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512 |
- @c Copyright (C) 2009-2015 Free Software Foundation, Inc.
- @c Free Software Foundation, Inc.
- @c This is part of the GCC manual.
- @c For copying conditions, see the file gcc.texi.
- @node Plugins
- @chapter Plugins
- @cindex Plugins
- GCC plugins are loadable modules that provide extra features to the
- compiler. Like GCC itself they can be distributed in source and
- binary forms.
- GCC plugins provide developers with a rich subset of
- the GCC API to allow them to extend GCC as they see fit.
- Whether it is writing an additional optimization pass,
- transforming code, or analyzing information, plugins
- can be quite useful.
- @menu
- * Plugins loading:: How can we load plugins.
- * Plugin API:: The APIs for plugins.
- * Plugins pass:: How a plugin interact with the pass manager.
- * Plugins GC:: How a plugin Interact with GCC Garbage Collector.
- * Plugins description:: Giving information about a plugin itself.
- * Plugins attr:: Registering custom attributes or pragmas.
- * Plugins recording:: Recording information about pass execution.
- * Plugins gate:: Controlling which passes are being run.
- * Plugins tracking:: Keeping track of available passes.
- * Plugins building:: How can we build a plugin.
- @end menu
- @node Plugins loading
- @section Loading Plugins
- Plugins are supported on platforms that support @option{-ldl
- -rdynamic}. They are loaded by the compiler using @code{dlopen}
- and invoked at pre-determined locations in the compilation
- process.
- Plugins are loaded with
- @option{-fplugin=/path/to/@var{name}.so} @option{-fplugin-arg-@var{name}-@var{key1}[=@var{value1}]}
- The plugin arguments are parsed by GCC and passed to respective
- plugins as key-value pairs. Multiple plugins can be invoked by
- specifying multiple @option{-fplugin} arguments.
- A plugin can be simply given by its short name (no dots or
- slashes). When simply passing @option{-fplugin=@var{name}}, the plugin is
- loaded from the @file{plugin} directory, so @option{-fplugin=@var{name}} is
- the same as @option{-fplugin=`gcc -print-file-name=plugin`/@var{name}.so},
- using backquote shell syntax to query the @file{plugin} directory.
- @node Plugin API
- @section Plugin API
- Plugins are activated by the compiler at specific events as defined in
- @file{gcc-plugin.h}. For each event of interest, the plugin should
- call @code{register_callback} specifying the name of the event and
- address of the callback function that will handle that event.
- The header @file{gcc-plugin.h} must be the first gcc header to be included.
- @subsection Plugin license check
- Every plugin should define the global symbol @code{plugin_is_GPL_compatible}
- to assert that it has been licensed under a GPL-compatible license.
- If this symbol does not exist, the compiler will emit a fatal error
- and exit with the error message:
- @smallexample
- fatal error: plugin @var{name} is not licensed under a GPL-compatible license
- @var{name}: undefined symbol: plugin_is_GPL_compatible
- compilation terminated
- @end smallexample
- The declared type of the symbol should be int, to match a forward declaration
- in @file{gcc-plugin.h} that suppresses C++ mangling. It does not need to be in
- any allocated section, though. The compiler merely asserts that
- the symbol exists in the global scope. Something like this is enough:
- @smallexample
- int plugin_is_GPL_compatible;
- @end smallexample
- @subsection Plugin initialization
- Every plugin should export a function called @code{plugin_init} that
- is called right after the plugin is loaded. This function is
- responsible for registering all the callbacks required by the plugin
- and do any other required initialization.
- This function is called from @code{compile_file} right before invoking
- the parser. The arguments to @code{plugin_init} are:
- @itemize @bullet
- @item @code{plugin_info}: Plugin invocation information.
- @item @code{version}: GCC version.
- @end itemize
- The @code{plugin_info} struct is defined as follows:
- @smallexample
- struct plugin_name_args
- @{
- char *base_name; /* Short name of the plugin
- (filename without .so suffix). */
- const char *full_name; /* Path to the plugin as specified with
- -fplugin=. */
- int argc; /* Number of arguments specified with
- -fplugin-arg-.... */
- struct plugin_argument *argv; /* Array of ARGC key-value pairs. */
- const char *version; /* Version string provided by plugin. */
- const char *help; /* Help string provided by plugin. */
- @}
- @end smallexample
- If initialization fails, @code{plugin_init} must return a non-zero
- value. Otherwise, it should return 0.
- The version of the GCC compiler loading the plugin is described by the
- following structure:
- @smallexample
- struct plugin_gcc_version
- @{
- const char *basever;
- const char *datestamp;
- const char *devphase;
- const char *revision;
- const char *configuration_arguments;
- @};
- @end smallexample
- The function @code{plugin_default_version_check} takes two pointers to
- such structure and compare them field by field. It can be used by the
- plugin's @code{plugin_init} function.
- The version of GCC used to compile the plugin can be found in the symbol
- @code{gcc_version} defined in the header @file{plugin-version.h}. The
- recommended version check to perform looks like
- @smallexample
- #include "plugin-version.h"
- ...
- int
- plugin_init (struct plugin_name_args *plugin_info,
- struct plugin_gcc_version *version)
- @{
- if (!plugin_default_version_check (version, &gcc_version))
- return 1;
- @}
- @end smallexample
- but you can also check the individual fields if you want a less strict check.
- @subsection Plugin callbacks
- Callback functions have the following prototype:
- @smallexample
- /* The prototype for a plugin callback function.
- gcc_data - event-specific data provided by GCC
- user_data - plugin-specific data provided by the plug-in. */
- typedef void (*plugin_callback_func)(void *gcc_data, void *user_data);
- @end smallexample
- Callbacks can be invoked at the following pre-determined events:
- @smallexample
- enum plugin_event
- @{
- PLUGIN_PASS_MANAGER_SETUP, /* To hook into pass manager. */
- PLUGIN_FINISH_TYPE, /* After finishing parsing a type. */
- PLUGIN_FINISH_DECL, /* After finishing parsing a declaration. */
- PLUGIN_FINISH_UNIT, /* Useful for summary processing. */
- PLUGIN_PRE_GENERICIZE, /* Allows to see low level AST in C and C++ frontends. */
- 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_ATTRIBUTES, /* Called during attribute registration */
- PLUGIN_START_UNIT, /* Called before processing a translation unit. */
- PLUGIN_PRAGMAS, /* Called during pragma registration. */
- /* 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,
- /* Called when a file is #include-d or given via the #line directive.
- This could happen many times. The event data is the included file path,
- as a const char* pointer. */
- PLUGIN_INCLUDE_FILE,
- 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{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
- For the @i{PLUGIN_PASS_MANAGER_SETUP}, @i{PLUGIN_INFO}, and
- @i{PLUGIN_REGISTER_GGC_ROOTS} pseudo-events the @code{callback} should be null,
- and the @code{user_data} is specific.
- When the @i{PLUGIN_PRAGMAS} event is triggered (with a null pointer as
- data from GCC), plugins may register their own pragmas. Notice that
- pragmas are not available from @file{lto1}, so plugins used with
- @code{-flto} option to GCC during link-time optimization cannot use
- pragmas and do not even see functions like @code{c_register_pragma} or
- @code{pragma_lex}.
- The @i{PLUGIN_INCLUDE_FILE} event, with a @code{const char*} file path as
- GCC data, is triggered for processing of @code{#include} or
- @code{#line} directives.
- The @i{PLUGIN_FINISH} event is the last time that plugins can call GCC
- functions, notably emit diagnostics with @code{warning}, @code{error}
- etc.
- @node Plugins pass
- @section Interacting with the pass manager
- There needs to be a way to add/reorder/remove passes dynamically. This
- is useful for both analysis plugins (plugging in after a certain pass
- such as CFG or an IPA pass) and optimization plugins.
- Basic support for inserting new passes or replacing existing passes is
- provided. A plugin registers a new pass with GCC by calling
- @code{register_callback} with the @code{PLUGIN_PASS_MANAGER_SETUP}
- event and a pointer to a @code{struct register_pass_info} object defined as follows
- @smallexample
- 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 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. */
- @};
- /* Sample plugin code that registers a new pass. */
- int
- plugin_init (struct plugin_name_args *plugin_info,
- struct plugin_gcc_version *version)
- @{
- struct register_pass_info pass_info;
- ...
- /* Code to fill in the pass_info object with new pass information. */
- ...
- /* Register the new pass. */
- register_callback (plugin_info->base_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &pass_info);
- ...
- @}
- @end smallexample
- @node Plugins GC
- @section Interacting with the GCC Garbage Collector
- Some plugins may want to be informed when GGC (the GCC Garbage
- Collector) is running. They can register callbacks for the
- @code{PLUGIN_GGC_START} and @code{PLUGIN_GGC_END} events (for which
- the callback is called with a null @code{gcc_data}) to be notified of
- the start or end of the GCC garbage collection.
- Some plugins may need to have GGC mark additional data. This can be
- done by registering a callback (called with a null @code{gcc_data})
- for the @code{PLUGIN_GGC_MARKING} event. Such callbacks can call the
- @code{ggc_set_mark} routine, preferably through the @code{ggc_mark} macro
- (and conversely, these routines should usually not be used in plugins
- outside of the @code{PLUGIN_GGC_MARKING} event). Plugins that wish to hold
- weak references to gc data may also use this event to drop weak references when
- the object is about to be collected. The @code{ggc_marked_p} function can be
- used to tell if an object is marked, or is about to be collected. The
- @code{gt_clear_cache} overloads which some types define may also be of use in
- managing weak references.
- Some plugins may need to add extra GGC root tables, e.g. to handle their own
- @code{GTY}-ed data. This can be done with the @code{PLUGIN_REGISTER_GGC_ROOTS}
- pseudo-event with a null callback and the extra root table (of type @code{struct
- ggc_root_tab*}) as @code{user_data}. Running the
- @code{gengtype -p @var{source-dir} @var{file-list} @var{plugin*.c} ...}
- utility generates these extra root tables.
- You should understand the details of memory management inside GCC
- before using @code{PLUGIN_GGC_MARKING} or @code{PLUGIN_REGISTER_GGC_ROOTS}.
- @node Plugins description
- @section Giving information about a plugin
- A plugin should give some information to the user about itself. This
- uses the following structure:
- @smallexample
- struct plugin_info
- @{
- const char *version;
- const char *help;
- @};
- @end smallexample
- Such a structure is passed as the @code{user_data} by the plugin's
- init routine using @code{register_callback} with the
- @code{PLUGIN_INFO} pseudo-event and a null callback.
- @node Plugins attr
- @section Registering custom attributes or pragmas
- For analysis (or other) purposes it is useful to be able to add custom
- attributes or pragmas.
- The @code{PLUGIN_ATTRIBUTES} callback is called during attribute
- registration. Use the @code{register_attribute} function to register
- custom attributes.
- @smallexample
- /* Attribute handler callback */
- static tree
- handle_user_attribute (tree *node, tree name, tree args,
- int flags, bool *no_add_attrs)
- @{
- return NULL_TREE;
- @}
- /* Attribute definition */
- static struct attribute_spec user_attr =
- @{ "user", 1, 1, false, false, false, handle_user_attribute, false @};
- /* Plugin callback called during attribute registration.
- Registered with register_callback (plugin_name, PLUGIN_ATTRIBUTES, register_attributes, NULL)
- */
- static void
- register_attributes (void *event_data, void *data)
- @{
- warning (0, G_("Callback to register attributes"));
- register_attribute (&user_attr);
- @}
- @end smallexample
- The @i{PLUGIN_PRAGMAS} callback is called once during pragmas
- registration. Use the @code{c_register_pragma},
- @code{c_register_pragma_with_data},
- @code{c_register_pragma_with_expansion},
- @code{c_register_pragma_with_expansion_and_data} functions to register
- custom pragmas and their handlers (which often want to call
- @code{pragma_lex}) from @file{c-family/c-pragma.h}.
- @smallexample
- /* Plugin callback called during pragmas registration. Registered with
- register_callback (plugin_name, PLUGIN_PRAGMAS,
- register_my_pragma, NULL);
- */
- static void
- register_my_pragma (void *event_data, void *data)
- @{
- warning (0, G_("Callback to register pragmas"));
- c_register_pragma ("GCCPLUGIN", "sayhello", handle_pragma_sayhello);
- @}
- @end smallexample
- It is suggested to pass @code{"GCCPLUGIN"} (or a short name identifying
- your plugin) as the ``space'' argument of your pragma.
- Pragmas registered with @code{c_register_pragma_with_expansion} or
- @code{c_register_pragma_with_expansion_and_data} support
- preprocessor expansions. For example:
- @smallexample
- #define NUMBER 10
- #pragma GCCPLUGIN foothreshold (NUMBER)
- @end smallexample
- @node Plugins recording
- @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.
- @node Plugins gate
- @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.
- @node Plugins tracking
- @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.
- @node Plugins building
- @section Building GCC plugins
- If plugins are enabled, GCC installs the headers needed to build a
- plugin (somewhere in the installation tree, e.g. under
- @file{/usr/local}). In particular a @file{plugin/include} directory
- is installed, containing all the header files needed to build plugins.
- On most systems, you can query this @code{plugin} directory by
- invoking @command{gcc -print-file-name=plugin} (replace if needed
- @command{gcc} with the appropriate program path).
- Inside plugins, this @code{plugin} directory name can be queried by
- calling @code{default_plugin_dir_name ()}.
- Plugins may know, when they are compiled, the GCC version for which
- @file{plugin-version.h} is provided. The constant macros
- @code{GCCPLUGIN_VERSION_MAJOR}, @code{GCCPLUGIN_VERSION_MINOR},
- @code{GCCPLUGIN_VERSION_PATCHLEVEL}, @code{GCCPLUGIN_VERSION} are
- integer numbers, so a plugin could ensure it is built for GCC 4.7 with
- @smallexample
- #if GCCPLUGIN_VERSION != 4007
- #error this GCC plugin is for GCC 4.7
- #endif
- @end smallexample
- The following GNU Makefile excerpt shows how to build a simple plugin:
- @smallexample
- HOST_GCC=g++
- TARGET_GCC=gcc
- PLUGIN_SOURCE_FILES= plugin1.c plugin2.cc
- GCCPLUGINS_DIR:= $(shell $(TARGET_GCC) -print-file-name=plugin)
- CXXFLAGS+= -I$(GCCPLUGINS_DIR)/include -fPIC -fno-rtti -O2
- plugin.so: $(PLUGIN_SOURCE_FILES)
- $(HOST_GCC) -shared $(CXXFLAGS) $^ -o $@@
- @end smallexample
- A single source file plugin may be built with @code{g++ -I`gcc
- -print-file-name=plugin`/include -fPIC -shared -fno-rtti -O2 plugin.c -o
- plugin.so}, using backquote shell syntax to query the @file{plugin}
- directory.
- When a plugin needs to use @command{gengtype}, be sure that both
- @file{gengtype} and @file{gtype.state} have the same version as the
- GCC for which the plugin is built.
|