Сопоставить идентификаторы из файлов, сгенерированных g ++, с параметрами -fstack-use и -fdump-rtl-expand - PullRequest
0 голосов
/ 15 апреля 2019

Введение

Я пытаюсь сделать статическую оценку максимально возможного использования стека во встроенной программе. Мне удалось получить использование стека каждой отдельной функции с помощью опции GCC -fstack-usage, и я построил дерево всех вызовов функций, анализируя RTL, полученный с помощью опции -fdump-rtl-expand.

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

Проблема

Так в чем именно проблема?

Короче говоря, идентификаторы функций, сгенерированные GCC для двух файлов, различны. RTL использует как искаженные идентификаторы, так и понятные человеку имена. Последние похожи на те, которые вы можете увидеть в исходном коде. Файл использования стека имеет только удобочитаемые имена, но они записаны в какой-то странной записи, которая полностью отличается от записи в файле RTL.

Давайте рассмотрим пример.

Исходный файл test.cpp:

void test() {}

Команда (набор инструментов: GCC v8.2.0):

g++ -c test.cpp -fdump-rtl-expand -fstack-usage

RTL-файл ./test.cpp.234r.expand:

;; Function test (_Z4testv, funcdef_no=0, decl_uid=2358, cgraph_uid=0, symbol_order=0)


;; Generating RTL for gimple basic block 2


try_optimize_cfg iteration 1

Merging block 3 into block 2...
Merged blocks 2 and 3.
Merged 2 and 3 without moving.
Merging block 4 into block 2...
Merged blocks 2 and 4.
Merged 2 and 4 without moving.


try_optimize_cfg iteration 2



;;
;; Full RTL generated for this function:
;;
(note 1 0 3 NOTE_INSN_DELETED)
(note 3 1 2 2 [bb 2] NOTE_INSN_BASIC_BLOCK)
(note 2 3 7 2 NOTE_INSN_FUNCTION_BEG)
(insn 7 2 0 2 (const_int 0 [0]) "test.cpp":1 -1
     (nil))

Файл использования стека test.su:

test.cpp:1:6:void test()        16      static

Таким образом, функция называется test и _Z4testv в файле RTL и void test() в файле использования стека.

Еще сложнее сказать, какие функции одинаковы, когда мы получаем реальный пример из моего кода. Имена будут тогда (по порядку):

devices::Button<virtualIo::Port_<utils::type::list::List<virtualIo::IndexedPin_<0, virtualIo::PortD, 7, true> >, 1, unsigned char, utils::type::list::List<virtualIo::PortShifter_<virtualIo::PortD, unsigned char, unsigned char, false, 128, 1, utils::type::list::List<virtualIo::PartShifter_<unsigned char, unsigned char, 1, 7, 128> > > >, true>, true>::isUp

_ZNK7devices6ButtonIN9virtualIo5Port_IN5utils4type4list4ListIJNS1_11IndexedPin_ILh0ENS1_5PortDELh7ELb1EEEEEELh1EhNS6_IJNS1_12PortShifter_IS8_hhLb0ELh128ELh1ENS6_IJNS1_12PartShifter_IhhLh1ELa7ELh128EEEEEEEEEEELb1EEELb1ELb0EE4isUpEv

bool devices::Button<PORT, POSITIVE_INPUT, PULL_UP>::isUp() const [with PORT = virtualIo::Port_<utils::type::list::List<virtualIo::IndexedPin_<0, virtualIo::PortD, 7, true> >, 1, unsigned char, utils::type::list::List<virtualIo::PortShifter_<virtualIo::PortD, unsigned char, unsigned char, false, 128, 1, utils::type::list::List<virtualIo::PartShifter_<unsigned char, unsigned char, 1, 7, 128> > > >, true>; bool POSITIVE_INPUT = true; bool PULL_UP = false]

Решение о том, что это та же функция, едва ли выполнимо человеком, и я понятия не имею, как это сделать с помощью скрипта / программы.

Предложения по решению

Идеальным решением было бы иметь искаженные имена в файле использования стека. Они единообразны и недвусмысленны (за исключением незначительных неудобств с конструкторами и деструкторами).

Я приму любой способ, позволяющий надежно сопоставлять имена из одного файла с другим.

В крайнем случае я буду вынужден сопоставлять функции по их порядку, который в обоих файлах одинаков. Однако я очень не решаюсь делать это предположение.

GCC версия

Убедитесь, что для этого используется версия 8 GCC. Похоже, что версия 7 генерирует имена по-другому. Я тестировал версии 8.2.0 и 8.3.0. Оба имеют описанное поведение.

Я не могу использовать версию 7. В ней есть какая-то ошибка, препятствующая компиляции моего кода.


Редактировать

Дополнительные примеры

Исходный файл test.cpp:

template<typename T> long some_name(int); template<> long some_name<int>(int) { return 0; }

Первая строка файла RTL ./test.cpp.234r.expand:

;; Function some_name<int> (_Z9some_nameIiEli, funcdef_no=0, decl_uid=2364, cgraph_uid=0, symbol_order=0)

Файл использования стека test.su:

test.cpp:5:6:long int some_name(int) [with T = int] 16  static

Edit2

Эксперименты показали, что читаемые человеком идентификаторы из файлов RTL не являются уникальными. Они одинаковы для перегруженных функций.

...