Может ли LTO для gcc или clang оптимизироваться в методах C и C ++

Если оптимизация времени соединения (LTO) используется с НКУ или же лязг, Возможно ли, что код может быть оптимизирован через границы языка C и C ++?

Например, может ли функция C быть встроена в C ++?

7

Решение

Да!

Оптимизация времени соединения обычно работает с промежуточным представлением (IR), присутствующим в «толстых» объектных файлах, которые могут содержать как машинный код для традиционного связывания, так и IR для связывания LTO.

На данном этапе больше нет языковых конструкций высокого уровня, поэтому оптимизация времени соединения не зависит от языка.


ССЗ оптимизация времени соединения (LTO) работает над 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 IR, которые можно оптимизировать во время соединения. Увидеть LLVM Link Time Optimization.

Используя тот же тестовый код, что и выше, clang дает точно такой же результат:

00000000004004b0 <main>:
4004b0:   b8 0a 00 00 00          mov    eax,0xa
4004b5:   c3                      ret
8

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]