Wiki

Clone wiki

comp-house.repo / LLVM3.0

Оригинал: http://llvm.org/docs/ReleaseNotes.html

Переводчик: Любимов Алексей.

Условия использования перевода

Вы можете безо всяких ограничений на свое усмотрение читать и ссылаться на этот текст.

Вы НЕ можете копировать этот текст целиком или по частям. Цитирование допускается в пределах абзаца. При цитировании ссылка на этот перевод или оригинал статьи обязательна.

Дело в том, что данный перевод находится в статусе черновика и я хотел бы оставить за собой возможность вносить в него необходимые исправления, поэтому, если вы не можете избежать копирования - не используйте этот текст вообще.

Раз уж речь зашла об улучшении текста перевода, прошу вас - если вы нашли ошибки в переводе полагаете, что какие-то его части можно перевести лучше - пришлите мне свои возражения или свой вариант перевода спорного места и я постараюсь его учесть.

LLVM 3.0 замечания к выпуску.

Написано командой LLVM

Предисловие

Этот документ содержит детальную информацию о выпуске LLVM версии 3.0. Здесь мы опишем статус LLVM, не забывая главные улучшения, произошедшие в инфраструктуре LLVM с предыдущего выпуска, а также улучшения, которые произошли в различных подпроектах LLVM и у некоторых его пользователей. Все выпуски LLVM можно скачать со страницы релизов сайта LLVM.

Чтобы получить больше информации о LLVM, включая информацию о последнем релизе, обращайтесь на основной сайт LLVM. С вопросами и комментариями лучше всего обращаться в список рассылки разработчиков LLVM.

Изменения в статусах подпроектов

На данный момент поставка LLVM 3.0 состоит из кода из основного репозитария LLVM (который, грубо говоря, включает LLVM оптимизаторы, генераторы кода и инструменты поддержки), и репозитарий Clang. В дополнение к этому, проект LLVM включает и других подпроекты, часть из которых находится в разработке. Здесь мы говорим об обновлениях в этих подпроектах.

Clang: C/C++/Objective-C Frontend Toolkit

Clang представляет собой фронтэнд LLVM к языкам C, C++, и Objective-C. Clang разрабатывается с целью помочь пользователю улучшить свое мастерство через предоставление более четкой диагностики, высокий уровень соответствия стандартам, быструю компиляцию и бережливое использование памяти (ОЗУ). Как и LLVM, Clang предоставляет модульную, основанную на библиотеках архитектуру, которую можно использовать для создания или интеграции с другими инструментами разработчика. Clang можно считать готовым к реальному применению на производстве компилятором C, Objective-C, C++ и Objective-C++ на платформе x86 (32 и 64 разряда), а также на платформе Darwin/ARM.

В рамках LLVM 3.0, команда Clang сделала множество улучшений:

  • Существенно улучшена сборка приложений на C++, улучшена стабильность и диагностика.
  • Улучшена поддержка стандарта C++ 2011 (также известного, как "C++'0x"), включая реализацию non-static data member initializers, псевдонимов шаблонов, делегатов конструкторов, циклов на базе интерваловs, а также ко всему прочему implicitly-generated move constructors и move assignment operators. (переводить специфичные обороты не буду, чтоб не запутать читателя)
  • Реализована поддержка некоторых возможностей будущего стандарта C1x, включая static assertions и generic selections.
  • Специально для линукс-поставок улучшено определение путей к системным заголовочным файлам и разделяемым библиотекам (include and linking paths).
  • Некоторые улучшения в поддержке Objective-C, включая:
    • Автоматический подсчет ссылок (ARC), продвинутая модель памяти теперь полностью разделяет память под объекты и C.
    • Инструменты для миграции, чтобы перейти от ручного захват/освобождение кода к ARC (автоматический подсчет ссылок)
    • Улучшение поддержки скрытия данных, позволяющие декларировать пременные экземпляров в реализациях контекста или расширениях классов.
    • Поддержка Weak linking для классов Objective-C.
    • Улучшеная проверка статических типов на основе типов, которые возвращают такие функции, как +alloc или -init. Некоторые новые возможности Objective-C требуют или Mac OS X 10.7 / iOS 5 Objective-C рантайма, или рантайм GNUstep Objective-C начиная с версии 1.6.
  • Проведены множественные оптимизации в libclang, в C-интерфейсе Clang, с целью улучшить производительность дополнения кода и отображения места в исходниках на узлы абстрактного дерева синтаксиса.

Если вам нужно больше детальной информации об изменениях в Clang с момента выпуска версии 2.9 , смотрите замечания к выпуску Clang

Если Clang отбрасывает ваш код, в то время как другие компиляторы принимают его, пожалуйста, прочитайте руководство по совместимости с языком, чтобы быть уверенным, что эта реакция не является желательной или уже известной.

DragonEgg: GCC фронтэнд, LLVM бекэнд

DragonEgg представляет из себя gcc плагин, который заменяет оптимизаторы и генераторы кода GCC на аналоги из LLVM. Он работает с gcc-4.5 или gcc-4.6, целями на базе сеймейств ЦПУ x86-32 и x86-64, и успешно используется на платформах Darwin, FreeBSD, KFreeBSD, Linux и OpenBSD. Полностью поддерживаются Ada, C, C++ и Fortran. Частично поддерживаются Go, Java, Obj-C и Obj-C++.

