Получить количество функций файла C++, скомпилированных с помощью плагина gcc
Я создаю проход, используя плагины GCC, это мой проход:
static const struct pass_data calls_printer_pass_data = {
.type = GIMPLE_PASS,
.name = "calls_printer",
.optinfo_flags = OPTGROUP_NONE,
.has_gate = false,
.has_execute = true,
.tv_id = TV_NONE,
.properties_required = 0,
.properties_provided = 0,
.properties_destroyed = 0,
.todo_flags_start = 0,
.todo_flags_finish = 0
};
class calls_printer_pass : public gimple_opt_pass {
public:
calls_printer_pass() : gimple_opt_pass(calls_printer_pass_data, g) {}
unsigned int execute() { return toto(); }
};
int plugin_init (plugin_name_args* plugin_info,
plugin_gcc_version* ver)
{
cerr << "starting " << plugin_info->base_name << endl;
const char * const plugin_name = plugin_info->base_name;
const int argc = plugin_info->argc;
const struct plugin_argument * const argv = plugin_info->argv;
struct register_pass_info calls_printer_info;
calls_printer_info.pass = new calls_printer_pass();
calls_printer_info.reference_pass_name = "ssa" ;
calls_printer_info.ref_pass_instance_number = 1;
calls_printer_info.pos_op = PASS_POS_INSERT_AFTER;
register_callback (plugin_name,
PLUGIN_PASS_MANAGER_SETUP,
NULL,
&calls_printer_info);
return 0;
}
Так что toto() выполняется для каждой определенной функции, возможно ли получить количество всех функций при выполнении toto()
если нет, как я могу выполнить передачу только один раз для всего файла и выполнить цикл через все функции, используя FOR_EACH_FUNCTION()?
2 ответа
int toto_cnt = 0;
int toto (void)
{
struct cgraph_node *node;
if (!toto_cnt)
{
FOR_EACH_FUNCTION (node)
{
toto_cnt++;
}
}
}
class calls_printer_pass : public gimple_opt_pass {
public:
calls_printer_pass() : gimple_opt_pass (calls_printer_pass_data, g) {}
unsigned int execute() { return toto(); }
};
void execute_finish_unit (void *gcc_data, void *user_data)
{
printf ("%d\n", toto_cnt);
}
int plugin_init (plugin_name_args* plugin_info,
plugin_gcc_version* ver)
{
printf ("starting %s\n", plugin_info->base_name);
const char * const plugin_name = plugin_info->base_name;
const int argc = plugin_info->argc;
const struct plugin_argument * const argv = plugin_info->argv;
struct register_pass_info calls_printer_info;
calls_printer_info.pass = new calls_printer_pass();
calls_printer_info.reference_pass_name = "ssa" ;
calls_printer_info.ref_pass_instance_number = 1;
calls_printer_info.pos_op = PASS_POS_INSERT_AFTER;
register_callback (plugin_name,
PLUGIN_PASS_MANAGER_SETUP,
NULL,
&calls_printer_info);
register_callback (plugin_name, PLUGIN_FINISH_UNIT, &execute_finish_unit, NULL);
return 0;
}
Вы можете получить желаемый эффект, написав пропуск "IPA". Это "межпроцедурные" проходы, и они имеют доступ к графу вызовов (и пулу переменных).