2014-06-18 1 views
2

Я разрабатываю плагин GCC, который управляет скомпилированными приложениями. Приложения написаны на C и построены с GCC 4.7 (4.8 и 4.9 также являются опцией) в системе x86 Linux.Плагин GCC: аргументы функции копирования

Мой плагин реализует прогон компиляции, который помещается после стандартного прохода «ssa» и работает с представлением GIMPLE. Среди прочего, мне нужно реализовать следующее, но в настоящее время не могу понять, как это сделать правильно.

При обработке функции C мне нужно вставить код в начале, который копирует свои аргументы в локальные переменные, которые я создаю, для будущей обработки.

Моя первая наивная реализация выглядела следующим образом:

tree p; 
gimple_seq seq = NULL; 
gimple_stmt_iterator gsi = gsi_start_bb(single_succ(ENTRY_BLOCK_PTR)); 

for (p = DECL_ARGUMENTS(current_function_decl); p; p = DECL_CHAIN(param)) { 
    tree copy_par; 
    copy_par = create_tmp_var(TREE_TYPE(p), NULL); 
    add_referenced_var(copy_par); 
    copy_par = make_ssa_name(copy_par, NULL); 
    g = gimple_build_assign(copy_par, p); 
    SSA_NAME_DEF_STMT(copy_par) = g; 
    gimple_seq_add_stmt_without_update (&seq, g); 
    ... // more processing here 
} 
... 
gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT); 

Таким образом, однако, недействителен присвоение объявлении параметра переменной создается в соответствии с отвала:

 
gimple_assign <parm_decl, D.2206_11, par, NULL> 

D.2206_11 СООТВЕТСТВУЕТ к локальной переменной, которую я создал, par - аргумент функции, которую я хочу скопировать.

В результате сбоя GCC в какой-то последующий проход пытается обработать это добавленное заявление. Я полагаю, это связано с тем, что p не переменная, удерживающая значение соответствующего аргумента, но декларация этой переменной. Так ли это? И как получить эту переменную?

Я пробовал использовать gimple_build_assign_with_ops(NOP_EXPR, copy_par, p, NULL_TREE) вместо gimple_build_assign(), но он этого не сделал. GCC все еще падает в одном месте. Я могу предоставить backtrace, но я чувствую, что просто теряю что-то фундаментальное.

Я также рассмотрел обход деревьев, начиная с TYPE_ARG_TYPES (TREE_TYPE (current_function_decl)) и далее через TREE_CHAIN(...), но это, кажется, дает типы аргументов, а не соответствующие переменные.

Итак, вопрос заключается в том, как правильно выполнить копирование аргументов функции.

Примечание Возможно, это может быть сделано с помощью талой или GCC Python плагин, но в этом проекте, я должен выполнить все преобразования кода, используя только то, что само по себе обеспечивает НКУ.

ответ

2

Я обнаружил, что копирование аргументов работает с GCC 4.8 и 4.9, но не с 4.7. Here is the code, который работает для меня сейчас (instrument_fentry() выполняет копирование).

Чтобы избежать копирования копий на последующих сетах, я сделал соответствующие переменные неустойчивыми.

Кроме того, если не было SSA_NAME с оператором определения по умолчанию, заданным для данного параметра (см. SSA_NAME_IS_DEFAULT_DEF()), я добавил такие SSA_NAME с GIMPLE_NOP в качестве определяющих операторов.

До сих пор это работало нормально с GCC 4.8 и 4.9, поэтому оно выглядит как ошибка в GCC 4.7 или некоторая смена правил между GCC 4.7 и 4.8. Хотя я не мог точно определить точную фиксацию.

+0

'get_or_create_ssa_default_def'? –

+0

@MarcGlisse: Вы имеете в виду использование 'get_or_create_ssa_default_def' вместо того, чтобы вручную вставлять GIMPLE_NOP? Да, может быть. Сохраняет некоторую типизацию. – Eugene