Как добавить встроенную функцию в плагин GCC?
Возможно ли для плагина GCC добавить новую встроенную функцию? Если так, как это сделать правильно?
Версия GCC 5.3 (или новее). Код, который компилируется и обрабатывается плагином, написан на C.
В обосновании плагинов GCC на gcc-melt.org упоминается, что это выполнимо, но я не вижу, как это сделать.
Насколько я вижу в источниках 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
, уникальный числовой идентификатор функции.
Похоже (см. add_builtin_function_common()
), значение от enum built_in_function
ожидается там, но плагин GCC не может изменить это перечисление.
Нельзя передать любое случайное значение больше END_BUILTINS
как function_code
либо, похоже. builtin_decl_implicit()
а также builtin_decl_explicit()
будет иметь ошибочное утверждение в этом случае.
Итак, как правильно добавить встроенный модуль в плагин GCC (без использования MELT и т. Д., Только API плагинов GCC)?
Обновление я снова посмотрел на реализацию add_builtin_function_common()
и из langhooks.builtin_function()
для C, а также на то, как они используются в GCC. Кажется, что 0 приемлемо как function_code
в некоторых случаях. Вы не можете использовать builtin_decl_implicit()
тогда, но вы можете сохранить DECL, возвращенный add_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, скомпилированном и связанном с основным исходным файлом. Затем я использовал decl для вставки вызовов этой функции в другие функции (gimple_build_call
) во время моего прохода GIMPLE.
GCC не выдает ошибок и действительно вставил вызов my_helper
но как вызов обычной функции. Я действительно нуждался в встроенной функции, чтобы избежать вызова, а вместо этого вставить тело функции.
С другой стороны, tsan0
pass, который выполняется сразу после моего pass, вставляет вызовы встроенных функций, как и следовало ожидать: в результате явного вызова нет, просто вставляется тело функции. Однако его встроенные функции определяются самим GCC, а не подключаемыми модулями.
Так что я полагаю, что моему встроенному все еще нужно что-то, чтобы быть действительным встроенным, но я не знаю, что это такое. Что бы это могло быть?
0 ответов
Я предполагаю, что вы хотите (из вашего комментария и связанного сообщения) вставить код C в функцию. В этом случае я бы подумал, что вам не нужно заходить так далеко, чтобы писать плагин компилятора. Взгляните на Boost.Preprocessor, который может выполнять очень сложные манипуляции с кодом C, используя только препроцессор.