【问题标题】:How to add a builtin function in a GCC plugin?如何在 GCC 插件中添加内置函数?
【发布时间】:2017-01-09 18:43:50
【问题描述】:

GCC 插件可以添加新的内置函数吗?如果可以,如何正确操作?

GCC 版本为 5.3(或更新)。代码由C语言编写的插件编译处理。

rationale for GCC plugins at gcc-melt.org 中提到这是可行的,但我不知道如何。

据我在 GCC 的源代码中所见,内置函数是使用来自 gcc/langhooks.cadd_builtin_function() 创建的:

tree
add_builtin_function (const char *name,
      tree type,
      int function_code,
      enum built_in_class cl,
      const char *library_name,
      tree attrs)

除了function_code,函数的唯一数字ID之外,这个函数的参数应该具有哪些值或多或少是清楚的。

看起来(参见add_builtin_function_common()),应该有来自enum built_in_function 的值,但GCC 插件无法更改该枚举。

似乎也不能将任何大于END_BUILTINS 的随机值作为function_code 传递。在这种情况下,builtin_decl_implicit()builtin_decl_explicit() 的断言会失败。

那么,在 GCC 插件中添加内置函数的正确方法是什么(不使用 MELT 等,只使用 GCC 插件 API)?

更新 我再次查看了 C 的 add_builtin_function_common()langhooks.builtin_function() 的实现以及它们在 GCC 中的使用方式。在某些情况下,似乎 0 作为function_code 是可以接受的。此时不能使用builtin_decl_implicit(),但可以保存add_builtin_function()返回的DECL,以后再使用。

看起来我可以尝试以这种方式创建内置插件的唯一事件是 PLUGIN_START_UNIT(否则 GCC 可能会由于 external_scope 变量为 NULL 而崩溃)。

我在那个阶段尝试了以下操作(之前创建了fntype):

decl = add_builtin_function (
    "my_helper", fntype,
    0 /* function_code */,
    BUILT_IN_NORMAL /* enum built_in_class cl */,
    NULL /* library_name */,
    NULL_TREE /* attrs */)

my_helper 是在另一个 C 源文件中定义的,该文件已编译并与主源文件链接。然后我使用 decl 在我的 GIMPLE 传递期间将该函数的调用插入到其他函数 (gimple_build_call) 中。

GCC 输出没有错误,并且确实插入了对my_helper 的调用,但作为对普通函数的调用。我实际上需要一个内置函数来避免调用,而是插入函数体。

另一方面,tsan0 pass,在我的 pass 之后立即执行,插入了内置函数的调用,就像人们期望的那样:结果没有显式调用,只是插入了函数的主体。然而,它的内置函数是由 GCC 本身而不是插件定义的。

所以我想我的内置仍然需要一些东西才能成为有效的内置,但我不知道它是什么。那会是什么?

【问题讨论】:

  • 函数真的需要在 gcc 意义上是内置的吗?不能是普通函数吗?
  • 对于我实际尝试解决的问题(更详细地描述了here),它本身不必是内置的 GCC。我需要有一种方法可以将 C 函数的代码插入到另一个函数的代码中,而无需实际调用前者。内置和内联是显而易见的选择,但到目前为止我都没有运气。至于这个特殊的问题 - 是的,我只是对内置函数感到好奇。有人说可以通过 GCC 插件添加内置函数,但我不知道如何。
  • @Nisarg:我已经应用了您编辑的格式相关部分,谢谢。至于最后一句话——不,我不是想问你的建议。我现在已经替换它以使事情更清楚。
  • 你试过__attribute__((always_inline))吗?
  • 作为记录,我最终实现了一个从类似 C 的函数调用序列到 GIMPLE 序列的简单转换,作为此问题的部分解决方法。 GCC 插件在需要的地方插入这些 GIMPLE 序列。它不能“内联”对它插入的助手的调用,但目前对我来说已经足够了。详细信息为in this commit,请参阅对i13n/ 子目录的更改。对我有用,但当然,内置帮助器可能会更好。

标签: c gcc built-in gcc-plugins


【解决方案1】:

我假设您想要做的(从您的评论和链接的帖子中)是将 C 代码插入到函数中。在那种情况下,我会认为您不需要编写编译器插件。看看Boost.Preprocessor,它可以仅使用预处理器对 C 代码进行非常高级的操作。

【讨论】:

  • 我打算在内核代码中使用新的内置函数,所以它只适用于 C 语言。我对 Boost 有一些经验,宁愿在这里避免它。另一方面,GCC 插件已经被 Linux 内核支持了一段时间,可能会在这里使用。
  • 预处理器是一个只有头文件的库,它与 C 一起工作,不需要 C++。我看不出它不应该在内核中工作的任何原因。
  • 好吧,除非他们尝试,否则永远不会知道 ;-) 无论如何,正如我在 cmets 中对问题所说的那样,我已经准备了一种解决方法,并且在 2016 年需要时它工作正常。我只是想知道,也许有人可以指出在那里创建内置函数的正确方法。
猜你喜欢
  • 2011-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-21
  • 2012-05-28
  • 1970-01-01
相关资源
最近更新 更多