LINUX.ORG.RU

LTO не работает

 , , , ,


1

5

Когда компилирую программу с -flto, в конце, во время линкования ошибка:

lto1: internal error: in add_symbol_to_partition_1, at lto/lto-partition.c:153
Пытаюсь поменять на gold, но и тут засада, пишет во время конфигурации meson:
-----
Sanity check compile stderr:
/usr/bin/ld.gold: error: cannot find -lugin
/usr/bin/ld.gold: error: cannot find -lugin-opt=/usr/lib/gcc/i686-linux-gnu/9/lto-wrapper
/usr/bin/ld.gold: error: cannot find -lugin-opt=-fresolution=/tmp/ccZU7VQK.res
/usr/bin/ld.gold: error: cannot find -lugin-opt=-pass-through=-lgcc
/usr/bin/ld.gold: error: cannot find -lugin-opt=-pass-through=-lgcc_s
/usr/bin/ld.gold: error: cannot find -lugin-opt=-pass-through=-lc
/usr/bin/ld.gold: error: cannot find -lugin-opt=-pass-through=-lgcc
/usr/bin/ld.gold: error: cannot find -lugin-opt=-pass-through=-lgcc_s
collect2: error: ld returned 1 exit status

-----

Compiler cc can not compile programs.

Кто меня проклял? Как включить эту парашу под названием LTO?

Meson: 0.52.0

Gcc: 9

Ld (и gold и bfd): 2.30

Ответ на: комментарий от xaizek

Так они же исправили этот баг ещё в Gcc 8.1, какого чёрта она опять вылезла? Что за плагин? Может быть эта ошибка от неправильной сборки (я пересобирал binutils)? Может ли не подходить версия 2.30 к gcc 9?

gradle ()
Ответ на: комментарий от gradle

Так они же исправили этот баг ещё в Gcc 8.1, какого чёрта она опять вылезла?

Я нашёл несколько похожих багов, но с разными номерами строк. Этот может быть другим (в ОП нету самого ассерта). А может исправили не до конца.

Что за плагин?

Плагин для линкера. При LTO объектные файлы содержат дампы translation unit и сам линкер с таким работать не умеет, поэтому компилятор предоставляет ему плагин.

Может быть эта ошибка от неправильной сборки (я пересобирал binutils)? Может ли не подходить версия 2.30 к gcc 9?

Не думаю, что это имеет значение. Это всё же ошибка не вызова утилиты, а работы части компилятора (LTO-плагина).

Ответьте хотя бы почему gold не хочет запускаться

-lugin
-lugin-opt

Должно быть --plugin и --plugin-opt. Возможно, что модный и молодёжный meson тупо вырезал вхождения -p какого-то хрена.

xaizek ★★★★★ ()
Последнее исправление: xaizek (всего исправлений: 1)
Ответ на: комментарий от gradle

Не знаю. Да и вообще ld.gold должен вызываться самим gcc, т.е. meson не должен был повлиять. Тем более, если раньше работало. Это какая-то странная ошибка после обновления.

Хотел предложить воспользоваться аналогом strace для дерева процессов, что может показать кто и что запускает, но не получилось вспомнить название… Как бы не на ЛОРе в новостях оно было.

xaizek ★★★★★ ()
Ответ на: комментарий от gradle

А я утилиту вспомнил. forkstat, называется (исходники). Запускать от рута так:

forkstat -gx

Потом выполнить попытку сборки и завершить forkstat по Ctrl-C. Может что полезное и покажет.

xaizek ★★★★★ ()

Кстати, ведь правильно понимаю, что когда в с++ приедут модули (ещё и std на них запилят), то компилятор/линкер сможет оптимизировать сpp+код_из_модулей как одно целое (ну и lto в таком случае как бы и не нужна)?

pavlick ★★ ()
Ответ на: комментарий от pavlick

Думаю, что неправильно. Модули кешируют в основном интерфейс. Там может быть что-то ещё, что не публично, но основная масса кода не попадёт в бинарный файл модуля, если это не header-only.

А если бы попадало, то компиляция бы сильно замедлилась. При этом место для LTO осталось бы, так как оно оптимизирует всё единицы трансляции вместе, а не по отдельности.

xaizek ★★★★★ ()
Ответ на: комментарий от xaizek

Дело в том, что как-то тестил модули на clang, сделал модуль с функцией, в цпп вызывал в цикле. В итоге функция из модуля заинлайнилась, т.е. оптимизатор поработал. С другой стороны, никакой официальной инфы нет, никто на оптимизации+модули акцент не делает. Может у шланга оно так случайно получилось и это вообще необязательно )). Думаю, что это нужно прям сейчас на уровне стандарта обязать компиляторы оптимизировать сквозь модули.

pavlick ★★ ()
Ответ на: комментарий от pavlick

модули на clang

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

xaizek ★★★★★ ()
Ответ на: комментарий от xaizek

Ну я уже не очень помню, но пробовал модули примерно так (пример из стековерфлоу, помню его):

// file: foo.cppm
export module M;
export int f(int x){
    return 2 + x;
}
export double g(double y, int z){
    return y * z;
}

// file: bar.cpp
import M;
int main(){
    f(5);
    g(0.0, 1);
    return 0;
}

$ clang++ -fmodules-ts --precompile foo.cppm -o M.pcm
$ clang++ -fmodules-ts -c M.pcm -o M.o
$ clang++ -fmodules-ts -fprebuilt-module-path=. M.o bar.cpp


А про LTO помню читал (то ли автора плагина, то ли ещё кого), что мол на некоторых проектах ускорение, а на некоторых даже замедление имеется. В общем плюнул разбираться дальше.

pavlick ★★ ()
Ответ на: комментарий от pavlick

Это принятые модули и полностью определённые в одном файле, тут компилятор всё видит (кажется, можно сделать секцию, чтобы видел не всё).

LTO может замедлять, если из-за встраивания код сильно раздувается. Т.е. дело не в самом LTO, модули это никак не решат.

xaizek ★★★★★ ()
Ответ на: комментарий от xaizek

cd папка_исходников_binutils

mkdir -v build

cd build

../configure –prefix=/usr –enable-gold –enable-ld=default –enable-plugins –enable-shared –disable-werror –enable-64-bit-bfd –with-system-zlib

make tooldir=/usr

make -k check

make tooldir=/usr install

Файлы устанавливаются в /usr/i386-pc-linux-gnu, нужно вручную вырезать их оттуда и вставить в /usr/bin и /usr/lib/i386-linux-gnu, под рутом. Ещё можно сделать симлинк для удобства:

ln -s /usr/bin/ld.bfd /usr/bin/bfd ln -s /usr/bin/ld.gold /usr/bin/gold

gradle ()