Наиболее важные изменения при переходе от lcc-1.28 к lcc-1.29 (changelog)

Изменения, затрагивающие совместимость

  • Для переменных register asm типа long double использование extended регистра под именем не-extended регистра объявлено устаревшим (DEPRECATED). Подробнее см. статью Подготовка в lcc-1.29 для E2K к будущим несовместимым изменениям при работе с register asm переменными типа long double

  • Следующие опции объявлены устаревшими (DEPRECATED) и будут удалены в будущих версиях компилятора:

    • -fno-tail-calls (используйте -fno-optimize-sibling-calls)

    • -fno-loop-unswitching (используйте -fno-unswitch-loops)

    • -finit-locals-zero (используйте -ftrivial-auto-var-init=zero)

    • -Wreduced-alignment (необходимость в этом предупреждении отпала после поддержки ovaraligned распределения в стеке)

Общие улучшения

  • Переход на совместимость с gfortran-13.2.0. В lcc-1.28 была совместимость с gfortran-10.3.0

  • Добавлена частичная поддержка OpenMP 4.5 (lcc-1.28 поддерживал OpenMP 4.0), поддержаны приоритеты task’ов и зависимости между ними

  • Поддержано распределение overaligned локальных переменных в стеке, т.е. имеющих выравнивание более 16 байт, указанное с помощью __attribute__((aligned(N)))

  • Реализована оптимальная поддержка платформо-независимых векторных инструкций, определённых над векторными типами, заданными с помощью __attribute__((vector_size(N)))

  • Переработан AddressSanitizer, произведён переход на библиотеку поддержки версии 11.1.0 (в lcc-1.28 была версия 5.0.1)

  • Добавлена поддержка опции -ftrivial-auto-var-init=<choice>. Опция аналогична существующей в GCC, но с одним важным различием. В режиме -ftrivial-auto-var-init=uninitialized (по умолчанию) с оптимизациями (-O1-O4) компилятор lcc инициализирует некоторые переменные, которые могут быть использованы неинициализированными. Это позволяет избежать очень редких падений при исполнении на Эльбрусе из-за диагностических тегов в регистрах. В режиме без оптимизаций (-O0) uninitialized имеет такой же смысл, как у GCC, т.е. никакие переменные не инициализируются компилятором.

  • Добавлена поддержка __attribute__((optimize)) для следующих опций:

    • -fno-use-memset

    • -fno-use-memcpy

  • В runtime-анализатор качества работы оптимизаций (опция -fsanitize=opt) добавлена поддержка оптимизаций overlap, apb, nesting. Анализатор по-прежнему имеет статус экспериментального.

  • В защищённом режиме добавлены опции -mprot-va-arg-semi-spec и -mprot-abi-promotion для программного ослабления защиты. Опции помогут в процессе портирования чужого софта в защищённый режим

  • Добавлена поддержка опции -fprofile-correction. Опция аналогична существующей в GCC. В некоторых случаях файл с профильной информацией может содержать несовместимые счётчики, например, из-за неявной передачи управления, невидимой для компилятора. При загрузке такого файла с профилем в режиме -fprofile-use компилятор по умолчанию выдаст ошибку. Опция -fprofile-correction позволяет “сгладить” подобные несоответствия в профильной информации.

  • Добавлена поддержка прагм cache_opt и no_cache_opt. Прагма cache_opt форсирует применение оптимизации Cache Opt к ближайшему после объявления циклу. Прагма no_cache_opt запрещает применение этой оптимизации. Суть оптимизации заключается в отодвигании load’ов от операций, использующих их результат, в конвейеризованных циклах; за счёт этого уменьшается количество блокировок в случае, когда данные отсутствуют в кэш-памяти 1-го или 2-го уровня. Данная оптимизация существует в компиляторе достаточно давно, и теперь у пользователя появился способ управлять её применением для отдельных циклов.

  • Начиная с версии lcc-1.29.15 оптимизация full peeling отключается, если значение прагмы unroll не совпадает с количеством итераций цикла

  • В режиме -fopt-report добавлены печати применения softpipe (программная конвейеризация циклов без аппаратной поддержки) и причины отвала этой оптимизации

  • Добавлена поддержка __builtin_e2k_get_cpu_iset

  • Добавлена поддержка __builtin_e2k_get_cpu_mode, __builtin_e2k_set_cpu_mode

  • Добавлена поддержка __builtin_e2k_rrq

  • Добавлена поддержка __builtin_e2k_get_rwap_base, __builtin_e2k_get_rwap_size, __builtin_e2k_get_rwap_curptr

  • Добавлена поддержка __builtin_e2k_get_rwsap_base, __builtin_e2k_get_rwsap_size, __builtin_e2k_get_rwsap_curptr

  • Добавлена поддержка __builtin_e2k_get_ap_color

  • Добавлена поддержка __builtin_e2k_create_ap_subarray_color, __builtin_e2k_apincr_color

  • Добавлена поддержка __builtin_e2k_is_ptr_ap, __builtin_e2k_is_ptr_pl, __builtin_e2k_is_ptr_nv

