Ответ 1
ОБНОВЛЕНИЕ: см. комментарий @PeterCordes ниже. По сути, -fuse-linker-plugin больше не нужен.
Эти различия неуловимы. Во-первых, поймите, что на самом деле делает -flto. По сути, он создает выходные данные, которые могут быть оптимизированы позже (во время соединения).
То, что делает -fwhole-program, предполагает ", что текущий модуль компиляции представляет всю компилируемую программу", независимо от того, так ли это на самом деле. Следовательно, GCC будет предполагать, что ему известны все места, которые вызывают определенную функцию. Как говорится, он может использовать более агрессивные межпроцедурные оптимизаторы. Я объясню это немного позже.
Наконец, то, что делает -fuse-linker-plugin, на самом деле выполняет оптимизацию во время соединения, которая обычно выполняется при выполнении каждого модуля компиляции. Таким образом, он предназначен для сопряжения с -flto, поскольку -flto означает сохранение достаточного количества информации для последующей оптимизации, а -fuse-linker-plugin означает, что эта оптимизация действительно выполняется.
Итак, чем они отличаются? Что ж, как предполагает документ GCC, в принципе использование -fwhole-program не дает никаких преимуществ, потому что эта опция предполагает что-то, что вы должны убедиться, что это правда. Чтобы сломать его, просто определите функцию в одном файле .cpp и используйте ее в другом. Вы получите ошибку компоновщика.
Есть ли какое-либо преимущество для -fwhole-программы? Что ж, если у вас есть только один модуль компиляции, вы можете использовать его, но, честно говоря, он не будет лучше. Мне удалось получить исполняемые файлы разных размеров с помощью эквивалентных программ, но при проверке фактического сгенерированного машинного кода они были идентичны. Фактически, единственные различия, которые я видел, были в том, что номера строк с отладочной информацией были разными.