Ответ 1
Если вы посмотрите на документацию gcc, вы найдете:
-flto [= п]
Эта опция запускает стандартный оптимизатор ссылок времени. При вызове с исходным кодом он генерирует GIMPLE (одно из внутренних представлений GCC) и записывает его в специальные секции ELF в объектном файле. Когда объектные файлы связаны друг с другом, все тела функций считываются из этих разделов ELF и создаются так, как если бы они были частью одной и той же единицы перевода.
Чтобы использовать оптимизатор времени ссылки, параметры -flto и оптимизации следует указывать во время компиляции и во время финальной ссылки. Например:
gcc -c -O2 -flto foo.c
gcc -c -O2 -flto bar.c
gcc -o myprog -flto -O2 foo.o bar.o
Первые два вызова в GCC сохраняют представление байт-кода GIMPLE в специальные секции ELF внутри foo.o и bar.o. Окончательный вызов читает байт-код GIMPLE из foo.o и bar.o, объединяет два файла в одно внутреннее изображение и компилирует результат, как обычно. Поскольку foo.o и bar.o объединены в одно изображение, , это заставляет все межпроцедурные анализы и оптимизации в GCC работать в двух файлах, как если бы они были одним. Это означает, например, что inliner может встроить функции в bar.o в функции в foo.o и наоборот.
Как говорится в документации, да, все! Оптимизация - это то, что программа скомпилирована в одном файле. Это также можно сделать с помощью -fwhole-program
, чтобы получить "тот же" результат оптимизации.
Если вы скомпилируете этот очень простой пример:
f1.cpp:
int f1() { return 10; }
f2.cpp:
int f2(int i) { return 2*i; }
main.cpp:
int main()
{
int res=f1();
res=f2(res);
res++;
return res;
}
Я получил выход ассемблера:
00000000004005e0 <main>:
4005e0: b8 15 00 00 00 mov $0x15,%eax
4005e5: c3 retq
4005e6: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
4005ed: 00 00 00
Весь код встроен, как ожидалось.
Мой опыт в том, что фактический gcc оптимизируется с lto точно так же, как и скомпилирован в один файл. В очень редких условиях я получил ICE при использовании lto. Но с фактической версией 5.2.0 я больше не видел ICE.
[ICE] → Внутренняя ошибка компилятора