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

После шести месяцев разработки представлен релиз проекта LLVM 10.0 — GCC-совместимого инструментария (компиляторы, оптимизаторы и генераторы кода), компилирующего программы в промежуточный биткод RISC-подобных виртуальных инструкций (низкоуровневая виртуальная машина с многоуровневой системой оптимизаций). Сгенерированный псевдокод может быть преобразован при помощи JIT-компилятора в машинные инструкции непосредственно в момент выполнения программы.

Из новых возможностей LLVM 10.0 отмечается поддержка концепций C++ (C++ Concepts), прекращение запуска Clang в форме отдельного процесса, поддержка проверок CFG (control flow guard) для Windows и поддержка новых возможностей CPU.

Улучшения в Clang 10.0:

  • Добавлена поддержка «концепции«, расширения шаблонов C++, которое войдёт в состав следующего стандарта, развиваемого под кодовым именем C++2a (включается флагом -std=c++2a).
    Концепции позволяют определить набор требований к параметрам шаблона, которые во время компиляции ограничивают набор аргументов, которые могут приниматься в качестве параметров шаблона. Концепции можно применять для того, чтобы избежать логических несоответствий между свойствами типов данных, используемых внутри шаблона, и свойствами типов данных входных параметров.

    template<typename T>
    concept EqualityComparable = requires(T a, T b) {
    { a == b } -> std::boolean;
    { a != b } -> std::boolean;
    };

  • По умолчанию прекращён запуск отдельного процесса («clang -cc1»), в котором выполняется компиляция. Компиляция теперь выполняется в основном процессе, а для восстановления старого поведения можно использовать опцию «-fno-integrated-cc1».
  • Новые режимы диагностики:
    • «-Wc99-designator» и «-Wreorder-init-list» — предупреждают об использовании инициализаторов C99 в режиме C++ в случаях, когда они корректны в C99, но не подходят для C++20.
    • «-Wsizeof-array-div» — отлавливает такие ситуации, как «int arr[10]; …sizeof(arr) / sizeof(short)…» (должно быть «sizeof(arr) / sizeof(int)»).
    • «-Wxor-used-as-po» — предупреждает об использовании таких конструкций, как применение оператора «^» (xor) в операциях, которые можно спутать с возведением в степень (2 ^ 16).
    • «-Wfinal-dtor-non-final-class» — предупреждает о классах, не помеченных спецификатором «final», но имеющих деструктор c признаком «final».
    • «-Wtautological-bitwise-compare» — группа предупреждений для диагностики тавтологического сравнения битовой операции и константы, а также для выявления всегда истинных сравнений, в которых битовая операция OR применяется к неотрицательному числу.
    • «-Wbitwise-conditional-parentheses» предупреждает о проблемах при смешивании логических операторов AND («&») и OR («|») c условным оператором («?:»).
    • «-Wmisleading-indentation» — аналог одноимённой проверки из GCC, предупреждающей о выражениях, выделенных отступом, будто они входят в блок if/else/for/while, но на самом деле в данный блок не входящих.
    • При указании «-Wextra» обеспечено включение проверки «-Wdeprecated-copy», предупреждающей об использовании конструкторов
      «move» и «copy» в классах с явным определением деструктора.

    • Расширены проверки «-Wtautological-overlap-compare», «-Wsizeof-pointer-div», «-Wtautological-compare», «-Wrange-loop-analysis».
    • Отключены по умолчанию проверки «-Wbitwise-op-parentheses» и «-Wlogical-op-parentheses».
  • В коде на С и С++ арифметические операции с указателями разрешены только в массивах. Детектор неопределённого поведения (Undefined Behavior Sanitizer) в режиме «-fsanitize=pointer-overflow» теперь отлавливает такие случаи, как добавление ненулевого смещения к указателю со значением null или образование нулевого указателя при вычитании целого числа из ненулевого указателя.
  • Режим «-fsanitize=implicit-conversion» (Implicit Conversion Sanitizer) адаптирован для выявления проблем с операциями инкремента и декремента для типов с битовым размером меньшим, чем у типа «int».
  • При выборе целевых x86-архитектур «-march=skylake-avx512», «-march=icelake-client», «-march=icelake-server», «-march=cascadelake» и «-march=cooperlake» по умолчанию в векторизированном коде прекращено использование 512-разрядных регистров zmm, за исключением их прямого указания в исходных текстах. Причиной является снижение частоты CPU при выполнении 512-разрядных операций, что может негативно сказываться на общей производительности. Для изменения нового поведения предусмотрена опция «-mprefer-vector-width=512».
  • Поведение флага «-flax-vector-conversions» приближено к GCC: запрещены неявные векторные битовые преобразования между целочисленными векторами и векторами с плавающей точкой. Для исключения данного ограничения предлагается использовать флаг
    «-flax-vector-conversions=all», который используется по умолчанию.

  • Улучшена поддержка CPU MIPS семейства Octeon. В список допустимых типов CPU добавлен «octeon+».
  • При сборке в промежуточный код WebAssembly обеспечен автоматический вызов оптимизатора wasm-opt, при его наличии в системе.
  • Для систем на базе архитектуры RISC-V в условных блоках ассемблерных inline-вставок разрешено использование регистров, хранящих значения с плавающей запятой.
  • Добавлены новые флаги компилятора: «-fgnuc-version» для задания значения версии для «__GNUC__» и подобных макросов; «-fmacro-prefix-map=OLD=NEW» для замены префикса каталогов OLD на NEW в таких макросах, как «__FILE__»; «-fpatchable-function-entry=N[,M]» для генерации определённого числа инструкций NOP перед и после точкой входа в функцию. Для RISC-V
    добавлена поддержка флагов «-ffixed-xX», «-mcmodel=medany» и «-mcmodel=medlow».

  • Добавлена поддержка атрибута ‘__attribute__((target(«branch-protection=…»)))’, действие которого аналогично опции -mbranch-protection.
  • На платформе Windows при указании флага «-cfguard» реализована подстановка проверок целостности потока выполнения (Control Flow Guard) при непрямых вызовах функций. Для отключения подстановки проверок можно использовать флаг «-cfguard-nochecks» или модификатор «__declspec(guard(nocf))».
  • Поведение атрибута gnu_inline приближено к GCC, в случаях, когда он используется без ключевого слова «extern».
  • Расширены возможности, связанные с поддержкой OpenCL и CUDA. Добавлена поддержка новых возможностей OpenMP 5.0.
  • В утилиту clang-format добавлена опция Standard, позволяющая определить версию стандарта C++, применяемую при разборе и форматировании кода (Latest, Auto, c++03, c++11, c++14, c++17, c++20).
  • В статический анализатор добавлены новые проверки: alpha.cplusplus.PlacementNew для определения достаточного места в хранилище, fuchsia.HandleChecker для выявления утечек, связанных с обработчиками Fuchsia, security.insecureAPI.decodeValueOfObjCType для определения потенциальных переполнений буфера при использовании [NSCoder decodeValueOfObjCType:at:].
  • В детекторе неопределённого поведения (UBSan, Undefined Behavior Sanitizer) расширены проверки переполнения указателей, которые теперь отлавливают применение ненулевых смещений к указателям NULL или получение в результате добавления смещения указателя со значением NULL.
  • В linter clang-tidy добавлена большая порция новых проверок.

