После года разработки увидел свет релиз свободного набора компиляторов GCC 5.1, первый значительный выпуск в новой ветке GCC 5.x (номер 5.0 был пропущен). Новый выпуск примечателен возможностью работы в роли JIT-компилятора, интеграцией системы оптимизации AutoFDO, поддержкой OpenMP 4.0 и OpenACC 2.0 для offloading-вычислений, применением по умолчанию стандарта GNU11 (C11) для языка Си, поддержкой интерфейса параллельного программирования Cilk Plus, включением детектора переполнений буфера, полной поддержкой стандартов C++11 и C++14.
Основные изменения:
- Для языка Си вместо gnu89 (-std=gnu89) по умолчанию активирован режим gnu11 (-std=gnu11) на базе стандарта C11.
- В runtime-библиотеке C++ (libstdc++) обеспечена полная поддержка стандарта C++11, а также экспериментальная поддержка стандарта C++14 и спецификаций Library Fundamentals TS. Задействован по умолчанию новый ABI, а также новые реализации std::string и std::list. Возможность использования старого ABI сохранена, для этого нужно установить в 0 макрос _GLIBCXX_USE_CXX11_ABI перед включением в заголовочного файла;
- Генератор кода может быть собран в виде разделяемой библиотеки libgccjit и затем встроен в другие процессы и использован для организации JIT-компиляции байткода в машинный код. Кроме предоставляемого библиотекой C API и обёртки для C++, подготовлены биндинги для языков Python и D. В качестве возможных областей применения отмечается использование libgccjit в интерпретаторах для компиляции функций из байткода в машинный код или для организации упреждающей компиляции (ahead-of-time);
- В G++ добавлена поддержка возможностей языка C++, определённых в стандарте C++14. В частности, добавлены шаблоны для переменных, возможность объявления локальных переменных, массовой инициализации методов классов, добавлены функции освобождения памяти с указанием размера и т.д.;
- Реализован новый компонент Pointer Bounds Checker (-fcheck-pointer-bounds), нацеленный на выявление фактов выхода указателей за допустимые границы памяти (служит для борьбы с переполнением буфера). Компонент доступен для систем x86/x86-64 GNU/Linux и требует наличие процессора с поддержкой расширений Intel MPX;
- В компиляторах C, C++ и Fortran реализованы средства OpenMP 4.0 (Open Multi-Processing) для ускорения вычислений за счёт выноса операций (offloading) на специализированные процессоры. Готовая runtime-библиотека и эмулятор представлены для акселераторов Intel Xeon Phi (Intel MIC). Для выноса операций на GPU представлена предварительная реализация спецификации OpenACC 2.0a;
- Реализована полноценная поддержка набора расширений Cilk Plus, предлагающего новую эффективную методику параллельного программирования для языков Си и Си++, позволяющую существенно упростить разработку программ, части которых выполняются параллельно с задействованием разных процессорных ядер и векторных сопроцессоров (Vector Units). Для управления генерацией кода с улучшенной векторизацией предусмотрена pragma simd. Поддерживается два метода увеличения производительности — параллелизм данных и параллельное выполнение подпрограмм. В первом случае, обеспечиваются механизмы прозрачного распараллеливания типовых операций над массивами данных и автоматическое задействование SIMD-инструкций. Для организации параллелизма на уровне подпрограмм в обиход вводится три ключевых слова: _Cilk_spawn — запуск функции в параллельном режиме, _Cilk_sync — ожидание завершения параллельно выполняемой функции, и _Cilk_for — организация работы цикла в параллельном режиме.
- Возможность включения заголовочных файлов, только если они присутствуют в системе. Для проверки наличия заголовочного файла представлены директивы препроцессора __has_include и __has_include_next. Кроме того, представлен макрос __has_attribute для определения наличия атрибута;
- Добавлена серия новых встроенных арифметических функций со встроенной проверкой на переполнение: __builtin_add_overflow, __builtin_sub_overflow и __builtin_mul_overflow;
- Многочисленные улучшения оптимизатора:
- Добавлен новый режим оптимизации на основе обратной связи — AutoFDO (Automatic Feedback Directed Optimizer), который использует счетчики производительности (performance counters) ядра Linux в качестве источника информации о производительности различных частей программы.
- Сокращено потребление памяти и времени связывания при включении оптимизаций во время динамического связывания (LTO, Link Time Optimization).
- В оптимизаторе, работающем во время динамического связывания, реализована возможность указания опций оптимизации на уровне отдельных функций, что позволяет добиться большей гибкости, чем при задании опция в привязке к отдельным файлам. Например, можно указать разные режимы (-ffast-math, -mavx, -finline) для разных блоков кода.
- Обеспечено слияние С++ типов на основе метода One Definition Rule;
- В реализацию межпроцедурных оптимизаций добавлен новый проход ICF (Identical Code Folding, «-fipa-icf»), нацеленный на более качественное объединение идентичных блоков кода, без привязки к отдельным секциям функциям. Проверка работы нового режима на кодовой базе Firefox позволила унифицировать около 31 тысячи функций, что составляет 14% от их общего числа.
- Значительно улучшен проход девиртуализации, в котором добавлена поддержка спекулятивной девиртуализации, и динамического определения типов. При тесте на Firefox удалось девиртуализировать около 50% виртуальных вызовов.
- Добавлен новый проход comdat-локализации, позволяющий на этапе компоновки избавиться от дополнительного неиспользуемого кода в inline-функциях C++.
- Проведена оптимизация виртуальных таблиц.
- Добавлена опция «-fno-semantic-interposition», позволяющая повысить качество кода разделяемых библитек, в ситуации запрета вмешательства в экспортируемые символы.
- Реализовано определение и оптимизация переменных, в которых производится только запись.
- Представлен новый проход распределения локальных регистров (-flra-remat), реализующий метод рематериализации, при котором вместо сохранения значения регистра при необходимости используется его повторное вычисление. Применение новой оптимизации продемонстрировало в тестах SPEC20 ускорение выполнение сгенерированного кода на 1% для архитектуры ARM и на 0.5% для x86-64;
- В детекторе неопределенного поведения (Undefined Behavior Sanitizer), выявляющего ситуации, когда поведение программы становится неопределенным (зависит от реализации компилятора) из-за ошибки программиста, добавлены новые режимы: -fsanitize=float-divide-by-zero,
-fsanitize=float-cast-overflow,
-fsanitize=bounds,
-fsanitize=alignment,
-fsanitize=object-size,
-fsanitize=vptr.
- Поддержка развиваемого компанией Google языка программирования Go обновлена до версии 1.4.2;
- Добавлена поддержка векторных инструкций AVX-512 (BW,DQ,VL,IFMA,VBMI), которые появятся в будущих выпусках процессоров Intel на базе новой микроархитектуры Skylake, а также ISA-расширений Intel MPX
- Добавлена поддержка процессоров ARM Cortex-A72, Cavium ThunderX и Applied Micro X-Gene 1. Улучшена генерация кода для 64-разрядной архитектуры ARM (AArch64) с учётом специфики процессоров Cortex-A57 и Cortex-A53.
- Поддержка архитектуры MIPS третьего, пятого и шестого поколения, в том числе процессоров Cavium Octeon 3 и Imagination P5600;
- Добавлена поддержка операционной системы DragonFly BSD, а также поддержка FreeBSD на архитектуре ARM (arm*-*-freebsd*).