Релиз набора компиляторов GCC 9

После года разработки опубликован релиз свободного набора компиляторов GCC 9.1, первый значительный выпуск в новой ветке GCC 9.x. В соответствии с новой схемой нумерации выпусков, версия 9.0 использовалась в процессе разработки, а незадолго до выхода GCC 9.1 уже ответвилась ветка GCC 10.0, на базе которой будет сформирован следующий значительный релиз GCC 10.1.

GCC 9.1 примечателен стабилизацией поддержки стандарта C++17, продолжением реализации возможностей будущего стандарта C++20 (кодовое название C++2a), включением в состав фронтэнда для языка D, частичным обеспечением поддержки OpenMP 5.0, почти полной поддержкой OpenACC 2.5, увеличением масштабируемости межпроцедурных оптимизаций и оптимизаций на этапе связывания, расширением средств диагностики и добавлением новых предупреждений, бэкендами для OpenRISC, C-SKY V2 и AMD GCN GPU.

Основные изменения:

  • Добавлена поддержка языка программирования D. В основной состав GCC включены фронтэнд с компилятором GDC (Gnu D Compiler) и runtime-библиотеки (libphobos), которые позволяют использовать штатный GCC для сборки программ на языке программирования D. Процесс включения поддержки языка D в GCC начался ещё в 2011 году, но затянулся из-за необходимости приведения кода к соответствию требованиям GCC и проблем с передачей прав на интеллектуальную собственность компании Digital Mars, развивающей язык программирования D;
  • Внесены улучшения в генератор кода. Например, реализовано применение разных стратегий раскрытия выражений Switch (jump table, bit test, decision tree) в зависимости от ситуаций. Добавлена возможность трансформации линейных функций, включающих выражение Switch, с использованием оптимизации »-ftree-switch-conversion» (например, набор условий вида «case 2: how = 205; break; case 3: how = 305; break;» будет преобразован в »100 * how + 5»;
  • Улучшены межпроцедурные оптимизации. Настройки inline-развёртывания адаптированы для современных кодовых баз на C++ и расширены новыми параметрами max-inline-insns-small, max-inline-insns-size, uninlined-function-insns, uninlined-function-time, uninlined-thunk-insns и uninlined-thunk-time. Повышена точность и агрессивность разделения «холодного» и «горячего» кода. Улучшена масшабируемость для очень больших единиц трансляции (например, при применении оптимизации на этапе связывания к большим программам);
  • Улучшен механизм оптимизации на основе результатов профилирования кода (PGO — Profile-guided optimization), который генерирует более оптимальный код на основе анализа особенностей выполнения кода. Сводная опция »-fprofile-use» теперь включает режимы оптимизации »-fversion-loops-for-strides»,»-floop-interchange»,»-floop-unroll-and-jam» и »-ftree-loop-distribution». Удалено включение в файлы гистограмм со счётчиками, что позволило сократить размер файлов с профилями (гистограммы теперь генерируются на лету при выполнении оптимизаций во время связывания);
  • Расширены оптимизации на этапе связывания (LTO). Обеспечено упрощение типов перед генерацией результата, что позволило существенно сократить размер объектных файлов LTO, уменьшить потребление памяти на этапе связывания и улучшить распараллеливание операций. Число разделов (--param lto-partitions) увеличено с 32 до 128, что повысило эффективность работы на системах с большим числом потоков в CPU. Для управления числом процессов оптимизатора добавлен параметр »--param lto-max-streaming-parallelism»;

    В итоге, по сравнению с GCC 8.3 внесённые в GCC 9 оптимизации позволили примерно на 5% сократить время компиляции Firefox 66 и LibreOffice 6.2.3. Размер объектных файлов снизился на 7%. Время связывания на 8-ядерном CPU уменьшилось на 11%. Последовательная стадия оптимизации на этапе связывания теперь выполняется на 28% быстрее и потребляет на 20% меньше памяти. Потребление памяти каждого обработчика распараллеливаемой стадии LTO снизилось на 30%;

  • Для языков C, C++ и Fortran реализована бо́льшая часть спецификации параллельного программирования OpenACC 2.5, определяющей средства для выноса операций (offloading) на GPU и специализированные процессоры, такие как NVIDIA PTX;
  • Для С и С++ реализована частичная поддержка стандарта OpenMP 5.0 (Open Multi-Processing), определяющего API и способы применения методов параллельного программирования для языков Си, Си++ и Фортран на многоядерных и гибридных (CPU+GPU/DSP) системах с общей памятью и блоками векторизации (SIMD);
  • Для языка Си добавлены новые предупреждения:»-Waddress-of-packed-member» (невыравненное значение указателя на упакованный элемент структуры или объединения) и »-Wabsolute-value» (при обращении к функциям вычисления абсолютного значения, если для указанного аргумента имеется более подходящая функция, например, вместо abs (3.14) следует использовать fabs (3.14)). Для C++ добавлены новые предупреждения:»-Wdeprecated-copy»,»-Winit-list-lifetime»,»-Wredundant-move»,»-Wpessimizing-move» и »-Wclass-conversion». Расширены многие ранее доступные предупреждения;
  • Добавлена экспериментальная поддержка части будущего стандарта языка Си, развиваемого под кодовым именем C2x. Для включения поддержки C2x следует использовать опции »-std=c2x» и »-std=gnu2x» (для включения расширений GNU). Стандарт пока на ранней стадии развития, поэтому из его возможностей поддерживается только выражение _Static_assert с одним аргументом (_Static_assert c двумя аргументами стандартизировано в C11);
  • Объявлена стабильной поддержка стандарта C++17. Во фронтэнде языковые возможности C++17 реализованы полностью, а в libstdc++ определённые в стандарте библиотечные функции близки к полной реализации;
  • Продолжена реализация элементов будущего стандарта C++2a. Например, добавлена возможность включения диапазонов при инициализации, реализованы расширения для лямбда-выражений, добавлена поддержка пустых членов структур данных и атрибутов likely/unlikely, обеспечена возможность вызова виртуальных функций в условных выражениях и т.п. Для включения поддержки C++2a следует использовать опции »-std=c++2a» и »-std=gnu++2a». В libstdc++ для C++2a добавлены заголовочные файлы bit и version, типажи std: remove_cvref, std: unwrap_reference, std: unwrap_decay_ref, std: is_nothrow_convertible и std: type_identity, функции std: midpoint, std: lerp, std: bind_front, std: visit, std: is_constant_evaluated и std: assume_aligned, добавлена поддержка типа char8_t, реализована возможность проверки префикса и суффикса строк (starts_with, ends_with);
  • Добавлена поддержка новых процессоров ARM Cortex-A76, Cortex-A55, Cortex-A76 DynamIQ big.LITTLE и Neoverse N1. Добавлена поддержка появившихся в Armv8.3-A инструкций для работы с комплексными числами, генерации псевдослучайных чисел (rng) и теггирования памяти (memtag), а также инструкций для блокирования атак, связанных со спекулятивным выполнением и работой блока предсказания переходов. Для архитектуры AArch64 добавлен режим защиты от пересечения стека и кучи (»-fstack-clash-protection»). Для использования особенностей архитектуры Armv8.5-A добавлена опция »-march=armv8.5-a»
  • В состав включён бэкенд для генерации кода для GPU AMD на базе микроархитектуры GCN. Реализация пока ограничена компиляцией однопоточных приложений (поддержка выноcа многопоточных вычислений через OpenMP и OpenACC будет предложена позднее) и поддержкой GPU Fiji и Vega 10;
  • Добавлен новый бэкенд для процессоров OpenRISC;
  • Добавлен бэкенд для процессоров C-SKY V2, выпускаемых одноимённой китайской компанией для различных потребительских устройств;
  • Во всех опциях командной строки, оперирующих байтовыми значениями, обеспечена поддержка суффиксов kb, KiB, MB, MiB, GB и GiB;
  • Реализована опция »-flive-patching=[inline-only-static|inline-clone]», позволяющая добиться безопасной компиляции для систем горячего наложения патчей (live-patching) за счёт многоуровневого управления применением межпроцедурных (IPA) оптимизаций;
  • Добавлена опция »--completion» для тонкого управления автодополнением опций при использовании bash;
  • В средствах диагностики обеспечено отображения отрывков исходных текстов с указанием номера строки и с наглядной пометкой сопутствующей информации, такой как типы операндов. Для отключения вывода номеров строк и меток предусмотрены опции »-fno-diagnostics-show-line-numbers» и »-fno-diagnostics-show-labels»; 0_1556905058.png
  • Расширены инструменты для диагностики ошибок в коде на C++, улучшена читаемость сведений о причинах ошибок и подсветка проблемных параметров; 0_1556913958.png
  • Добавлена опция »-fdiagnostics-format=json», позволяющая формировать диагностический вывод в машиночитаемом формате (JSON);
  • Добавлены новые опции профилирования »-fprofile-filter-files» и »-fprofile-exclude-files» для выбора обрабатываемых файлов с исходными текстами;
  • В AddressSanitizer обеспечена генерация более компактного проверочного кода для автоматических переменных, что позволило снизить потребление памяти проверяемым исполняемым файлом;
  • Улучшен вывод в режиме »-fopt-info» (детализация информации о добавленных оптимизациях). Добавлены новые префиксы «optimized» и «missed», помимо ранее доступного префикса «note». Добавлен вывод сведений о принятии решения по inline-развёртыванию и векторизации циклов;
  • Добавлена опция »-fsave-optimization-record», при указании которой GCC сохраняет файл SRCFILE.opt-record.json.gz с описанием решений по применению тех или иных оптимизаций. От режима »-fopt-info» новая опция отличается включением дополнительных метаданных, таких как информация о профиле и inline-цепочках;
  • Добавлены опции »-fipa-stack-alignment» и »-fipa-reference-addressable» для управления при межпроцедурных оптимизациях выравниванием стека и применением режимов адресации (только запись или точно чтение) для статических переменных;
  • Представлены новые встроенные функции для управления привязкой атрибутов, а также поведением, связанным с предсказанием переходов и спекулятивным выполнением инструкций:»__builtin_has_attribute»,»__builtin_expect_with_probability» и »__builtin_speculation_safe_value». Для функций, переменных и типов добавлен новый атрибут copy;
  • Для языка Fortran реализована полноценная поддержка асинхронного ввода/вывода;
  • Объявлена устаревшей и будет удалена в следующем значительном выпуске поддержка платформ Solaris 10 (*-*-solaris2.10) и Cell/B.E (Cell Broadband Engine SPU). Прекращена поддержка архитектур Armv2, Armv3, Armv5 и Armv5E. Прекращена поддержка расширения Intel MPX (Memory Protection Extensions).

© OpenNet