Доработки оптимизаций

  • Значительно переработана фаза apb, добавлена поддержка 64-разрядных регистров AAIND, появившихся в Elbrus V5

  • Добавлена оптимизация ICF (Identical Code Folding), объединяющая функции с одинаковым содержимым. Включается опциями -fipa-icf -fwhole, оптимизация по умолчанию выключена.

  • Доработана оптимизация MAW (Memory Access Wedening), объединяющая соседние мелкоформатные инструкции обращения к памяти, - добавлен отдельный проход, позволяющий работать с очень длинными кортежами соседних операций. Добавлена опция -fno-maw для отключения оптимизации.

  • Добавлена новая оптимизация bit_maw, объединяющая инструкции инициализации смежных битовых полей структур константами. Включена по умолчанию начиная с уровня -O2. Может быть отключена опцией -fno-bit-maw

  • Добавлена новая оптимизация gcse_calls для объединения вызовов pure и const функций с одинаковыми аргументами. Управляется опциями -fgcse-calls, -fno-gcse-calls. Включена по умолчанию начиная с уровня -O2

  • Добавлена поддержка инициализатора у extern переменных, теперь значение инициализатора может быть использовано пропагатором констант.

  • Улучшена работа оптимизаций в режиме -fsanitize=address - теперь после фазы инструментирования разрешено снимать предикаты с операций с постановкой в спекулятивный режим. Это позволило ускорить исполнение инструментированных программ в среднем почти в 2 раза в режиме -O3

  • Добавлена новая оптимизация ipo_dce для удаления глобальных переменных, в которые есть записи, но нет чтений. Включается опцией -fipo-dce

  • Добавлена новая оптимизация carry_early_cond - вынос раннего выхода из функции с постановкой всех вызовов функции под условие. Управляется опциями -fipo-cec, -fno-ipo-cec. Включена по умолчанию начиная с уровня -O3

  • Доработана поддержка restrict-указателей:

    • Теперь в режиме -frestrict-params указатель this в языке C++ также трактуется как имеющий модификатор restrict

    • Добавлена опция -frestrict-cross-iter, по которой компилятор рвёт межитерационные зависимости для restrict-указателей, объявленных внутри цикла. По стандарту для таких указателей можно рвать зависимости только в пределах одной итерации цикла, что не позволяет применять в таком цикле важные для Эльбруса оптимизации (overlap, apb и т.д.). Для решения этой проблемы можно либо вынести объявление таких указателей за пределы цикла, либо подать указанную опцию, если таких мест в исходниках много.

  • Добавлена опция -finline-scale-code-size-limit=<f>, позволяющая скорректировать ограничение на рост размера кода на фазе inline