Основные новшества LLVM 10.0:

  • Во фреймворк Attributor добавлены новые межпроцедурные оптимизации и анализаторы. Обеспечено прогнозирование состояния 19 различных атрибутов, включая 12 атрибутов 12 LLVM IR и 7 абстрактных атрибутов, таких как живучесть (liveness).
  • Добавлены новые встроенные в компилятор матричные математические функции (Intrinsics), которые при компиляции заменяются на эффективные векторные инструкции.
  • Внесены многочисленные улучшения в бэкенды для архитектур X86, AArch64, ARM, SystemZ, MIPS, AMDGPU и PowerPC. Добавлена поддержка CPU
    Cortex-A65, Cortex-A65AE, Neoverse E1 и Neoverse N1. Для ARMv8.1-M оптимизирован процесс генерации кода (например, появилась поддержка циклов с минимальными накладными расходами) и добавлена поддержка автовекторизации с использованием расширения MVE. Улучшена поддержка CPU MIPS Octeon. Для PowerPC включена векторизация математических подпрограмм с использованием библиотеки MASSV (Mathematical Acceleration SubSystem), улучшена генерация кода и оптимизирован доступ к памяти из циклов. Для x86 изменена обработка векторных типов v2i32, v4i16, v2i16, v8i8, v4i8 и v2i8.

  • Улучшен генератор кода для WebAssembly. Добавлена поддержка TLS (Thread-Local Storage) и инструкции atomic.fence. Значительно расширена поддержка SIMD. В объектных файлах WebAssembly добавлена возможность использования сигнатур функций с несколькими значениями.
  • При обработке циклов задействован анализатор MemorySSA, позволяющий определять зависимости между различными операциями с памятью. MemorySSA позволяет добиться сокращения времени компиляции и выполнения кода или может использоваться вместо AliasSetTracker без потери в производительности.
  • В отладчике LLDB значительно улучшена поддержка формата DWARF v5. Улучшена поддержка сборки с MinGW
    и добавлена начальная возможность отладки исполняемых файлов Windows для архитектур ARM и ARM64. Добавлены описания опций, предлагаемых при автодополнении ввода нажатием табуляции.

  • Расширены возможности компоновщика LLD. Улучшена поддержка формата ELF, в том числе обеспечена полная совместимость glob-шаблонов с компоновщиком GNU, добавлена поддержка сжатых отладочных секций «.zdebug», добавлено свойство PT_GNU_PROPERTY для определения секции .note.gnu.property (может использоваться в будущих ядрах Linux),
    реализованы режимы «-z noseparate-code», «-z separate-code» и «-z separate-loadable-segments». Улучшена поддержка MinGW и WebAssembly.

Источник: opennet.ru