Search code examples
gccgimplegcc-plugins

How to register a GIMPLE_PASS?


I'm trying to do a simple plugin example like this:

#include "gcc-plugin.h"
#include "tree.h"
#include "gimple.h"
#include "tree-pass.h"
#include <stdio.h>

extern void
test(void*gcc_data, void*b) {
    printf("Hellow world\n");
}

extern int plugin_init (struct plugin_name_args *plugin_info,
                        struct plugin_gcc_version *version)
{
    const char * nombre = "Hello world";
    register_callback(nombre, GIMPLE_PASS, &test, NULL);

    return 0;
}

But GIMPLE_PASS is not a predefined event in gcc-plugin.h and I know I have to do something with PLUGIN_PASS_MANAGER_SETUP and struct pass_data in tree-pass.h, but I don't know exactly how and I didn't find any examples.

Somebody would show me how? iThanks.


Solution

  • I know you probably don't need this anymore but it can be useful for others, I have been working lately on this, and there is like 0 documentation about this ... All you can do is to find some example ( there is only few ) and try to understand what they are trying to do ( if it's well commented ), I am writing a plugin that kind of parse the gimple code, here is how my plugin_init

    int plugin_init (plugin_name_args* plugin_info,
                 plugin_gcc_version* ver)
    {
      // You can get the plugin name
      const char * const plugin_name = plugin_info->base_name;
      cerr << "starting ";
      // here you can get the plugin args and number of args, 
      // look at https://gcc.gnu.org/onlinedocs/gccint/Plugins-loading.html#Plugins-loading
      // for more information how to give your plugin some args
      const int argc = plugin_info->argc;   
      const struct plugin_argument * const argv = plugin_info->argv;
      struct register_pass_info calls_printer_info;
    
      // Here you say where you need to put your plugin, mine is called after ssa
      // This is my pass
      calls_printer_info.pass                         = new calls_printer_pass();
      calls_printer_info.reference_pass_name          = "ssa" ;
      calls_printer_info.ref_pass_instance_number     = 1;
      calls_printer_info.pos_op                       = PASS_POS_INSERT_AFTER;
      register_callback (plugin_name,
                         PLUGIN_PASS_MANAGER_SETUP,
                         NULL,
                         &calls_printer_info);
      return 0;
    }
    

    you need to create your pass before :

    static const struct pass_data calls_printer_pass_data = {
                    .type                   = GIMPLE_PASS,
                    .name                   = "calls_printer",
                    .optinfo_flags          = OPTGROUP_NONE,
                    .has_gate               = false,
                    .has_execute            = true,
                    .tv_id                  = TV_NONE,
                    .properties_required    = PROP_cfg,
                    .properties_provided    = 0,
                    .properties_destroyed   = 0,
                    .todo_flags_start       = 0,
                    .todo_flags_finish      = 0
    };
    
    class calls_printer_pass : public gimple_opt_pass {
    public:
            calls_printer_pass() : gimple_opt_pass(calls_printer_pass_data, g) {}
            // put the function you want to execute when the pass is executed
            unsigned int execute() { return my_function(); }
    };
    

    and don't forget this for the license :

    int plugin_is_GPL_compatible;