Позволяет ли передача нескольких файлов в компилятор C / C ++ для межпроцедурной оптимизации? - PullRequest
0 голосов
/ 28 февраля 2019

Допустим, у меня есть foo.cpp со следующим содержимым

int foo() {
  return 123;
}

и main.cpp, в котором я использую foo:

int main() {
  int r = foo();
  return r;
}

Я могу скомпилировать оба исходных файла вобъектный код, а затем связать их, используя оптимизацию времени соединения, чтобы сделать foo() вызов встроенным в main().

Но можно ли добиться того же эффекта, перечислив оба файла в командной строке компилятора, например c++ foo.cpp main.cpp?Или это просто сводится к

foreach(file in files)
  UsualCompilingRoutinesForSingleFile(file)

?

Если да, почему компилятору не разрешено объединять все файлы, переданные в один, для достижения своего рода LTO?

Ответы [ 2 ]

0 голосов
/ 28 февраля 2019

Если да, то почему компилятору не разрешено объединять все файлы, переданные в один, для достижения своего рода LTO?

Компилятор разрешен и может "видеть"все файлы в одно и то же время для выполнения LTO.Но это действительно не то же самое, что иметь один исходный файл.

Из документации gcc (только в качестве примера, другие компиляторы поддерживают подобную технологию):

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

Как вы можете видеть, результатом будетТо же самое, что было бы, если вы представляете все файлы одновременно компилятору, но без проблем упорядочиваете все включенные заголовки / источники в «правильном» порядке.

Для получения дополнительной информации от gcc относительно времени ссылкиУровни и методы оптимизации: https://gcc.gnu.org/onlinedocs/gccint/LTO-Overview.html

0 голосов
/ 28 февраля 2019

Конкатенация файлов не одинакова из-за локальных / статических объектов.У вас могут быть конфликты (подумайте о безымянных пространствах имен).Например, первый файл использует локальную функцию foo, которая что-то ищет в статической карте, а затем второй файл имеет другую локальную функцию foo, которая ищет в хэш-карте (по любой причине, и да, я согласен, чтоэто также плохой дизайн).

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

В вашем примерекомпилятор компилирует оба файла и связывает их вместе, это не LTO, а нечто иное (не только создание объектных файлов, но и своего рода AST, который можно объединить с другими и затем оптимизировать).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...