@c Copyright (c) 2009 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

@section Loading Plugins

Plugins are supported on platforms that support @option{-ld
-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/NAME.so} @option{-fplugin-arg-NAME-<key1>[=<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.


@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.

@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_name}: Name of the plugin.
@item @code{argc}: Number of arguments specified with @option{-fplugin-arg-...}.
@item @code{argv}: Array of @code{argc} key-value pairs.
@end itemize

If initialization fails, @code{plugin_init} must return a non-zero
value.  Otherwise, it should return 0.

@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_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_EVENT_LAST             /* Dummy event used for indexing callback
                                   array.  */
@};
@end smallexample

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{plugin_callback_func callback}: The function that handles @code{event}.
@item @code{void *user_data}: Pointer to plugin-specific data.
@end itemize


@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 plugin_pass} 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 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.  */
@};


/* Sample plugin code that registers a new pass.  */
int
plugin_init (const char *plugin_name, int argc, struct plugin_argument *argv)
@{
  struct plugin_pass pass_info;

  ...

  /* Code to fill in the pass_info object with new pass information.  */

  ...

  /* Register the new pass.  */
  register_callback (plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &pass_info);

  ...
@}
@end smallexample