Релиз 3.0 примечателен следующими изменениями:

  • Отныне полностью поддерживается GCC версии 4.6.
  • Патчить и пересобирать GCC больше не требуется: плагин должен работать с вашим системным GCC (версий 4.5 или 4.6; в системах Debian/Ubuntu также будут нужны пакеты gcc-4.5-plugin-dev или gcc-4.6-plugin-dev).
  • Опция fplugin-arg-dragonegg-enable-gcc-optzns, которая запускает оптимизаторы из GCC также как и из LLVM теперь работает существенно лучшеr. Эта опция предназначена для тех, кто хочет получить максимальную производительность! Она все еще остается экспериментальной и может обрушить плагин.
  • Полностью переписана логика конверсии типов и констант. Исправлена масса неявных багов.

compiler-rt: рантайм компилятора (библиотека времени исполнения компилятора)

Новый проект LLVM под названием compiler-rt представляет собой простую библиотеку реализующую низкоуровневые специфичные для конкретных целей хуки (обработчики), которые требуютсягенераторами кода и другими компонентами в рантайме. К примеру, во время сборки для 32-разрядной цели, процедура перевода double в 64-разрядное беззнаковое целое компилируется в вызов в рантайме функции __fixunsdfdi. Библиотека compiler-rt предоставляет высокооптимизированные реализации данных и других низкоуровневых процедур (некоторые втрое бфстрее, чем их эквиваленты в libgcc).

В рамках релиза LLVM 3.0, специфичный для ARM-целей код был преобразован в "единообразный" синтаксис сборки, а также было добавлено нескольконовых функций.

LLDB: Низкоуровневый отладчик

LLDB представляет собой созданную с нуля реализацию консольного отладчика, которая может быть использована как есть или через API отладчика из других приложений. LLDB использует парсер Clang, чтобы предоставить высококачественный разбор выражений (особенно для C++) и использует LLVM JIT для поддержки целей.

LLDB совершил прорыв в рамках релиза 3.0. Он стал куда более стабильным и удобным в использовании, а также включает новое руководство и сравнение плечом к плечу с GDB.

libc++: Стандартная библиотека C++

Как и compiler_rt, libc++ отныне находится под двойной лицензией MIT и UIUC, позволяющей более свободно использовать эти библиотеки.

Libc++ была портирована на FreeBSD и вошла в базовую систему. К выходу FreeBSD 10 планируется сделать ее основной реализацией STL.

VMKit

Проект VMKit представляет собой реализацию виртуальной машины Java (Java VM или JVM), которая использует LLVM для статической и just-in-time компиляции.

В рамках LLVM 3.0, VMKit получил значительные улучшения производительности как при запуске, так и во время исполнения:

  • Прекомпиляция: за счет предварительной компиляции (AOT) небольшой части основной (core) Java-библиотеки, производительность при запуске была значительно улучшена. Так, для запуска программы 'Hello World' теперь требуется менее 30 миллисекунд. Кастомизация: При адаптации виртуальных методов для отдельных классов, VM теперь может статически определить цель виртуального вызова и попытаться включить ее инлайном.
  • Инлайнинг: VM теперь чаще чем раньше применяет инлайнинг, за счет того, что позволяет большему количеству инструкций байткода быть использоваными в инлайнинге и благодаря кастомизации. Он также использует инланинг для GC-барьеров и размещений объектов.
  • Новая модель исключений: генерирукмый для методов код, который не использует никаких try/catch более на наказывается через случайный вызов метода, который вызывает исключение. Вместо этого, метод, который вызывает исключение переходт прямов в том метод, который перехватывает это исключение.

LLBrowse: IR браузер

LLBrowse представляет собой интерактивный просмотрщик модулей LLVM. Он может загрузить любой модуль LLVM и отобразить его содержимое в виде раскрывающегося дерева, позволяя по простому проинспектировать узлы с типами, функциями, глобальными переменными или метаданными. Он полнустью кросс-платформенен и основан на популярном GUI тулките wxWidgets.

Внешние проекты с открытым исходным кодом, которые используют LLVM 3.0

Один из самых интересных аспектов LLVM является то, что он позволяет существовать многим проектам, реализующим свои языки и инструменты. В этом разделе перечислены некоторые из этих проектов, которые были обновлены для работы с LLVM 3.0.

AddressSanitizer

AddressSanitizer использует инструментарий компилятора и специализированную библиотеку malloc для поиска таких ошибок C/C++, как использование после освобождения (use-after-free) и вфход за границы кучи (out-of-bound accesses to heap), стэка и глобальности. Ключевой возможностью этого инструмента является скорость: AddressSanitizer замедляет программу в среднем менее, чем вдвое.

ClamAV

Clam AntiVirus представляет собой свободный (GPL) антивирусный комплект инструментов для UNIX, специально спроектированный для сканирования почты на почтовых шлюзах.

Начиная с версии 0.96 он использует сигнатуры в байткоде, которые позволяют писать комплексные определители вредоносного кода. Он использует LLVM JIT для увеличения скорости выполнения байткода на X86, X86-64, PPC32/64, в ином случае возвращаясь к использованию своего интерпретатора. git версия была обновлена для работы с LLVM 3.0.

clang_complete для VIM

clang_complete представляет собой VIM плагин, который предоставляет аккуратное C/C++ автодополнение, используя clang. Разрабатываемая версия clang complete может напрямую использовать libclang, которая может вести кеш для ускорения автодополнения.

clReflect

