public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* Creating builtins or using the inliner in a GCC plugin
@ 2016-09-07 20:03 Evgenii Shatokhin
  0 siblings, 0 replies; only message in thread
From: Evgenii Shatokhin @ 2016-09-07 20:03 UTC (permalink / raw)
  To: gcc-help

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

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2016-09-07 20:03 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-09-07 20:03 Creating builtins or using the inliner in a GCC plugin Evgenii Shatokhin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).