Может ли LTO для gcc или clang оптимизироваться в методах C и C++
1 ответ
Да!
Оптимизация времени соединения обычно работает с промежуточным представлением (IR), присутствующим в "толстых" объектных файлах, которые могут содержать как машинный код для традиционного связывания, так и IR для связывания LTO.
На данном этапе больше нет языковых конструкций высокого уровня, поэтому оптимизация времени соединения не зависит от языка.
НКУ
Оптимизация времени соединения (LTO) GCC работает на GIMPLE, одном из промежуточных представлений GCC. IR всегда не зависит от языка, поэтому любая оптимизация во время компоновки будет работать с кодом, сгенерированным из любого языка.
Из документации по параметрам оптимизации GCC:
Другой особенностью LTO является то, что можно применять межпроцедурную оптимизацию к файлам, написанным на разных языках:
gcc -c -flto foo.c g++ -c -flto bar.cc gfortran -c -flto baz.f90 g++ -o myprog -flto -O3 foo.o bar.o baz.o -lgfortran
Обратите внимание, что последняя ссылка выполняется с помощью g ++, чтобы получить библиотеки времени выполнения C++ и
-lgfortran
добавлен для получения библиотек времени исполнения Fortran. В общем случае при смешивании языков в режиме LTO следует использовать те же параметры команды ссылки, что и при смешивании языков в обычной (не LTO) компиляции.
Вот пример, чтобы показать вам, насколько мощна эта технология. Мы определим функцию C и вызовем ее из программы C++:
func.h
#ifndef FUNC_DOT_H
#define FUNC_DOT_H
#ifdef __cplusplus
extern "C" {
#endif
int func(int a, int b, int c);
#ifdef __cplusplus
}
#endif
#endif /* FUNC_DOT_H */
func.c
#include "func.h"
int func(int a, int b, int c)
{
return 3*a + 2*b + c;
}
main.cpp
#include "func.h"
int main()
{
int a = 1;
int b = 2;
int c = 3;
return func(a, b, c);
}
компилировать
gcc -o func.o -c -Wall -Werror -flto -O2 func.c
g++ -o main.o -c -Wall -Werror -flto -O2 main.cpp
g++ -o testlto -flto -O2 main.o func.o
Разбирать (objdump -Mintel -d -R -C testlto
)
Disassembly of section .text:
00000000004003d0 <main>:
4003d0: b8 0a 00 00 00 mov eax,0xa ; 1*3 + 2*2 + 3 = 10
4003d5: c3 ret
Вы можете видеть, что это не только встроенный мой C func()
в мой C++ main()
, но это превратило все это в постоянное выражение!
Clang / LLVM
Используя тот же синтаксис, Clang может генерировать "толстые" объектные файлы с LLVM IR, которые можно оптимизировать во время соединения. См. Оптимизация времени соединения LLVM.
Используя тот же тестовый код, что и выше, clang дает точно такой же результат:
00000000004004b0 <main>:
4004b0: b8 0a 00 00 00 mov eax,0xa
4004b5: c3 ret