65

GCC 插件可以添加新的内置函数吗?如果是这样,如何正确地做到这一点?

GCC 版本是 5.3(或更新)。代码由用 C 编写的插件编译和处理。

在 gcc-melt.org 的 GCC 插件的基本原理中提到这是可行的,但我看不出如何。

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

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_codebuiltin_decl_implicit()builtin_decl_explicit()

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

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

看起来我可以尝试以这种方式创建内置插件的唯一事件是 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 源文件中定义。gimple_build_call然后我使用 decl在我的 GIMPLE 传递期间将该函数的调用插入到其他函数 ( ) 中。

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

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

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

4

1 回答 1

1

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

于 2020-07-29T11:51:42.990 回答