clReflect представляет собой парсер C++, который использует clang/LLVM для реализации легковесных отображений баз данных, пригодных для использования в разработке игр. clReflect поставляется с очень маленькой рантайм библиотекой для загрузки и запросов в базу данных, не имеет внешних зависимостей (включая CRT), а также несет дополнительную вспомогательную библиотеку для управления объектами и сериализации.

Cling C++ интерпретатор

Cling придставляет собой интерактивный интерфейс компилятора (другими словами C++ интерпретатор). Он поддерживает C++ и C и использует LLVM JIT и парсер Clang. Cling интерфейс со строкой запроса, исполняет исходные файлы, осуществляет вызовы в разделяемые библиотеки, печатаетзначения выражений, а также делает лукап идентификаторов в рантайме (dynamic scopes). И вообще программа ведет себя так, как это ожидается от интерпретатора.

Язык программирования Crack

Crack направлен на создание простого в разработке скриптового языка программирования, наделенного быстродействием компилируемого языка. Язык унаследовал концепции из C++, Java и Python, впитал парадигму объектно-ориентированного программирования, перезагрузку операторов и строгую типизацию.

Eero

Eero представляет собой полностью бинарно и по заголовкам совместимый диалект Objective-C 2.0, реализованный с использованной измененной версии компилятора Clang/LLVM. Среди его возможностей потоковый синтаксис, отсупы и новые операторы в стиле Python, которые внесены с целью улучшить читабельность кода. В нем также есть новые возможности, такие как ограниченые формы перезагрузки операторов и пространств имен и строгих (тип и оператор безопасных) енумераторов. Он сделан в духе таких языков, как Smalltalk, Python и Ruby.

FAUST Язык программирования для обработки звука в реально времени

FAUST представляет собой компилируемый ЯП для обработки звука в реальном времени. Название FAUST основано на выражении "Functional AUdio STream". Язык представляет собой комбинацию двух подходов: функционального программирования и блок-схемы. На выходе, в дополнение к C, C++, Java форматам,компилятор фауста теперь может генерировать LLVM биткод и работает с LLVM 2.7-3.0.

Glasgow Haskell Compiler (GHC)

GHC представляет собой свободную, современную систему программирования на Haskell, стандарт функционального языка программирования с ленивыми вычислениями. Он включает в себя оптимизирующий статический компилятор, который генерирует неплохой код для различных платформ и интерактивную систему для удолбной и быстрой разработки.

GHC начиная с версии 7.0 содержит генератор кода LLVM, поддерживающий LLVM 2.8 и выше. Начиная с LLVM версии 2.9, GHC включает экспериментальную поддержку ARM платформ с LLVM 3.0. (?)

gwXscript

gwXscript представляет собой объектно-ориентированный, предметно-ориентированный язык программирования, который может создавать исполняемый файлы форматов ELF и EXE, а также разделяемые библиотеки форматов DLL, SO, DYNLIB. Компилятор написан на самом языке и транслирует скрипты в LLVM-IR, уоторый в свою очередь умеет оптимизировать и транслировать этот код далее в машинные инструкции через LLVM. Исходные файлы в gwScript содержат определения, которые расширяют пространства имен, так что вы можете собрать свой проект и просто отключать части, удаляя файлы. Оставшаяся часть проекта не пострадает, поскольку вы прямо разделяете сущности через возможность gwX, называемую "шаблоны". Также есть возможность добавлять новые возможности в проект просто добавляя файлы и не редактируя оригинальный проект. Этот язык используется, к примеру, для создания игр или CMS. которые должны быть расширяемыми.

gwXscript использует строгую типизацию и позволяет с комфортом работать с родными типами строка, хеш и массив. Также можно легко писать новые библиотеки на gwXscript или в родном коде. gwXscript безопасен к типам и пользователи могут не волноваться о сбоях программы или запуске враждебного кода за исключением кода, пожирающего процессорное время.

include-what-you-use

include-what-you-use представляет собой инструмент, который позволяет убедиться, что файл включает в себя все заголовочные (.h) файлы, которые предоставляют символы, которые этот файл использует.

ispc: Intel компилятор программ SPMD

ispc представляет собой компилятор для программ "Одна программа, множество данных" ("single program, multiple data") (SPMD). Он компилирует программы с основанного на C ЯП SPMD для запуска на процессорных юнитах SIMD ; он позволяет в 5-6 раз повыситьскорость одного ядра ЦПУ с 8микратным SIMD юнитом по сравнению с последовательным кодом, оставаясь при этом языком с чистой и легкой для понимания моделью программирования. Чтобы аойти в курс дела этого языка и его производительности, смотрите обзор коротких программ-примеров. ispc выпущен под лицензией BSD.

Язык программирования Julia

Julia представляет собой высокоуровневый, высокопроизводительный динамический язык для технических вычислений. Он предлагает мощный компилятор, распределенные параллельные вычисления, цифровую точность и обширную библиотеку математических функций. Компилятор использует вывод типов для генерации быстрого кода без какого-либо указания типов и использует оптимизирующие проходы LLVM, а также компилятор JIT. Этот язык спроектирован вокруг множественных пересылок, делающий программы в большей степени гибкими. Он готов к использованию в различных областях.

LanguageKit и Pragmatic Smalltalk

