(Могу ли я получить Clang или, возможно, какой-нибудь другой оптимизирующий инструмент, поставляемый с LLVM, чтобы идентифицировать неиспользуемые виртуальные функции в программе на C ++, чтобы пометить их для удаления мертвого кода?
Если в LLVM нет такой функциональности, как можно реализовать такую вещь? Какой слой лучше всего подходит для этого, и где я могу найти примеры, на которых я мог бы это построить?
Моей первой мыслью был оптимизатор, работающий с LLVM или IR. В конце концов, для этого представления написано много оптимизаторов. Простое удаление мертвого кода достаточно просто: любая функция, которая не вызывается и не получает адрес, где-то хранится, является мертвым кодом и может быть исключена из окончательного двоичного кода. Но адрес виртуальной функции берется и сохраняется в таблице виртуальных функций соответствующего класса. Чтобы определить, есть ли у этой функции возможность вызова, оптимизатор должен не только идентифицировать все вызовы виртуальных функций, но и определить иерархию типов для сопоставления этих вызовов виртуальных функций со всеми возможными реализациями.
Это делает вещи довольно сложными для решения на уровне битового кода. Возможно, было бы лучше обрабатывать это где-то ближе к интерфейсу, на этапе, когда доступно больше информации о типах и где вызовы виртуальной функции могут быть более легко связаны с реализациями этих функций. Возможно, VirtualCallChecker может служить отправной точкой.
Вероятно, одной из проблем является тот факт, что хотя можно оптимизировать битовый код нескольких объектов в одном модуле для оптимизации времени соединения, вряд ли когда-либо скомпилируется весь исходный код проекта среднего размера в виде одного модуля преобразования. Таким образом, связь между вызовами виртуальных функций и реализациями, возможно, придется каким-то образом поддерживать до этой стадии. Я не знаю, возможна ли какая-либо особая аннотация с LLVM; Я не видел никаких признаков этого в спецификация языка.
Но в любом случае у меня есть небольшая проблема со спецификацией языка. Единственная ссылка на virtual
там есть virtuality
а также virtualIndex
свойства MDSubprogram, но до сих пор я не нашел никакой информации об их семантике. Никакой документации или полезных мест внутри исходного кода LLVM. Возможно, я смотрю не ту документацию для моего варианта использования.
устранить неиспользуемые виртуальные функции спросил примерно то же самое в контексте GCC, но я специально ищу здесь решение LLVM. Раньше был -fvtable-gc
переключитесь на GCC, но, видимо, он был слишком глючным и получил наказание, и Clang также не поддерживает его.
struct foo {
virtual ~foo() { }
virtual int a() { return 12345001; }
virtual int b() { return 12345002; }
};
struct bar : public foo {
virtual ~bar() { }
virtual int a() { return 12345003; }
virtual int b() { return 12345004; }
};
int main(int argc, char** argv) {
foo* p = (argc & 1 ? new foo() : new bar());
int res = p->a();
delete p;
return res;
};
Как я могу написать инструмент для автоматического избавления от foo::b()
а также bar::b()
в сгенерированном коде?
clang++ -fuse-ld=gold -O3 -flto
с Clang 3.5.1 было недостаточно, как objdump -d -C
из получившегося исполняемого файла показал.
Первоначально я спрашивал не только о том, как использовать clang или LLVM для этого, но, возможно, о том, чтобы сторонние инструменты могли добиться того же результата, если clang и LLVM не справляются с этой задачей. Тем не менее, вопросы, касающиеся инструментов, здесь не одобряются, поэтому к настоящему времени акцент сместился с поиска инструмента на его написание. Я предполагаю, что шансы найти его в любом случае невелики, так как поиск в Интернете не выявил намеков в этом направлении.
Задача ещё не решена.