title: How to add a builtin function in a GCC plugin?
body: <p>It is possible for a GCC plugin to add a new builtin function? If so, how to do it properly?</p>
  <p>GCC version is 5.3 (or newer). The code is compiled and processed by the plugin written in C.</p>
  <p>It is mentioned in the <a href="http://starynkevitch.net/Basile/gcc-melt/" rel="noreferrer">rationale for GCC plugins at gcc-melt.org</a> that this is doable but I cannot see how.</p>
  <p>As far as I can see in the sources of GCC, the builtins are created using <code>add_builtin_function()</code> from <a href="https://github.com/gcc-mirror/gcc/blob/gcc-5-branch/gcc/langhooks.c#L605" rel="noreferrer">gcc/langhooks.c</a>:</p>
  <pre><code>tree
  add_builtin_function (const char *name,
        tree type,
        int function_code,
        enum built_in_class cl,
        const char *library_name,
        tree attrs)
  </code></pre>
  <p>It is more or less clear which values the arguments of this function should have, except for <code>function_code</code>, a unique numeric ID of the function.</p>
  <p>Looks like (see <code>add_builtin_function_common()</code>), a value from <code>enum built_in_function</code> is expected there but a GCC plugin cannot change that enum.</p>
  <p>One cannot pass any random value greater than <code>END_BUILTINS</code> as <code>function_code</code> either, it seems. <code>builtin_decl_implicit()</code> and <code>builtin_decl_explicit()</code> would have a failed assertion in that case.</p>
  <p>So, what is the proper way to add a builtin in a GCC plugin (without using MELT and such, just GCC plugin API)?</p>
  <p><strong>Update</strong>
  I looked again at the implementation of <code>add_builtin_function_common()</code> and of <code>langhooks.builtin_function()</code> for C as well as at how these are used in GCC. It seems that 0 is acceptable as <code>function_code</code> in some cases. You cannot use <code>builtin_decl_implicit()</code> then but you can save the DECL returned by <code>add_builtin_function()</code> and use it later.</p>
  <p>Looks like the only event when I can try to create built-ins that way is PLUGIN_START_UNIT (otherwise GCC may crash due to <code>external_scope</code> variable being NULL).</p>
  <p>I tried the following at that stage (<code>fntype</code> was created before):</p>
  <pre><code>decl = add_builtin_function (
      &quot;my_helper&quot;, fntype,
      0 /* function_code */,
      BUILT_IN_NORMAL /* enum built_in_class cl */,
      NULL /* library_name */,
      NULL_TREE /* attrs */)
  </code></pre>
  <p><code>my_helper</code> was defined in a different C source file compiled and linked with the main source file. Then I used decl to insert the calls to that function into other functions (<code>gimple_build_call</code>) during my GIMPLE pass.</p>
  <p>GCC output no errors and indeed inserted the call to <code>my_helper</code> but as a call to an ordinary function. I actually needed a builtin to avoid a call but rather insert the body of the function.</p>
  <p>On the other hand, <code>tsan0</code> pass, which executes right after my pass, inserts the calls of builtin functions just like one would expect: there is no explicit call as a result, just the body of the function is inserted. Its builtins, however, are defined by GCC itself rather than by the plugins.</p>
  <p>So I suppose my builtin still needs something to be a valid builtin, but I do not know what it is. What could that be?</p>