LanguageKit представляет собой фреймворк для реализации динамических языков, использующих общую с Objective-C модель объектов. Он предоставляет статическую и JIT компиляцию посредством LLVM параллельно со своим собственным интерпретатором. Pragmatic Smalltalk представляет собой диалект Smalltalk, собраный поверх LanguageKit, чьи интерфейсы напрямую с Objective-C разделяют общее представление объектов и механизм отправки сообщений. Эти проекты разрабатываются как часть десктопного окружения Étoilé.

LuaAV

LuaAV представляет собой среду для программирования реального времени аудио-видео, основанную на языке Lua и коллекции библиотек для работы со звуком, графикой и различными медиапротоколами. LuaAV использует LLVM и Clang для эффективной JIT компиляции синтезирующих звук шаблонов, которые пользователь определяет в декларативном синтаксисе.

Mono

Одна из свободных кроссплатформенных реализаций C# и CLR, которая бинарно совмсестима с Microsoft.NET. Включает в себя необязательный динамически подгружаемый генератор кода LLVM в Mini, компилятор JIT. (? смысл утерян)

Замечание, они используют зеркало Git LLVM с некоторыми патчами.

Polly

Polly представляет собой продвинутый оптимизатор расположения данных и автоматический распараллеливатель. Он использует продвинутуе же математическиую модель расчета зависимостей в данных, которая используется для оптимизации циклов в программе. Polly может ускорить последовательный код оптимизируя размещение памяти и, как следствие, использование кеша. Более того, Polly позволяет раскрыть различные области параллельного вычисления, которые могут быть открыты введением в основы OpenMP и SIMD кода.

Portable OpenCL (pocl)

Переносимый OpenCL представляет собой свободную реализацию стандарта OpenCL, которая может быть легко адаптирована к новым целям(платформам). Одной из целей проекта является улучшение производительности портируемых OpenCL программ, без необходимости проведения специфичных для конкретных целей (платформ) ручных оптимизаций. "Родные" цели тоже включены, что позволяет запускать ядра OpenCL на хосте (ЦПУ).

Pure

