Новая версия набора компиляторов LLVM 3.8
Состоялся релиз проекта LLVM 3.8 (Low Level Virtual Machine) — GCC-совместимого инструментария (компиляторы, оптимизаторы и генераторы кода), компилирующего программы в промежуточный биткод RISC-подобных виртуальных инструкций (низкоуровневая виртуальная машина с многоуровневой системой оптимизации). Сгенерированный платформонезависимый псевдокод может быть преобразован при помощи JIT-компилятора в машинные инструкции непосредственно в момент выполнения программы. В новом выпуске включена по умолчанию поддержка OpenMP 3.1, добавлены элементы OpenMP 4.x, реализована возможность компиляции CUDA, задействован режим shrink-wrapping, добавлены новые возможности OpenCL 2.0, добавлен режим emutls, улучшен статический анализатор, проведена ревизия C API, объявлена устаревшей система сборки autoconf.
Улучшения в Clang 3.8:
- Значительно улучен генератор кода для конструкций OpenMP, который теперь генерирует более стабильный и быстрый код. Включена по умолчанию поддержка стандарта OpenMP 3.1 (Open Multi-Processing), предоставляющего средства для применения методов параллельного программирования в программах на языках Си и Си++. Вместо библиотеки GCC OpenMP в Clang используется открытая компанией Intel runtime-библиотека OpenMP, которая при указании флага »-fopenmp» связывается с итоговыми OpenMP-приложениями и выполняет диспетчеризацию потоков в процессе выполнения OpenMP-программы.
Кроме полной поддержки OpenMP 3.1 в новом выпуске также реализована порция возможностей, доступных в OpenMP 4.0/4.5: конструкции map, num_teams, simdlen, hint и thread_limit, директивы «target», «target data», «target enter data» и «target exit data», определение зависимостей между задачами, секции массивов, модификаторы имён для выражений «if», возможность использования выражения linear в директивах управления циклами;
- Экспериментальная поддержка компиляции CUDA. Драйвер определяет наличие установок CUDA, создаёт сценарии компиляции компонентов для хоста и устройства (GPU), связывает выполняемый на стороне устройства код с соответствующим биткодом и генерирует единый объектный файл с кодом для выполнения на стороне хоста и GPU. Поддерживается перезагрузка функций на основе атрибутов, которая позволяет компилировать код CUDA без его разделения на отдельные части для хоста и GPU;
- Режим диагностики »-Wmicrosoft» разбит на серию отдельных флагов, что позволяет выборочно включать определённые подкатегории предупреждений. Флаг »-Wno-microsoft» по-прежнему отключает, а »-Wmicrosoft» включает сразу все предупреждения, специфичные для расширений MSVC;
- Возможность настройки включения отладочной информации DWARF с учётом особенностей различных отладчиков. В частности, можно не включать в файл отладочные данные, которые не поддерживаются или не используются определённым отладчиком, или добавлять специфичные для какого-то отладчика расширения. Предусмотрены три флага:»-ggdb» — адаптация для GDB (после опции можно указать отладочный уровень, например,»-ggdb1»),»-glldb» — адаптация для LLDB,»-gsce» — адаптация для Sony Computer Entertainment debugger;
- Добавлена опция »-fstrict-vtable-pointers», включающая экспериментальный режим улучшенной девиртуализации;
- Улучшены средства передачи в LLVM дополнительной информации о выравнивании указателей для строгих типов, задаваемой в коде через специальные атрибуты. Разыменование некорректно выравненных указателей относится к области неопределённого поведения, так как может привести к крахам или к понижению производительности на архитектурах, требующих обязательного выравнивания указателей;
- Для языка Си улучшена поддержка проверки »__builtin_object_size» и возможность применения специфичных для Си преобразований типов для функций, помеченных атрибутом «overloadable»;
- Расширена поддержка диалекта языка Си, используемого в OpenCL. Добавлены новые возможности OpenCL 2.0: опция »-std=CL2.0», поддержка разделяемой виртуальной памяти (__generic), предварительная поддержка pipes (доступ к памяти по принципу FIFO), атомарные типы (atomic_int, atomic_uint, atomic_long и т.п.), типы для изображений (image2d_depth_t, image2d_msaa_t и т.п.). В общем виде для OpenCL улучшена поддержка векторов, расширены средства диагностики, добавлен оператор »^^», реализована порция новых флагов: -cl-no-signed-zeros, -cl-unsafe-math-optimizations, -cl-finite-math-only, -cl-fast-relaxed-math;
- Улучшены средства статического анализа. В базовый состав включены утилиты scan-build и scan-view, предназначенные для запуска статического анализа для проекта и просмотра результатов проверки. Значительно расширены средства статического анализа лямбда-функций C++, в том числе добавлен межпроцедурный анализ лямбда-приложений. Добавлены новые проверки: некорректное использование vfork () и типа _Nonnull, выявление ошибок локализации в Cocoa-приложениях и т.д.
Основные новшества LLVM 3.8:
- Переведена в разряд устаревших система сборки на базе инструментария autoconf. Поддержка autoconf будет удалена в выпуске LLVM 3.9. В качестве основной системы сборки используется CMake;
- Прекращена поддержка Windows Vista и XP. Для работы LLVM на платформе Windows требуется Windows 7 и старше;
- Добавлена поддержка совместимого с GCC и независящего от особенностей целевых платформ режима хранения локальных переменных emutls (TLS — Thread-Local Storage). При указании флага »-femultated-tls» все обращения к TLS-переменным транслируются в вызов __emutls_get_address, предоставляемый runtime-библиотекой;
- Компоновщик IR Linker разделён на две части: IRMover (перемещает биткод из одного модуля в другой) и Linker (принимает решение о связывании);
- Добавлена опциональная возможность связывания clang и утилит LLVM с одной разделяемой библиотекой libLLVM (для включения следует установить флаг »-DLLVM_LINK_LLVM_DYLIB=ON» в CMake);
- Внесены многочисленные улучшения в бэкенды для архитектур ARM, AArch64, MIPS и PowerPC;
- Для архитектуры x86 повышена эффективность кода сравнения больших целочисленных значений (64-разрядных чисел на 32-разрядных системах);
- Включена по умолчанию оптимизации по перемещению пролога и эпилога функций в статичные блоки кода (shrink-wrapping);
- Прекращена генерация секций .data.rel.ro.local и .data.rel;
- Документированы принципы обеспечения стабильности C API для релизов и экспериментальных веток, а также правила расширения C API; В разряд устаревших переведены функции C API: LLVMLinkModules (следует использовать LLVMLinkModules2), LLVMParseBitcode, LLVMParseBitcodeInContext, LLVMGetBitcodeModuleInContext, LLVMGetBitcodeModule, LLVMGetBitcodeModuleProviderInContext, LLVMGetBitcodeModuleProvider, LLVMCreateExecutionEngine, LLVMCreateInterpreter, LLVMCreateJITCompiler, LLVMAddModuleProvider и LLVMRemoveModuleProvider; Проведена реорганизация заголовочных файлов C API: связанные с типами определения перенесены в Type.h, а обработка ошибок в ErrorHandling.h;
Из параллельно развивающихся проектов, основанных на LLVM, можно отметить:
- KLEE — символьный анализатор и генератор тестовых наборов;
- Runtime-библиотека compiler-rt;
- llvm-mc — автогенератор ассемблера, дизассемблера и других связанных с машинным кодом компонентов на основе описаний параметров LLVM-совместимых платформ.
- Реализация функционального языка программирования Pure;
- LDC — компилятор для языка D;
- Виртуальные машины для Ruby: Rubinius и MacRuby;
- LLVM-Lua
- FlashCCompiler — средство для компиляции кода на языке Си в вид, пригодный для выполнения в виртуальной машине Adobe Flash;
- LLDB — новая модульная инфраструктура отладки, использующая такие подсистемы LLVM как API для дизассемблирования, Clang AST (Abstract Syntax Tree), парсер выражений, генератор кода и JIT-компилятор. LLDB поддерживает отладку многопоточных программ на языках C, Objective-C и C++; отличается возможностью подключения плагинов и скриптов на языке Python; показывает крайне высокое быстродействие при отладке программ большого размера;
- emscripten — компилятор биткода LLVM в JavaScript, позволяющий преобразовать для запуска в браузере приложения, изначально написанные на языке Си. Например, удалось запустить Python, Lua, Quake, Freetype;
- sparse-llvm — бэкенд, нацеленный на создание Си-компилятора, способного собирать ядро Linux.
- CUDA Compiler — позволяет сгенерировать GPU-инструкции из кода, написанного на языках Си, Си++ и Fortran;
- Julia — открытый динамический язык программирования, использующий наработки проекта LLVM.
- Jade (Just-in-time Adaptive Decoder Engine) — универсальный движок для декодирования видео, использующий LLVM для JIT-компиляции адаптивных конфигураций декодера видео, определённых комитетом MPEG Reconfigurable Video Coding (RVC);
- PNaCl (Portable Native Client) — интегрированная в браузер Chrome система, которая позволяет организовать выполнение приложений, написанных на языках C и С++, в специальном изолированном окружении web-браузера, независимо от текущей аппаратной архитектуры;
- PoCL (Portable Computing Language OpenCL) — реализация стандарта OpenCL, независимая от производителей графических ускорителей и позволяющая использовать различные бэкенды для выполнения OpenCL-ядер на разных типах графических и центральных процессоров;
- Likely — открытый предметно-ориентированный язык для распознавания изображений. Алгоритмы распознавания на лету компилируются (JIT) при помощи инфраструктуры LLVM MCJIT для выполнения на одно- или многоядерных CPU, а также на GPU с использованием OpenCL SPIR или CUDA.
- LibBeauty — инструментарий для декомпиляции и обратного инжиниринга, построенный с использованием дизассемблера LLVM и LLVM IR Builder. Приняв на входе объектный файл (.o) на выходе генерирует файл в промежуточном представлении LLVM (.bc или .ll);
- RUST — основанный на LLVM язык программирования, развиваемый компанией Mozilla;
- McSema — фреймворк для преобразования машинного кода в биткод LLVM;
- Swift — основанный на LLVM язык программирования, развиваемый компанией Apple;
- FTL (Fourth Tier LLVM) — JIT-компилятор для движка WebKit;
- Polly — экспериментальный оптимизатор, поддерживающий несколько техник оптимизации циклов и позволяющий организовать автоматическое распараллеливание кода с задействованием OpenMP.
© OpenNet