The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

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

12.10.2020 22:46

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

Ключевым изменением в новом выпуске стало включение в состав Flang, фронтэнда для языка Fortran. Flang поддерживает Fortran 2018, OpenMP 4.5 и OpenACC 3.0, но разработка проекта пока не завершена и фронтэнд ограничивается разбором кода и его проверкой на корректность. Генерация промежуточного кода LLVM пока не поддерживается и для формирования исполняемых файлов генерируется канонический код, который передаётся во внешний компилятор Fortran.

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

  • Добавлена возможность восстановления абстрактного синтаксического дерева (AST) для некорректного кода на C++, которое может использоваться для упрощения диагностики ошибок и предоставляет дополнительную информацию для внешних утилит, таких как clang-tidy и clangd. Возможность по умолчанию включена для кода на C++ и управляется через опции "-Xclang -f[no-]recovery-ast".
  • Добавлены новые режимы диагностики:
    • "-Wpointer-to-int-cast" - группа предупреждений о приведении указателей к целому типу int, не вмещающему все возможные значения.
    • "-Wuninitialized-const-reference" - предупреждение о передаче неинициализированных переменных в параметрах функции, принимающих ссылочные аргументы с признаком "const".
    • "-Wimplicit-const-int-float-conversion" - включённое по умолчанию предупреждение о неявном преобразовании вещественной константы в целый тип.
  • Для платформы ARM предоставлены встроенные в компилятор Си-функции (Intrinsics), заменяемые на эффективные векторные инструкции Arm v8.1-M MVE и CDE. Доступные функции определены в заголовочных файлах arm_mve.h и arm_cde.h.
  • Добавлен набор расширенных целочисленных типов _ExtInt(N), позволяющих создавать типы не кратные степени двойки, которые могут эффективно обрабатываться на FPGA/HLS. Например, _ExtInt(7) определяет целый тип, состоящий из 7 бит.
  • Добавлены макросы, определяющие поддержку встроенных Си-функций на базе инструкций ARM SVE (Scalable Vector Extension): __ARM_FEATURE_SVE, __ARM_FEATURE_SVE_BF16, __ARM_FEATURE_SVE_MATMUL_FP32, __ARM_FEATURE_SVE_MATMUL_FP64, __ARM_FEATURE_SVE_MATMUL_INT8, __ARM_FEATURE_SVE2, __ARM_FEATURE_SVE2_AES, __ARM_FEATURE_SVE2_BITPERM, __ARM_FEATURE_SVE2_SHA3, __ARM_FEATURE_SVE2_SM4. Например, макрос __ARM_FEATURE_SVE определяется при генерации кода AArch64 с установкой опции командной строки "-march=armv8-a+sve".
  • Флаг "-O" теперь отождествляется с режимом оптимизации "-O1" вместо "-O2".
  • Добавлены новые флаги компилятора:
    • "-fstack-clash-protection" - включает защиту от пересечения стека и кучи.
    • "-ffp-exception-behavior={ignore,maytrap,strict}" - позволяет выбрать режим обработчика исключений для чисел с плавающей запятой.
    • "-ffp-model={precise,strict,fast}" - упрощает доступ к серии специализированных опций для чисел с плавающей запятой.
    • "-fpch-codegen" и "-fpch-debuginfo" для генерации предкомпилированного заголовка (PCH) с отдельными объектными файлами для кода и debuginfo.
    • "-fsanitize-coverage-allowlist" и "-fsanitize-coverage-blocklist" для проверки белого и чёрного списков coverage-тестирования.
    • "-mtls-size={12,24,32,48}" для выбора размера TLS (thread-local storage).
    • "-menable-experimental-extension" для включения экспериментальных расширений RISC-V.
  • По умолчанию для Си применён режим "-fno-common", позволяющий повысить эффективность доступа к глобальным переменным на некоторых платформах.
  • Кэш модулей по умолчанию перенесён из /tmp в каталог ~/.cache. Для переопределения можно использовать флаг "-fmodules-cache-path=".
  • Применяемый по умолчанию стандарт языка Си обновлён с gnu11 до gnu17.
  • Добавлена предварительная поддержка расширения GNU C "asm inline" для добавления ассемблерных вставок. Расширение пока только разбирается, но никак не обрабатывается.
  • Расширены возможности, связанные с поддержкой OpenCL и CUDA. Добавлена поддержка диагностики блоков OpenCL 2.0 и реализованы новые возможности OpenMP 5.0.
  • В утилиту clang-format добавлена опция IndentExternBlock для выравнивания внутри блоков extern "C" и extern "C++".
  • В статическом анализаторе улучшена обработка унаследованных конструкторов в C++. Добавлены новые проверки alpha.core.C11Lock и alpha.fuchsia.Lock для проверки блокировок, alpha.security.cert.pos.34c для выявления небезопасного использования putenv, webkit.NoUncountedMemberChecker и webkit.RefCntblBaseVirtualDtor для выявления проблем с несчётными типами, alpha.cplusplus.SmartPtr для проверки разыменования нулевого умного указателя.
  • В linter clang-tidy добавлена большая порция новых проверок.
  • В кеширующем сервере clangd (Clang Server) повышена производительность и добавлены новые возможности диагностики.

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

  • Система сборки переведена на использование Python 3. Если Python 3 недоступен, то реализована возможность отката на использование Python 2.
  • Из выпуска исключён фронтэнд с компилятором для языка Go (llgo), который возможно будет реструктуризирован в будущем.
  • В промежуточное представление (IR) добавлен атрибут vector-function-abi-variant для описания маппинга между скалярными и векторными функциями для векторизации вызовов. Из llvm::VectorType выделено два отдельных векторных типа llvm::FixedVectorType и llvm::ScalableVectorType.
  • Признано неопределённым поведением ветвление на основе undef-значений и передача undef-значений в функции стандартной библиотеки. В memset/memcpy/memmove разрешена передача undef-указателей, но, если параметр с размером равен нулю.
  • В LLJIT добавлена поддержка выполнения статических инициализаций через методы LLJIT::initialize и LLJIT::deinitialize. Реализована возможность добавления статических библиотек к JITDylib при помощи класса StaticLibraryDefinitionGenerator. Добавлен Си API для ORCv2 (API для сборки JIT-компиляторов).
  • В бэкенд для архитектуры AArch64 добавлена поддержка процессоров Cortex-A34, Cortex-A77, Cortex-A78 и Cortex-X1. Реализованы расширения ARMv8.2-BF16 (BFloat16) и ARMv8.6-A, включая RMv8.6-ECV (Enhanced Counter Virtualization), ARMv8.6-FGT (Fine Grained Traps), ARMv8.6-AMU ( Activity Monitors virtualization) и ARMv8.0-DGH (Data gathering hint). Обеспечена возможность генерации кода для встроенных функций-обвязок к векторным инструкциям SVE.
  • В бэкенд для архитектуры ARM добавлена поддержка процессоров Cortex-M55, Cortex-A77, Cortex-A78 и Cortex-X1. Реализованы расширения Armv8.6-A Matrix Multiply и RMv8.2-AA32BF16 BFloat16.
  • В бэкенд для архитектуры PowerPC добавлена поддержка генерации кода для процессоров POWER10. Расширены оптимизации циклов и улучшена поддержка операций с плавающей запятой.
  • В бэкенде для архитектуры RISC-V разрешён приём патчей с поддержкой экспериментальных расширенных наборов инструкций, ещё официально не одобренных.
  • Бэкенд для архитектуры AVR переведён из категории экспериментальных в стабильные, включённые в базовую поставку.
  • В бэкенде для архитектуры x86 реализована поддержка инструкций Intel AMX и TSXLDTRK. Добавлена защита от атак LVI (Load Value Injection), а также реализован общий механизм Speculative Execution Side Effect Suppression для блокирования атак, вызванных спекулятивным выполнением операций в CPU.
  • В бэкенде для архитектуры SystemZ добавлена поддержка MemorySanitizer и LeakSanitizer.
  • В Libc++ добавлена поддержка заголовочного файла с математическими константами <numbers>.
  • Расширены возможности компоновщика LLD. Улучшена поддержка формата ELF, в том числе добавлены опции "--lto-emit-asm", "--lto-whole-program-visibility", "--print-archive-stats", "--shuffle-sections", "--thinlto-single-module", "--unique", "--rosegment", "--threads=N". Добавлена опция "--time-trace" для сохранения трассировки в файл, который затем можно проанализировать через интерфейс chrome://tracing в Chrome.


  1. Главная ссылка к новости (https://lists.llvm.org/piperma...)
  2. OpenNews: Результаты пересборки пакетной базы Debian при помощи Clang 10
  3. OpenNews: Экспериментальная поддержка пересборки ядра Linux в Clang с механизмом защиты CFI
  4. OpenNews: Релиз набора компиляторов GCC 10
  5. OpenNews: Разработчики из Google предложили разработать свою libc для LLVM
  6. OpenNews: Релиз набора компиляторов LLVM 10.0
Лицензия: CC BY 3.0
Короткая ссылка: https://opennet.ru/53874-llvm
Ключевые слова: llvm, clang, compile
При перепечатке указание ссылки на opennet.ru обязательно


Обсуждение (85) Ajax | 1 уровень | Линейный | +/- | Раскрыть всё | RSS
  • 1.1, Аноним (1), 22:53, 12/10/2020 [ответить] [﹢﹢﹢] [ · · · ]  
  • +4 +/
    Нужно, не копайте
     
  • 1.3, Аноним (3), 23:01, 12/10/2020 [ответить] [﹢﹢﹢] [ · · · ]  
  • –8 +/
    Для чего Fortran использовать можно, кроме вычислений? А то ощущение, что язык под одну нишу заточен.
     
     
  • 2.5, Аноним (5), 23:12, 12/10/2020 [^] [^^] [^^^] [ответить]  
  • –10 +/
    А зачем нужен фортран, если есть C, C++, OpenCL, SyCL, а если и их мало, то Boost::Compute (по сути просто обёртка вокруг OpenCL для человечной инициализации), ArrayFire, а если и этого мало, то pyTorch, TensorFlow, MxNet, и даже недавний релиз NeoML от ABBYY, с зависимостями от проприетарной платной bloatare, дискриминирующей против AMD, Intel Performance Primitives.
     
     
  • 3.6, Аноним (3), 23:26, 12/10/2020 [^] [^^] [^^^] [ответить]  
  • +3 +/
    Зачем библиотеки перечислять?
     
     
  • 4.7, Аноним (5), 23:31, 12/10/2020 [^] [^^] [^^^] [ответить]  
  • +3 +/
    Потому что без них BLAS (оптимизированные операции линейной алгебры, вроде скалярного произведения и разложений, причём каждой операции по несколько видов, в зависимости от симметрии матрицы) из коробки нет. Ещё AMD OpenCL BLAS и FFT забыл перечислить.
     
  • 4.36, YetAnotherOnanym (ok), 09:45, 13/10/2020 [^] [^^] [^^^] [ответить]  
  • +7 +/
    Чтобы показать, что он про них читал.
     
  • 3.62, Gefest (?), 20:21, 13/10/2020 [^] [^^] [^^^] [ответить]  
  • –1 +/
    Патамушта это все не для людей,это все для погроммистов, чюдо ты наше.
     
  • 2.10, Я (??), 23:44, 12/10/2020 [^] [^^] [^^^] [ответить]  
  • +4 +/
    Fortran вечен!!!
     
     
  • 3.12, Аноним (3), 23:54, 12/10/2020 [^] [^^] [^^^] [ответить]  
  • –3 +/
    Можно на нём операционную систему написать или микроконтроллеры прогать?
     
     
  • 4.15, Аноним (15), 00:16, 13/10/2020 [^] [^^] [^^^] [ответить]  
  • +6 +/
    Я под ВЭБ на нем прогаю, вместо жаваскрипта. Олдскульненько так.
     
     
  • 5.33, ksjdjfgklsjdklgfj (?), 08:29, 13/10/2020 [^] [^^] [^^^] [ответить]  
  • +4 +/
    блин, я аж пивом подавился когда распарсил :)
     
  • 4.39, ИмяХ (?), 11:22, 13/10/2020 [^] [^^] [^^^] [ответить]  
  • –1 +/
    Можно ли молотком хлеб порезать или полы подмести?
     
     
  • 5.47, Аноним (3), 12:25, 13/10/2020 [^] [^^] [^^^] [ответить]  
  • +1 +/
    Некорректное сравнение.
     
  • 5.80, Аноним (80), 11:45, 16/10/2020 [^] [^^] [^^^] [ответить]  
  • +/
    Заморозь в форме ножа, желательно хлебного (как пила чтобы лезвие было); Мойка высокого давления и направленной струёй вжух, вжух
     
  • 2.18, Аноним (18), 00:48, 13/10/2020 [^] [^^] [^^^] [ответить]  
  • –3 +/
    >Для чего Fortran использовать можно, кроме вычислений?

    Для повышения чсв разве что.

     
  • 2.19, Аноним (19), 01:05, 13/10/2020 [^] [^^] [^^^] [ответить]  
  • –13 +/
    Ни для чего. В llvm он нужен только для поддежрки кое-какого распространнного легаси на этом г-не написанного, чтобы исключить необходимость в gfortran, который тащит gcc и прочий несовместимый мусор.
     
     
  • 3.65, Аноним (65), 02:01, 14/10/2020 [^] [^^] [^^^] [ответить]  
  • +5 +/
    Уровень опеннетовских анонимных экспертов порой просто поражает.
     
  • 2.26, yep (?), 07:06, 13/10/2020 [^] [^^] [^^^] [ответить]  
  • +5 +/
    Да, он изначально заточен и его продолжают затачивать прежде всего под цели вычислений.
     
  • 2.37, nobody (??), 11:02, 13/10/2020 [^] [^^] [^^^] [ответить]  
  • +/
    Это язык для физиков и математиков, а не для программистов. Нахрен им его ещё для чего-то использовать?
     
     
  • 3.38, Sw00p aka Jerom (?), 11:14, 13/10/2020 [^] [^^] [^^^] [ответить]  
  • –2 +/
    а вам все готовое подавай?

    пс: не подскажите каким языком пользуются "макаки"?

     
     
  • 4.44, Zlo (??), 11:53, 13/10/2020 [^] [^^] [^^^] [ответить]  
  • +3 +/
    AppleScript
     
  • 3.72, fsb4000 (?), 17:10, 14/10/2020 [^] [^^] [^^^] [ответить]  
  • +/
    А как же Haskell? Разве не Haskell язык для математиков?
     
  • 2.51, Аноним (51), 13:51, 13/10/2020 [^] [^^] [^^^] [ответить]  
  • +/
    Фортран это почти ассемблер с человеческим лицом. Что-то сложное типа БД на нем делать боль.
     

  • 1.4, Аноним (5), 23:05, 12/10/2020 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    А грёбанный долгоиграющий баг с неправильными флагами компоновки при использовании стандартной библиотеки glibc при включённом positional-independent code при использовании clang в качестве фронтенда линкера так и не пофиксили. Приходится изращаться для обхода.
     
     
  • 2.40, Аноним (40), 11:36, 13/10/2020 [^] [^^] [^^^] [ответить]  
  • +/
    А можно чуть поподробнее, пожалуйста? Интересно.
     
     
  • 3.68, Аноним (5), 10:25, 14/10/2020 [^] [^^] [^^^] [ответить]  
  • +/
    Можно.

    https://github.com/pocl/pocl/blob/master/cmake/clangLinkerWorkaround.sh
    https://bugs.llvm.org/show_bug.cgi?id=44594

     
  • 2.49, Аноним (-), 13:39, 13/10/2020 [^] [^^] [^^^] [ответить]  
  • –2 +/
    Юзай GCC!
     

  • 1.8, Аноним (5), 23:41, 12/10/2020 [ответить] [﹢﹢﹢] [ · · · ]  
  • +2 +/
    >Добавлена защита от атак LVI (Load Value Injection)

    1. Большая деградация производительности.
    2. Требует SSE2.

     
     
  • 2.13, Аноним (13), 00:02, 13/10/2020 [^] [^^] [^^^] [ответить]  
  • +5 +/
    >Требует SSE2

    Который есть во всех х64 процессорах. Что сказать-то хотел?

     
     
  • 3.16, Аноним (5), 00:30, 13/10/2020 [^] [^^] [^^^] [ответить]  
  • +4 +/
    >Который есть во всех х64 процессорах

    В aarch64 этого набора инструкций нет ;)

    А сказать я хотел, что есть люди (которые даже софт не собирают, только на форумах - ****ят), которым очень не терпится прибить 32-бита, а вернее не столько прибить 32-бита, сколько нагадить его пользователям, при этом прикрывшись другими мотивами. Если кого-то толкнуть вниз, сам полетишь вверх - им кажется. Не понимают, что в обществе закон сохранения импульса не работает.

     
     
  • 4.20, Аноним (19), 01:10, 13/10/2020 Скрыто ботом-модератором     [к модератору]
  • +/
     
     
  • 5.28, Аноним (5), 07:40, 13/10/2020 Скрыто ботом-модератором     [к модератору]
  • –2 +/
     
     
  • 6.34, ksjdjfgklsjdklgfj (?), 08:30, 13/10/2020 Скрыто ботом-модератором     [к модератору]
  • –1 +/
     
     
  • 7.35, Аноним (5), 08:38, 13/10/2020 Скрыто ботом-модератором     [к модератору]
  • –1 +/
     
  • 4.27, Fracta1L (ok), 07:28, 13/10/2020 [^] [^^] [^^^] [ответить]  
  • +/
    > Если кого-то толкнуть вниз, сам полетишь вверх - им кажется. Не понимают, что в обществе закон сохранения импульса не работает.

    К сожалению, в обществе этот закон прекрасно работает

     
     
  • 5.29, Аноним (5), 07:42, 13/10/2020 [^] [^^] [^^^] [ответить]  
  • +/
    Не, в обществе ты толкнёшь кого-то вниз, сам полетишь наверх, но всё общество целиком полетит вниз, вместе с тобой, хоть относительно общества ты и полетишь наверх.
     
     
  • 6.43, пох. (?), 11:53, 13/10/2020 [^] [^^] [^^^] [ответить]  
  • –1 +/
    Но им-то - наплевать!

    Самому взобраться на броневичок над остальными рабами гораздо прикольнее, чем быть пиццотым гребцом, не прикованным к скамье.

     
     
  • 7.46, Аноним (46), 12:22, 13/10/2020 [^] [^^] [^^^] [ответить]  
  • +/
    хорошо ты Ленина мазанул, на корзину печенья и банку варенья заработал.
     
     
  • 8.55, пох. (?), 16:35, 13/10/2020 [^] [^^] [^^^] [ответить]  
  • +/
    Но я броневик хочу Печенье и варенье потом сам реквизирую, у недобитых плохишей... текст свёрнут, показать
     
  • 8.79, Аноним (79), 11:25, 16/10/2020 [^] [^^] [^^^] [ответить]  
  • +/
    Это где выдают Кроме троцкистких недобитков никто пропагандой сейчас не занима... текст свёрнут, показать
     
  • 2.63, topin89 (ok), 23:17, 13/10/2020 [^] [^^] [^^^] [ответить]  
  • +/
    3. Необязательна (-mno-lvi-cfi -mno-lvi-hardening)
     
     
  • 3.69, Аноним (5), 10:30, 14/10/2020 [^] [^^] [^^^] [ответить]  
  • +1 +/
    Есть нюанс - требует либо пересборки софта (очень долго и ресурсоёмко в случае Firefox или TensorFlow, даже pytorch и llvm часами пересобираются), либо как-то взять и занопить инструкцию в момент исполнения (напр. ядерным модулем).
     

  • 1.9, Аноним (5), 23:43, 12/10/2020 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    > Бэкенд для архитектуры AVR переведён из категории экспериментальных в стабильные, включённые в базовую поставку.

    Зато PIC несколько лет назад выпилили. Теперь лифтинг делать некуда и натравливать retdec не на что.

     
  • 1.11, Аноним (5), 23:46, 12/10/2020 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    >"-fpch-codegen" и "-fpch-debuginfo" для генерации предкомпилированного заголовка (PCH) с отдельными объектными файлами для кода и debuginfo.

    А толку? Их всё равно кроме Visual Studio ни одна система сборки не использует.

     
     
  • 2.22, Имя (?), 02:48, 13/10/2020 [^] [^^] [^^^] [ответить]  
  • +1 +/
    Cmake, нет?
     
     
  • 3.23, Аноним (23), 05:18, 13/10/2020 [^] [^^] [^^^] [ответить]  
  • +/
    И внезапно visual studio так же может использовать clang/llvm.
     
     
  • 4.24, Имя (?), 05:20, 13/10/2020 [^] [^^] [^^^] [ответить]  
  • +/
    Не спорю, я и GCC прикручивал к студии, VS это только среда. А вы говорите про MS Build.
     
  • 3.30, Аноним (5), 07:45, 13/10/2020 [^] [^^] [^^^] [ответить]  
  • +/
    Спасибо, значит уже добавили. Помню, как мне пришлось их из кода выпиливать, когда портировал на CMake + gcc.
     
  • 2.54, Ordu (ok), 16:20, 13/10/2020 [^] [^^] [^^^] [ответить]  
  • –1 +/
    debug-info в отдельном файле -- это удобно. Можно хоть всю систему собрать с отладочной информацией, положив эту информацию отдельно куда-нибудь. Когда дело доходит до отладки чего-нибудь там, можно не парясь заглядывать в функции системно-установленных библиотек, и смотреть что там происходит. То есть, понятно, -O2 и прочие оптимизации делают отладку не столь гладкой, как хотелось бы, но в большинстве случаев этого достаточно, и не надо пересобирать glibc с отладочной инфой, и пересобирать полсистемы потом под эту версию glibc, только для того, чтобы посмотреть что там происходит.

    И да, emerge так умеет. Я, правда, не уверен, что -fpch-debuginfo это как раз та штука, которая нужна для emerge -- я не знаю, как он это делает, не вникал. Может быть он использует binutils, чтобы из бинаря, полученного в результате линковки, вынуть отладочную инфу и положить в отдельный бинарь, а потом стрипает сам бинарь от всего лишнего.

     
     
  • 3.60, Аноним (60), 19:57, 13/10/2020 [^] [^^] [^^^] [ответить]  
  • +/
    Это вообще не та штука. И objcopy для этой цели используется примерно во всех бинарных дистрибутивах.
     

  • 1.14, zzz (??), 00:13, 13/10/2020 [ответить] [﹢﹢﹢] [ · · · ]  
  • –5 +/
    С таким прогрессом впору GCC именовать "LLVM-совместимым".
     
  • 1.21, Андрей (??), 01:33, 13/10/2020 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    > В бэкенд для архитектуры ARM добавлена поддержка процессоров Cortex-M55, Cortex-A77, Cortex-A78 и Cortex-X1.

    С поддержкой Cortex-A77 как-то протормозили.

     
  • 1.25, Иваня (?), 06:44, 13/10/2020 [ответить] [﹢﹢﹢] [ · · · ]  
  • –5 +/
    Ненужно. GCC по всем параметрам уделывает LLVM
     
     
  • 2.31, Аноним (5), 08:04, 13/10/2020 [^] [^^] [^^^] [ответить]  
  • +/
    Возможно, что зависит от программы, архитектуры, для которой соберается, и от камня. На моём бенчмарке, который нифига не бенчмарк, а просто just for fun был сделан из обычной процедуры, для -march=k8 на AMD APU Carrizo clang порвал gcc на 287 миллисекунд. Для -march=native проигрыш на 289 миллисекунд. Для -march=cascadelake gcc порвал clang на 294 миллисекунд. Для остальных -march различия порядка 40-90 миллисекунд в пользу gcc.
     
     
  • 3.32, Аноним (5), 08:09, 13/10/2020 [^] [^^] [^^^] [ответить]  
  • +/
    ошибка, для native дельта вообще 9 миллисекунд, но у native время больше, чем, например, у ivybridge
     
  • 3.42, Аноним (42), 11:43, 13/10/2020 [^] [^^] [^^^] [ответить]  
  • +1 +/
    > clang порвал gcc на 287 миллисекунд.

    кто-то кого-то порвал. Сам тест сколько миллисекунд длился?

     
     
  • 4.45, Аноним (45), 12:19, 13/10/2020 [^] [^^] [^^^] [ответить]  
  • –1 +/
    100500
     
  • 4.70, Аноним (5), 10:36, 14/10/2020 [^] [^^] [^^^] [ответить]  
  • +/
    https://github.com/KOLANICH/research_compiler_optimizations_comparison/tree/ma

    Вот тут всё необходимое для воспроизведения исследования на вашем камне.

     
  • 2.41, Аноним (41), 11:37, 13/10/2020 [^] [^^] [^^^] [ответить]  
  • +/
    >GCC по всем параметрам уделывает LLVM

    Влажность мечт 146%

     
     
  • 3.48, erthink (ok), 13:02, 13/10/2020 [^] [^^] [^^^] [ответить]  
  • +1 +/
    Исследовал тему, более чем, 9-й и тем более 10-й GCC именно что уделывает.

    Пару лет назад я бы утверждал обратное, но ситуация постепенно принципиально поменялась.
    В LLVM, на вскидку, накопилось более десятка багов типа https://bugs.llvm.org/show_bug.cgi?id=38217
    И вот теперь либо палки, Г и гвозди, либо еще один раунд "немножко перепишем базовые внутренние интерфейсы" ;)

     
     
  • 4.50, Аноним (-), 13:47, 13/10/2020 [^] [^^] [^^^] [ответить]  
  • –2 +/
    >Пару лет назад я бы утверждал обратное

    И зря! Ты не знаешь как начинался проект LLVM. Изначально разработчики тупо скопировали исходники GCC и постепенно начали его переписывать. Так и создавалось LLVM.

    Разработчиков GCC тоже когда-то задела популярность виртуальных машин. Они когда-то делали GCC виртуально-машинноподобным, но они отказались от этой затеи. И вернулись обратно в классическую модель: Язык_Программирования -------> ассемблер_AT&T --------> машинный код.

    Если разработчики отказались от затеи виртуальных машин, значит был какой-то весомый МИНУС такого проектирования.

     
     
  • 5.52, Аноним (51), 13:59, 13/10/2020 [^] [^^] [^^^] [ответить]  
  • –1 +/
    Минус что llvm уже существует и второй не нужен
     
  • 5.53, Аноним84701 (ok), 14:24, 13/10/2020 [^] [^^] [^^^] [ответить]  
  • +1 +/
    > Разработчиков GCC тоже когда-то задела популярность виртуальных машин. Они когда-то делали
    > GCC виртуально-машинноподобным, но они отказались от этой затеи. И вернулись обратно
    > в классическую модель: Язык_Программирования -------> ассемблер_AT&T --------> машинный код.

    А они о том, что "вернулись", знают? o_O




    cat hello.c && gcc hello.c -fdump-final-insns
    #include <stdio.h>
    int main(void) {
        printf("hello %d", 1+4);
        return 0;
    }

    tail hello.o.gkd
    (insn/f # 0 0 2 (set (reg/f:DI 6 bp)
            (mem:DI (post_inc:DI (reg/f:DI 7 sp)) [  S8 A8])) "hello.c":5:1# {*popdi1}
         (expr_list:REG_CFA_DEF_CFA (plus:DI (reg/f:DI 7 sp)
                (const_int 8 [0x8]))
            (nil)))
    (jump_insn # 0 0 2 (simple_return) "hello.c":5:1# {simple_return_internal}
         (nil)
    -> simple_return)
    (barrier # 0 0)
    (note # 0 0 NOTE_INSN_DELETED)



    https://gcc.gnu.org/onlinedocs/gccint/RTL.html

     
     
  • 6.57, n00by (ok), 17:00, 13/10/2020 [^] [^^] [^^^] [ответить]  
  • +/
    >[оверквотинг удален]
    > sp)) [  S8 A8])) "hello.c":5:1# {*popdi1}
    >      (expr_list:REG_CFA_DEF_CFA (plus:DI (reg/f:DI 7 sp)
    >            
    > (const_int 8 [0x8]))
    >         (nil)))
    > (jump_insn # 0 0 2 (simple_return) "hello.c":5:1# {simple_return_internal}
    >      (nil)
    >  -> simple_return)
    > (barrier # 0 0)
    > (note # 0 0 NOTE_INSN_DELETED)

    А что это? -fdump-final-insns выводит внутреннее представление, которое похоже на LISP.
    bp, sp, di - регистры "архитектуры Интел", без привязки к режиму (разрядности).
    Вот и с более привычном синтаксисе ассемблерного листинга они же:



    $ gcc -masm=intel  -S hello.c -o -
    #
    main:
    .cfi_startproc
    push rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    mov rbp, rsp
    .cfi_def_cfa_register 6
    mov esi, 5
    lea rdi, .LC0[rip]
    mov eax, 0
    call printf@PLT
    mov eax, 0
    pop rbp
    .cfi_def_cfa 7, 8
    ret



     
     
  • 7.58, Аноним84701 (ok), 18:42, 13/10/2020 [^] [^^] [^^^] [ответить]  
  • +/
    > А что это? -fdump-final-insns выводит внутреннее представление, которое похоже на LISP.
    > bp, sp, di - регистры "архитектуры Интел", без привязки к режиму (разрядности).

    Дык, Register Transfer Language
    > The last part of the compiler work is done on a low-level intermediate representation called Register Transfer Language. In this language, the instructions to be output are described, pretty much one by one, in an algebraic form that describes what the instruction does.
    > RTL is inspired by Lisp lists. It has both an internal form,

    (DI тут кстати == "Double Integer mode represents an eight-byte integer")
    Трансформированный из промежуточного представления GIMPLE  (в который, ЕМНИП, трансформируют код фронтенды).
    gcc -fdump-rtl-all даст тут более полную картинку.

    https://gcc.gnu.org/onlinedocs/gccint/GIMPLE.html
    > GIMPLE is a three-address representation derived from GENERIC by breaking down GENERIC expressions into tuples of no more than 3 operands (with some exceptions like function calls). GIMPLE was heavily influenced by the SIMPLE IL used by the McCAT compiler project at McGill University, though we have made some different choices.

    В общем, никаких "AT&T" или тем более "сразу в ASM" ;)

     
     
  • 8.66, n00by (ok), 07:45, 14/10/2020 [^] [^^] [^^^] [ответить]  
  • +/
    То есть язык, описывающий машинные инструкции целевой платформы В общем-то и... текст свёрнут, показать
     
  • 5.64, Sem (??), 01:38, 14/10/2020 [^] [^^] [^^^] [ответить]  
  • +/
    > И зря! Ты не знаешь как начинался проект LLVM. Изначально разработчики тупо скопировали исходники GCC и постепенно начали его переписывать. Так и создавалось LLVM.

    И зачем здесь демонстрировать свое невежество?

     
  • 4.56, n00by (ok), 16:44, 13/10/2020 [^] [^^] [^^^] [ответить]  
  • +/
    Интересно, что оптимизаторы определяют семантику высокоуровнего кода, но есть разница в кодогенераторах:




    $ cat popc.c
    /** Определяет количество единичных бит. */
    unsigned popc(unsigned d)
    {
        // См. Генри Уоррен "Алгоритмические трюки для программистов"
        unsigned n = 0;
        while (d) {
            ++n;
            d &= d - 1;
        }
        return n;
    }


    $ gcc -masm=intel -march=native -O2 -S popc.c -o -
    # Неинформативное вырезано
    popc:
    popcnt  eax, edi ; ZF is set if SRC = 0, otherwise ZF is cleared.
    test    edi, edi
    mov     edx, 0   ; Зачем?
    cmove   eax, edx
    ret
    #
    .ident "GCC: (Gentoo 10.2.0-r2 p3) 10.2.0"


    $ clang -masm=intel -march=native -O2 -S popc.c -o -
    #
    popc:                                   # @popc
    popcnt eax, edi
    ret
    #
    .ident "clang version 10.0.1 "


     
     
  • 5.59, Аноним84701 (ok), 19:16, 13/10/2020 [^] [^^] [^^^] [ответить]  
  • +2 +/
    >  mov     edx, 0   ; Зачем?

    Скорее всего (спекуляция), потому что на этапе промежуточного кода (gimple) оно выглядит так:


    popc (unsigned int d)
    {
      unsigned int D.1910;
      unsigned int n;

      n = 0;
      goto <D.1907>;
      <D.1906>:
      n = n + 1;
      _1 = d + 4294967295;
      d = d & _1;
      <D.1907>:
      if (d != 0) goto <D.1906>; else goto <D.1908>;
      <D.1908>:
      D.1910 = n;
      return D.1910;
    }



    На финальном этапе RTL



    (insn:TI # 0 0 2 (parallel [
                (set (reg:SI 0 ax [orig:82 _2 ] [82])
                    (popcount:SI (reg/v:SI 5 di [orig:84 d ] [84])))
                (clobber (reg:CC 17 flags))
    ...
    (insn:TI # 0 0 2 (set (reg/v:SI 0 ax [orig:83 <retval> ] [83])
            (if_then_else:SI (ne (reg:CCZ 17 flags)
                    (const_int 0 [0]))
                (reg:SI 0 ax [orig:82 _2 ] [82])
                (reg:SI 1 dx [86])))# {*movsicc_noc}
         (expr_list:REG_DEAD (reg:CCZ 17 flags)
            (expr_list:REG_DEAD (reg:SI 1 dx [86])
                (nil))))



    Т.е. получилось "мухи" (while(d) - модифицируем n, потом возвращаем) отдельно, "котлеты" (control flow, если "не d", возвращаем 0) отдельно, т.е. семантика popcnt не учитывается до такой степени
    (возможно, потому что на целевой платформе popcnt "как у интеля" может и не быть, возможно, потому что основная оптимизация делается на более высоком уровне).

    clang -S -emit-llvm



    define dso_local i32 @popc(i32 %0) local_unnamed_addr #0 {
      %2 = call i32 @llvm.ctpop.i32(i32 %0), !range !2
      ret i32 %2
    }
    The 'llvm.ctpop' family of intrinsics counts the number of bits set in a value.



    Получается, высокоуровневый код транслируется в одну "виртуальную" инструкцию подсчета, которая на "конкретных" интелях реализуется простым popcnt.

     
     
  • 6.67, n00by (ok), 08:06, 14/10/2020 [^] [^^] [^^^] [ответить]  
  • +/
    >>  mov     edx, 0   ; Зачем?
    > Скорее всего (спекуляция)

        test    edi, edi
        mov     edx, 0
        cmove   eax, edx

    Если о спекулятивном исполнении, то у cmove в любом случае зависимость по данным с test (ждёт флаг Z). А Z будет установлен, если edi ноль. Таким образом можно без лишнего регистра: cmove eax, edi
    Тут либо как-то связано с переименованием регистра (register renaming, но талмуд я читал давно, а сейчас искать лень), либо ещё что (может и оптимизатор лажанул).

    > Т.е. получилось "мухи" (while(d) - модифицируем n, потом возвращаем) отдельно, "котлеты"
    > (control flow, если "не d", возвращаем 0) отдельно, т.е. семантика popcnt
    > не учитывается до такой степени
    > (возможно, потому что на целевой платформе popcnt "как у интеля" может и
    > не быть, возможно, потому что основная оптимизация делается на более высоком
    > уровне).

    Если железо не поддерживает popcnt, выскочит #UD. Транслятор без подходящей -march генерирует цикл без  popcnt.

    Вероятно, GCC решил соптимизировать исполнение тела цикла, когда на входе 0. Вот тогда спекулятивное исполнение вернёт результат через cmove, а медленная popcnt (у неё на ряде архитектур Latency=3 Throughput=1, тогда как у cmove Latency=1 Throughput=0.5) исполняться не будет.

    В данном случае не всё так однозначно, код после GCC вроде больше, но иногда чуть быстрее.

    >[оверквотинг удален]
    >


    > define dso_local i32 @popc(i32 %0) local_unnamed_addr #0 {
    >   %2 = call i32 @llvm.ctpop.i32(i32 %0), !range !2
    >   ret i32 %2
    > }
    > The 'llvm.ctpop' family of intrinsics counts the number of bits set in
    > a value.
    >


    > Получается, высокоуровневый код транслируется в одну "виртуальную" инструкцию подсчета,
    > которая на "конкретных" интелях реализуется простым popcnt.

    Да, семантический анализатор понял, что именно делает код (интересно, как? может они всю книжку Уоррена туда запихали). На этой стадии трансляции GCC и Clang оказались на равных.

     
     
  • 7.71, Аноним84701 (ok), 12:15, 14/10/2020 [^] [^^] [^^^] [ответить]  
  • +2 +/
    > Если о спекулятивном исполнении,

    Да нет, это я так спекулирую (в смысле, с умным видом рассуждаю) ;)
    > Да, семантический анализатор понял, что именно делает код (интересно, как? может они всю книжку Уоррена туда запихали).

    Примерно да:
    https://github.com/llvm-mirror/llvm/blob/master/lib/Transforms/Scalar/LoopIdio



    static bool detectPopcountIdiom(
    ...
    // step 2: detect instructions corresponding to "x2 = x1 & (x1 - 1)"



    Там еще интересный пассаж есть:



    // TODO List:
    //
    // Future loop memory idioms to recognize:
    //   memcmp, memmove, strlen, etc.
    // Future floating point idioms to recognize in -ffast-math mode:
    //   fpowi
    // Future integer operation idioms to recognize:
    //   ctpop
    //
    // Beware that isel's default lowering for ctpop is highly inefficient for
    // i64 and larger types when i64 is legal and the value has few bits set.  It
    // would be good to enhance isel to emit a loop for ctpop in this case.



    А вот gcc я тыкал вчера минут 40 перед сном и так и не нашел, где "оно там" спрятанно.

     
  • 5.73, erthink (ok), 19:54, 14/10/2020 [^] [^^] [^^^] [ответить]  
  • +/
    > mov     edx, 0   ; Зачем?

    Так быстрее, хотя можно поспорить о том стоит ли игра свеч.

    Насколько помню, вариант кода от GCC в 2 раза (или даже в 3) быстрее на нулях.
    Т.е. если считать кол-во единичных бит в массиве, то "магия" добавленная gcc позволяет экономить по такту на каждом слове.
    Кроме этого, при последующих вычислениях разница может быть еще более значительной (cmov может порождать два пути спекулятивного выполнения).

    При этом, поведение актуального gcc 10.2 очень прецизионное. Добавляемая "магия" меняется в зависимости от целевого ядра (опция -march=), всего 4 варианта не считая цикла при отсутствии popcnt.

    Ну и вишенка - gcc можно было-бы упрекнуть в генерации лишнего кода, но если задать -Os, то останется только popcnt.

    Собственно, поэтому я говорю что сейчас gcc умеет больше чем llvm.

     
     
  • 6.74, n00by (ok), 11:04, 15/10/2020 [^] [^^] [^^^] [ответить]  
  • +/
    Про быстрее при 0 я писал https www opennet ru openforum vsluhforumID3 122094 ... большой текст свёрнут, показать
     
     
  • 7.77, erthink (ok), 23:28, 15/10/2020 [^] [^^] [^^^] [ответить]  
  • +/
    > Т.е не ясно, почему 1й вариант, а не 2й.

    Там четыре варианта в зависимости от целевого ядра.
    Поиграйтесь флагом -march на https://godbolt.org/z/j9q4oG

    > На массиве нулей. А если данные случайны? На каждом одном слове из
    > 256, то есть 1/256 такта. При этом кеш инструкций расходуется непропорционально.

    Тут "трусы vs крестик".
    Если gcc опросили -Ofast он делает быстрее, если -Os то компактнее.
    При необходимости более оптимального решения нужно использовать PGO, либо разметку функций атрибутами fast/cold (кстати, LLVM этого не умеет).

    > Дело может быть в области применения, а так же в том, что
    > в Ваши задачи входит писать быстрый код, потому в конкретных и
    > оптимизированных решениях GCC выигрывает, присваивая себе заслуги автора кода. А вот
    > эта моя поделка https://www.opennet.ru/opennews/art.shtml?num=53778 собранная GCC,
    > выполняется в 2 раза медленнее (согласно и top, и perf). Написал
    > как попало, принципиально не заморачиваясь оптимизацией (ну, только синус табличный),
    > в цикле считаются float-ы, примерно так:

    [...]
    > Причину не искал, потому не могу пока говорить про данный случай предметно.

    Покажите ваш код (в минимально объеме) через https://godbolt.org/
    Будет понятнее что там происходит.

     
     
  • 8.81, n00by (ok), 13:07, 16/10/2020 [^] [^^] [^^^] [ответить]  
  • +/
    Так варианты машинного кода не объясняют причину, почему выбрана именно такая В... большой текст свёрнут, показать
     
     
  • 9.82, erthink (ok), 15:45, 16/10/2020 [^] [^^] [^^^] [ответить]  
  • +/
    Ну как-бы очевидно что компилятор руководствуется подобными правилами, которые б... текст свёрнут, показать
     
     
  • 10.84, n00by (ok), 17:55, 17/10/2020 [^] [^^] [^^^] [ответить]  
  • +/
    Так вопрос в том, насколько эти правила адекватны железу Когда-то мне приходило... большой текст свёрнут, показать
     
  • 10.85, n00by (ok), 08:38, 18/10/2020 [^] [^^] [^^^] [ответить]  
  • +/
    Проверил гипотезу так объявил задействованные функции как static inline включи... большой текст свёрнут, показать
     
     
  • 11.87, Аноним (87), 10:51, 21/10/2020 [^] [^^] [^^^] [ответить]  
  • +/
    Как насчёт pgo Все эти ручные твики на редкость не универсальны А сам компилят... текст свёрнут, показать
     
     
  • 12.88, n00by (ok), 12:44, 21/10/2020 [^] [^^] [^^^] [ответить]  
  • +/
    В данном конкретном случае Clang безо всяких твиков выполнил во время трансля... текст свёрнут, показать
     
  • 2.61, Аноним (60), 19:58, 13/10/2020 [^] [^^] [^^^] [ответить]  
  • –3 +/
    > GCC по всем параметрам уделывает LLVM

    Вот когда по удобству кросс-компиляции уделает, тогда приходи со своим экспертным мнением.

     
     
  • 3.78, erthink (ok), 23:30, 15/10/2020 [^] [^^] [^^^] [ответить]  
  • +/
    >> GCC по всем параметрам уделывает LLVM
    > Вот когда по удобству кросс-компиляции уделает, тогда приходи со своим экспертным мнением.

    Человек-снежинка?

     
     
  • 4.83, Аноним (83), 17:49, 17/10/2020 [^] [^^] [^^^] [ответить]  
  • –1 +/
    n00by, erthink, Аноним84701 - втроём полнедели обсуждали обсуждали да таки ничего не поняли.
    Тсс!!! только не говорите им, что ассемблер синтаксиса AT&T в GCC просто и гениально превращяется в машинный код.
     
     
  • 5.86, n00by (ok), 08:46, 18/10/2020 [^] [^^] [^^^] [ответить]  
  • +/
    Ну да, я не понял, какое отношение имеет оптимизация графа вызовов (когда оптимизатор на основании количества вызовов решает, что вот этот вызов функции надо заинлайнить, а вон те - не надо) к целевому коду и его внутреннему представлению?
     

  • 1.89, Andrey_Karpov (ok), 15:03, 27/10/2020 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Не мог пройти мимо и не потыкать палочкой :)
    Проверка Clang 11 с помощью PVS-Studio - https://habr.com/ru/company/pvs-studio/blog/525248/
     

     Добавить комментарий
    Имя:
    E-Mail:
    Текст:



    Партнёры:
    PostgresPro
    Inferno Solutions
    Hosting by Hoster.ru
    Хостинг:

    Закладки на сайте
    Проследить за страницей
    Created 1996-2024 by Maxim Chirkov
    Добавить, Поддержать, Вебмастеру