Pure представляет собой алгебраический/функциональный язык программирования основанный на перезаписи выражений. Программы являются набором уравнений, которые используются для вычисления выражений в символьной форме. Интерпретатор использует LLVM, как бекэнд для JIT-компиляции программ Pure в быстрый нативный код. Pure позволяет динамическую типизацию, строгие и ленивые вычисления, лексические замыкания, здравую макро систему (тоже основаную на перезаписи выражений), встроенную поддержку списков и матриц (включая их дополнение (list and matrix comprehensions) и простой в использовании интерфейс к C и другим языкам программирования (в том числе возможност загрузки модулей биткода LLVM и вставки кода на C, C++, Fortran и Faust в программы на Pure, в тех случаях, когда установлен соотвествующий LLVM-компилятор).

Pure в версии 0.48 был протестирован и показал свою работоспособность с LLVM 3.0 (и продолжает работать с более ранними релизами LLVM >= 2.5).

Renderscript

Renderscript представляет собой мощный программный интерфейс для визуализаци и обработки 3d-графики на платформе Андройд. Он предоставляет переносимый основаный на C99 язык с расширениями для решению стандартных задач в области улучшения параллельности на уровне потоков и графики. Компилятор Renderscript основан на Clang/LLVM. Он выдает переносимый биткод для реального компилируемого скрипт-кода также, как java-интерфейс отображает для разработчиков, чтобы дать возможность управлять исполнением скомпилированным биткодом. Исполняемый машинный код генерируется посредством LLVM на устройстве. Renderscript предоставляет разработчикам под андройд механизм, который позволяет увеличить производительность приложения без ущерба переносимости на другие платформы.

SAFECode

SAFECode представляет собой компилятор C/C++ с безопасным распределением памяти, который был создан с использованием LLVM. Он берет обычный неаннотируемый код C/C++, анализирует этот код с точки зрения безопасности обращения к памяти и операций с индексами массивов и дополняет код проверками в рантайме тогда, когда безопасность не может быть обеспечена статически. SAFECode может быть использован, как помощь в отладке (как Valgrind) для поиска и лечения ошибок связанных с безопасностью работы с памятью. Он также может быть использован для защиты кода от атак на безопасность в рантайме.

The Stupid D Compiler (SDC)

Проект "тупой компилятор D" представляет собой попытку написать самодостаточный компилятор для языка программирования D без использования фронтэнда образцового компилятора (DMD).

TTA-based Co-design Environment (TCE)

TCE представляет собой набор инструментов для проектирования процессоров, специфичных для приложения (application-specific processors - ASP), который основан на Transport triggered architecture (TTA). Проект предоставляет полный цикл проектирования из программ на C/C++ в синтезируемый VHDL и параллельные исполняемые программы. Аспект адаптации процессора включает регистрацию файлов, функциональные модули, поддерживаемые операции и сеть коммуникаций.

TCE использует Clang и LLVM для поддержки языка C/C++, независимую от целей оптимизацию и часть генерации кода. Он на лету создает новые, основанные на LLVM генераторы кода для проектирования TTA процессоров и затем загрузки их в бекэнд компилятора, как рантайм-библиотеки, с целью избежать перекомпиляции больших частей компилятора и сопутствующих инструментов (compiler chain).

Язык программирования Tart

Tart представляет собой универсальный язык программирования со строгой типизацией, который был спроектирован для разработки приложений. Будучи сильно в духе Python и C#, Tart сфокусирован на практических решениях для профессиональных разработчиков ПО, избегая при этом хаоса и навязчивых шаблонов архаичных (legacy) языков типа Java и C++. Несмотря на то, что Tart находится в разработке, текущая реализация поддерживает многие возможности, которые ожидают от модных ЯП, таких как уборка мусора, полноценный двунаправленный вывод типов, очень простой синтаксис для метапрограммирования шаблонами, замыкания и функциональные литералы, отображения, перегрузка операторов, ясная изменчивость (mutability) и неизменчивость (immutability) и много чего другого. Tart досточно гибок, чтобы вобрать в себя широкий диапазон философий и стилей программирования, обязуясь при этом и дальше оставаться простым, минималистичным и элегантным в проектировании.

ThreadSanitizer

ThreadSanitizer представляет собой детектор гонок по данным, в основном, для кода на C и C++, который доступен для Linux, Mac OS и Windows. В раных системах они используют разные бинарные инструментальные фреймворки (Valgrind или Pin) в качестве фронэендов для генерации программных событий для своего алгоритма детектирования гонок. В линуксе есть возможность использовать основаный на LLVM инструментарий времени компиляции.

Что нового в LLVM 3.0?

Этот релиз включает множество исправлений ошибок, подстройки производительности и небольших улучшений. Некоторые крупные улучшения перечислены в этом разделе.

Новые возможности

LLVM 3.0 включает несколько крупных изменений и заметных улучшений:

  • llvm-gcc больше не поддерживается и вообще не включен в релиз. Мы рекомендуем перейти к Clang или DragonEgg.
  • Линейный сканирующий регистрирующий аллокатор был заменен на новый "greedy" регистрирующий аллокатор, позволяющий разделять на лету интервалы и включающий множество других оптимизаций, которые ведут к повышению качества кода. Чтобы узнать больше, читайте пост в его блоге или поговорите на встрече с разработчиками.
  • LLVM IR теперь включает полную поддержку атомарных операций с памятью напрвленную на поддержку моделей памяти C++'11 и C'1x. Среди этих операций атомарная загрузка и сохранение, сравнение и обмен, а также инструкции чтение/изменение и чтение/изменение/запись также как и полный набор ограничений на выделение памяти. Чтобы узнать побольше, см. руководство по атомарным операциям.
  • Представление поддержки исключений LLVM IR было полностью перепроектировано и переписано с целью сделать его более элегантным, исправить множество ошибок, включить инлайнинг и другие оптимизации. Чтобы узнать побольше об этом, читайте пост в блоге и документацию на управление исключениями.
  • Система типов LLVM IR тоже была полностью переписана с целью ускорения и решения долгоиграющих проблем. См. пост в блоге, чтобы узнать побольше об этом.
  • MIPS бекэнд совершил в этом релизе большой скачок, перейдя из экспериментальной цели в условно готовый к производству по качеству и поддержке широкого спектра MIPS подцелей. Чтобы узнать больше, см. дале раздел MIPS.
  • Оптимизатор и генератор кода теперь поддерживают gprof и gcov-стили покрытия (coverage) и информации профилирования, а также включают новый инструмент llvm-cov (хотя продолжают работать и с gcov). Clang представляет покрытие (coverage) и профайлинг через совместимые с GCC опции командной строки.

LLVM IR и улучшения в ядре

LLVM IR получил несколько новых возможностей, чтобы лучше поддерживать новые цели и раскрыть новые варианты оптимизации:

  • Атомарный доступ к памяти и учет памяти теперь могут быть напрямую выражены в IR.
  • Новый встроенный llvm.fma напрямую представляет операции сложения и умножения с плавающей точкой без промежуточной стадии округления.
  • Новый встроенный llvm.expect (XXX не документирован в руководстве по языку) позволяет фронтэнду вычислять ожидаемое управление потоком (и встроенный в GNU C __builtin_expect).
  • Внутренний llvm.prefetch теперь принимает четвертый аргумент, который обозначает, должна ли быть предварительная загрузка из icache или dcache.
    • Новый атрибут функции uwtable позволяет фронтэнду управлять выпуском таблиц unwind.
    • Новый атрибут функции nonlazybind позволяет оптимизировать доступ к глобальной таблице смещений (Global Offset Table GOT).
    • Новый атрибут returns_twice позволяет лучше моделировать функции типа setjmp.
    • Цель строка datalayout умеет теперь кодировать естественное выравнивание в стеке цели для лучшей оптимизации.

Улучшения в оптимизаторе

в дополнение к множеству мелких подстроек производительности и исправлениям ошибок,в этот релиз попали несколько важных улучшений и дополнений в оптимизаторах:

  • менеджер проходов теперь имеет API для расширений, который позволяет фронтэндам и плагинам вставлять свои оптимизации в общеизвестных местах стандартного прохода оптимизации.
  • Информация о вероятности ветвления и частоте повторения базовых блоков теперь доступна с LLVM, на основе комбинации из эвристического предсказания ветвлений и вызовов __builtin_expect. Эта информация на текущий момент используется для учета выпадений и условной конвертации, а в следующих релизах планируются и другие оптимизации. Этот же фреймворк предназначен для возможного использования совместно с определяемыми профилем оптимизациями.
  • "-indvars" запускает проход упрощения переменных, который меняет выпуск переменных, только когда это выгодно. Знаковые и нулевые расширения убираются, тесты последовательных функций подменяются, циклы разворачиваются, проводятся и другие упрощения, которые требуют обобщеного индуктивного анализа переменных, поскольку они больше не требуют перезаписи циклов в каноничную форму для оптимизации. Этот новый дизайн сохраняет больше информации уровня IR, избегая отката ранних оптимизаций циклов (особенно вручную оптимизированных циклов), а также более не требуется генератор кода для перестройки циклов в оптимальную форму - это одна из трудноизлечимых проблем.
  • LLVM теперь включает проход оптимизации retain/release вызовов для Автоматического подсчета ссылок (ARC), возможности языка Objective-C (в lib/Transforms/Scalar/ObjCARC.cpp). Это простой пример реализации специфической для исходников языка оптимизации в LLVM.

Улучшения уровня MC

Подсистема машинный кодв в LLVM (или MC) была создана с целью решить ряд проблем в области ассемблирования, дизассемблирования, управления форматами объетных файлов и других проблем в области работы инструментов уровня набора инструкций ЦПУ. Чтобы узнать больше, см. вводный пост в блоге проекта LLVM MC.

  • Уровень MC подвергся значительному рефакторингу с целью убрать нарушения в разделении на уровни, которые вызывают напряжение в коде бекэнда компилятора LLVM.
  • Код, записывающий файлы ELF-объектов получил множество новых возможностей.
  • Встроенный ассемблер теперь поддерживает директиву #line.
  • Реализация раннего JIT сделаная поверх фреймворка MC (известного как MC-JIT) постепенно заменит старый JIT. Он вбрасывает объекты файлов прямо в память и использует динамический линковщик для разименовывания ссылок и проведения ленивой компиляции. MC-JIT позволяет переиспользовать значительно улучшеный код между JIT и статическим компилятором и в результате предлагает лучшую интеграцию с ABI платформы.
  • Принтер ассемблера теперь использует псевдонимы инструкций вссемблеров (InstAliases) для печати простых мнемоник, когда это возможно.
  • TableGen теперь умеет автогенрировать MC расширения логики в псевдоинструкциях, которые раскрываются в множество MC инструкций (через класс PseudoInstExpansion).
  • Новый инструмент llvm-dwarfdump старт замены для соответствующих инструментов, которые используют библиотеки LLVM. Как часть этого, LLVM начал библиотеку разбора dwarf.
  • llvm-objdump получил более полный вывод, включая дизасемблирование символ за символом, инлайн перемещения, заголовки разделов, таблицы символов и содержимое разделов. А еще была добавлена поддержка архивов.
  • llvm-nm приобрел поддержку архивов двоичных файлов.
  • Добавили llvm-size. Этот инструмент печатает размеры разделов.

Независимые от цели улучшения генератора кода

Мы вложили значительные усилия в инфраструктуру генератора кода, благодаря чему мы можем реализовать более агрессивные алгоритмы и заставить его работать быстрее:

  • LLVM теперь умеет производить код, который работает с libgcc для динамического размещения сегментов стека в противовес размещению кусков (chunk) виртуальной памяти в наихудшем случае для каждой нити.
  • LLVM генерирует в значительной степени более лучший код для непрямых переходов за счет нового прохода хвостовых повторов (tail duplication pass), который может значительно улучшить производительность для тех циклов интерпретатора, которые он использует.
  • Управление исключениями и выход отладочной информации теперь происходит с директивами CFI, что дает ассемблеру возможность производить более компактную информацию, поскольку он знает конечные смещения, выпускать заметно меньшие исполняемые файлы для некоторых C++ приложений. Если системный ассемблер не поддерживает их, MC раскрывает директивы, когда встроенный ассемблер не используется.
  • Генратор кода теперь поддерживает векторные операции "select" в сравнениях векторов, включая их в различные последовательности оптимизированного кода (к примеру, используя SSE4/AVX "blend" инструкции).
  • Проходы исправления исполняемой области SSE (SSE execution domain fix pass) и ARM NEON исправление перемещений (move fix pass) были слиты в независимый от цели проход исправления зависимостей исполнения (execution dependency fix pass). Жтот проход используется для выбора альтернативных эквивалентов опкодов на пути минимизации пересечений исполняемых областей. Близко соединенные инструкции перемещаются в одну исполняемую область, когда это возможно. Цел могут переназначать хуки getExecutionDomain и setExecutionDomain, чтобы использовать этот проход.

Улучшения в X86-32 и X86-64 целях

Новые возможности и главные изменения в цели X86 включают:

  • Бекэнд X86, ассемблер и дизассемблер теперь полностью поддерживают AVX 1. Чтобы включить поддержку передайте в компилятор -mavx. AVX2 реализация на пути реализации в основной линии.
  • Интегрированный ассемблер и дизассемблер теперь поддерживают широкий диапазон новых инструкций включая Atom, инструкции Ivy Bridge, SSE4a/BMI, rdrand и многие другие.
  • Бекэнд X86 теперь полностью поддерживает встраиваемые ограничения сборок (inline assembly constraints) стека плавающей запятой X87.
  • Интегрированный ассемблер теперь поддерживает директивы .code32 и .code64, чтобы переключаться между 32-bit и 64-bit инструкциями.
  • Бекэнд X86 теперь синтезирует горизонтальные add/sub инструкции из обычного векторного кода когда соответвующие инструкции включены.
  • Бекэнд X86-64 генерирует меньший и более быстрый код при -O0 за счет улучшений в выборе быстрых инструкций.
  • Добавлена поддержка родных клиентских подцелей.
  • Внутренняя CRC32 была переименована. Внутренности, которые были @llvm.x86.sse42.crc32.[8|16|32] и @llvm.x86.sse42.crc64.[8|64]. теперь переименованы в @llvm.x86.sse42.crc32.32.[8|16|32] и @llvm.x86.sse42.crc32.64.[8|64].

Улучшения в ARM-цели

Новые возможности в цели ARM включают:

  • Бекэнд ARM генерирует многократно более быстрый код для чипов Cortex-A9.
  • Бекэнд ARM усилил поддержку для процессоров серий Cortex-M.
  • Реализованы и полностью поддерживаются ограничения внедряемых сборок (inline assembly constraints) ARM.
  • Производимый Clang код для NEON частенько исполняется быстрее за счет улучшений в скалярных заменах во время агрегатирующего прохода (Aggregates pass).
  • Старый ARM дизассемблер заменен на новый, который сделан на основе автогенерируемой кодировочной информации из ARM .td файлов.
  • Интегрированный ассемблер совершил большой скачок аперед, но все еще находится на уровне беты в LLVM 3.0.

MIPS Target Improvements

Этот релиз примечателен серьезной работой в каждом аспекте MIPS бекэнда. Самое главное из новых возможностей составляет:

  • Большинство MIPS32r1 и r2 инструкции теперь поддерживаются.
  • LE/BE MIPS32r1/r2 был интенсивно протестирован.
  • O32 ABI было полностью протестировано.
  • Бекэнд MIPS был перенесен на инфраструктуру MC для сборки печати. Также была сделана начальная поддержка прямой эмиссии объектного кода.
  • Отложенный заполнитель слота был обновлен. Теперь он пытается заполнить отложеные слоты полнофункциональными инструкциями вместо того, чтобы всегда заполнять их NOPами.
  • Поддержка старого стиля JIT готова.
  • Удалена поддержка старых архитектур (MIPS1 и MIPS2).
  • Добавлена начальная поддержка MIPS64.

Улучшения в цели PTX

Бекэнд PTX все еще остается экспериментальным, но он довольно пригоден для ядер вычислений в LLVM 3.0. Большая часть скалярной арифметики реализована, также ка внутренний доступ к специальным PTX регистрам с инструкциям синхронизации. Важнейшее из пропущенных частей составляет поддержка texture/sampler и некоторые векторные операции.

Это означает, что бекэенд может полноценно использоваться в локально-специфичных языках и может быть использован Clang для компиляции OpenCL C кода в PTX.

Другие специфичные к целям улучшения

  • Многие улучшения PowerPC были реализованы для ELF-целей, включая поддержку varargs и начальную поддержку прямого выхода файла .o.
  • (не могу понять, кто на ком и куда) MicroBlaze scheduling itineraries were added that model the 3-stage and the 5-stage pipeline architectures. Трехступенчатая модель конвейера может быть выбрана ключом -mcpu=mblaze3, а 5-ступенчатая ключом -mcpu=mblaze5.

Большие изменения и возможности, которые были удалены

Если вы уже являетесь пользователем LLVM или разработчик со своими внесистемными изменениями на основе LLVM 2.9, в этом списке перечислены некоторые "плюхи" которые вы можете поймать при обновлении с предыдущего релиза.

  • В LLVM 3.0 удалена поддержка чтения файлов LLVM версии 2.8 и ранее, а LLVM 3.1 уничтожит поддержку чтения файлов LLVM версии 2.9. Следуя вперед, мы поможем всем будущим версиям LLVM читать файлы биткода и файлов .ll, произведеных LLVM 3.0.
  • От Tablegen была отделена библиотека, благодаря которой clang tblgen части отныне существуют в дереве clang. Llvm версия была переименована в llvm-tblgen вместо tblgen.
  • LLVMC драйвер мета компилятора был удален.
  • Неиспользуемые PostOrder Dominator Frontiers и LowerSetJmp проходы были удалены.
  • Старый TailDup проход не использовался в стандартной последовательности и не позволял обновить форму ssa, так что его тоже удалили.
  • Синтаксис переменчивой загрузки и хранения в IR был изменен на "load volatile"/"store volatile". Старый синтаксис ("volatile load"/"volatile store") продолжает приниматься, но отныне объявлен устаревшим и будет удален в 3.1.
  • Тесты фронтенда llvm-gcc были удален из llvm/test/Frontend* и погружен в clang и dragonegg тесты.
  • Старые атомарные внутренние (llvm.memory.barrier и llvm.atomic.*) ушли. Пожалуйста, используйте новые атомарные инструкции, описанные в руководстве по атомарности.
  • Конфигурационные скрипты LLVM более не зависят от llvm-gcc, удалены странные круговые зависимости между проектами.

Windows (32-bit)

На Win32(MinGW32 и MSVC), Windows 2000 не будет поддерживаться. Требуется Windows XP или выше.

Изменения во внутреннем API

Ко всему прочему, в этом релизе было много изменений в API. К важным изменениям LLVM API относятся:

  • Наибольшим и самым всеобъемлющим изменением стало то, что была переписана система типов: PATypeHolder и OpaqueType ушли, и все API теперь имеют дело с Type* вместо const Type*. Если вам необходимо создать рекурсивные структуры, когда создаете именованную структуру используйте setBody(), когда все ее элементы созданы. Слияния и возгонки (refining) типов тоже больше нет: именованные структуры не сливаются с другими структурами, если только их раскладка не идентична. (само собой, анонимные структуры остаются уникальными по раскладке).
  • PHINode::reserveOperandSpace был удален. Взамен при создании PHINode вы должны передать дополнительный аргумент , в котором указать, сколько у вас операндов для резервирования пространства.
  • PHINodes более не хранит свои входящие BasicBlock-икак операнды. Вместо этого, список входящих BasicBlock-ов хранится отдельно и может быть доступен через новые функции: PHINode::block_begin и PHINode::block_end.
  • Различные функции теперь берут ArrayRef вместо или пары указателей (или итераторов) для начала и конца диапазона, или указателя и длинны. Другие функции возвращают ArrayRef вместо ссылки на SmallVector или std::vector. Эти функции включают:
    • CallInst::Create
    • ComputeLinearIndex (in llvm/CodeGen/Analysis.h)
    • ConstantArray::get
    • ConstantExpr::getExtractElement
    • ConstantExpr::getGetElementPtr
    • ConstantExpr::getInBoundsGetElementPtr
    • ConstantExpr::getIndices
    • ConstantExpr::getInsertElement
    • ConstantExpr::getWithOperands
    • ConstantFoldCall (in llvm/Analysis/ConstantFolding.h)
    • ConstantFoldInstOperands (in llvm/Analysis/ConstantFolding.h)
    • ConstantVector::get
    • DIBuilder::createComplexVariable
    • DIBuilder::getOrCreateArray
    • ExtractValueInst::Create
    • ExtractValueInst::getIndexedType
    • ExtractValueInst::getIndices
    • FindInsertedValue (в llvm/Analysis/ValueTracking.h)
    • gep_type_begin (in llvm/Support/GetElementPtrTypeIterator.h)
    • gep_type_end (in llvm/Support/GetElementPtrTypeIterator.h)
    • GetElementPtrInst::Create
    • GetElementPtrInst::CreateInBounds
    • GetElementPtrInst::getIndexedType
    • InsertValueInst::Create
    • InsertValueInst::getIndices
    • InvokeInst::Create
    • IRBuilder::CreateCall
    • IRBuilder::CreateExtractValue
    • IRBuilder::CreateGEP
    • IRBuilder::CreateInBoundsGEP
    • IRBuilder::CreateInsertValue
    • IRBuilder::CreateInvoke
    • MDNode::get
    • MDNode::getIfExists
    • MDNode::getTemporary
    • MDNode::getWhenValsUnresolved
    • SimplifyGEPInst (in llvm/Analysis/InstructionSimplify.h)
    • TargetData::getIndexedOffset
  • все формы StringMap::getOrCreateValue были убраны за исключением тех, которые берут StringRef.
  • функция LLVMBuildUnwind была удалены из C API. LLVM инструкция unwind долгое время была объявлена устаревшей и не использовалась в текущих фронтэндах. Так что он был удален во время переписывания поддержки исключений.
  • Функция LLVMAddLowerSetJmpPass была удалена из C API потому что был удален проход LowerSetJmp.
  • Интерфейс DIBuilder использовался фронтэндами для кодирования отладочной информации в LLVM IR теперь ожидает, что клиенты будут использовать DIBuilder::finalize() в конце модуля трансляции для завершения кодирования отладочной информации.
  • TargetSelect.h перемещен в Support/ из Target/
  • UpgradeIntrinsicCall более не обновляет встроенные вызовы pre-2.9 (к примеру llvm.memset.i32).
  • Теперь обязательно инициализировать все проходы вне дерева также, как и их зависимости через INITIALIZE_PASS{BEGIN,END,} и INITIALIZE_{PASS,AG}_DEPENDENCY.
  • Интерфейс MemDepResult в MemoryDependenceAnalysis был улучшен новыми возвращаемыми типами Unknown и NonFuncLocal, в дополнение к существующим типам Clobber, Def, и NonLocal.

Известные проблемы

LLVM в основном является пригодным для производства компилятором, его используют в широком спектре приложений и поставляют во множестве продуктов. Тем не менее не все подсистемы достаточно зрелы в совокупности, особенно дополнительные мутные цели. Если вы поймали проблему, пожалуйста, проверьте базу ошибок LLVM и отправьте ошибку, если такой там еще нет или спросите в списке рассылки LLVMdev.

Известные проблемные области включают в себя:

  • Alpha, Blackfin, CellSPU, MSP430, PTX, SystemZ и XCore бекэнды являются экспериментальными, а Alpha, Blackfin и SystemZ цели были удалены из основной линии.
  • Интегрированный ассемблер, дизассемблер и JIT не поддерживаются на некоторых целях. Если интегрированный ассемблер не поддерживается, необходим системный ассемблер. Чтобы узнать побольше, см. матрицу возможностей целей.
  • C бекэнд имеет множество проблем и не слишком активно поддерживается, вследствие чего не рекомендуем его для чего-то серьезного.

Дополнительная информация

Огромное количество различной информации доступно на странице LLVM, особенно в разделе с документацией. Еще на страницах расположились версии документации на API, которые обновляются в связке с версией кода в сабверсион. Еще можно получить доступ к версиям документов, зайдя на соответствующую этому релизу директорию в "llvm/doc/" в дереве LLVM.

Если у вас все еще есть вопросы или комментарии относительно LLVM, не сочтите за труд связаться с нами через списки рассылки.

Updated