This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Creating builtins or using the inliner in a GCC plugin


Hi,

I wonder if a GCC plugin (GCC 5.3 or newer) can create its own builtins or "emulate" builtins with the help of the inliner (after IPA passes). Any suggestions are appreciated.

Now, here is the long story.
My GCC plugin should instrument the calls to some functions, namely add some code before and may be after the call. The code to be compiled is written in C, if that matters.

For example,

    obj = calloc(num, sz);

should become something like this after the instrumentation:

    __size = num * sz;
    __do_something(__size);
    obj = calloc(num, sz);

__do_something() is a function defined elsewhere, __size is a local variable added by the plugin. The plugin adds a GIMPLE pass to do the instrumentation.

In this simple case, I can, of course, add the necessary GIMPLE statements explicitly to implement "__size = num * sz", and that would be fine. However, when it is not only "calloc()" but rather dozens of functions that should be instrumented, and each of these needs different statements before it, things get tedious and error-prone.

It would help if I could somehow write the helpers in C, for example:

  static size_t helper_calloc(size_t nmemb, size_t size)
  {
    return nmemb * size;
  }

It could be defined, say, in a header file specified in "-include" compiler option.

Then I could instrument that call to calloc() as follows (everything is actually done at GIMPLE level but the examples are in C for clarity):

  __size = helper_calloc(num, sz);
  __do_something(__size);
  obj = calloc(num, sz);

After that, I'd like to let GCC know somehow that helper_calloc() should be inlined there. This is where I am stuck now.

Creating a custom builtin function could probably help but it seems, a GCC plugin cannot create new builtins. At least, with add_builtin_function() from gcc/langhooks.c. add_builtin_function() needs a unique numeric ID of the function, "function_code", from enum built_in_function. A GCC plugin cannot add new values to this enum.

I went a different way and invoked the inliner explicitly in my GIMPLE pass to inline the call to helper_calloc() and such:

  ...
  unsigned int todo = early_inliner(cfun);
  ...

This did not work first because my GIMPLE pass needs to be executed way after the IPA passes. And during the IPA, the compiler finds helper_calloc(), which is unused at that moment, and removes it. So the inliner considers "helper_calloc(num, sz)" as a call to an external function and cannot inline it, of course.

I added "__attribute__((__used__))" for helper_calloc() and now the function was available to my GIMPLE pass, the inlining went fine. But! As the function was marked as "__used__", the compiler placed it in the object file. This is logical but less than ideal in my case because this function itself will no longer be used and will only bloat the object file.

Perhaps, there is a better way to add such function calls in a plugin, either as the calls to builtins or inlines?

Any suggestions?

Regards,
Evgenii


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]