Из Википедии, бесплатной энциклопедии
Перейти к навигации Перейти к поиску

LLVM компилятор инфраструктурный проект представляет собой набор компиляторов и ToolChain технологий, [4] , которые могут быть использованы для разработки переднего конца для любого языка программирования и задней часть для любой архитектуры набора команд . LLVM разработан на основе независимого от языка промежуточного представления (IR), которое служит переносимым высокоуровневым языком ассемблера, который можно оптимизировать с помощью различных преобразований за несколько проходов. [5]

LLVM написана на C ++ и предназначена для компиляции , времени компоновки , времени выполнения и оптимизации «простаивает время». Первоначально реализованный для C и C ++, не зависящий от языка дизайн LLVM с тех пор породил широкий спектр интерфейсов : языки с компиляторами, которые используют LLVM, включают ActionScript , Ada , C # , [6] [7] [8] Common Lisp , Crystal , CUDA , D , Delphi , Dylan , Fortran , Graphical G, [9] Halide , Haskell , байт-код Java , Джулия , Котлин , Lua , Objective-C , OpenCL , [10] PostgreSQL SQL и PLpgSQL, [11] Ruby , [12] Rust , Scala , [13] Swift , Ксоджо и Зиг .

История [ править ]

Проект LLVM стартовал в 2000 году в Университете Иллинойса в Урбана-Шампейн под руководством Викрама Адве и Криса Латтнера . LLVM изначально разрабатывался как исследовательская инфраструктура для исследования методов динамической компиляции для статических и динамических языков программирования . LLVM был выпущен под Университетом штат Иллинойс / NCSA Open Source License , [3] с разрешающей бесплатной лицензией программного обеспечения . В 2005 году Apple Inc. наняла Латтнера и сформировала команду для работы над системой LLVM для различных целей в системах разработки Apple. [14]LLVM является неотъемлемой частью последних инструментов разработки Apple для macOS и iOS . [15]

Название LLVM изначально было инициализмом для низкоуровневой виртуальной машины . Это сокращение было официально удалено, чтобы избежать путаницы, поскольку LLVM превратился в зонтичный проект, который имеет мало отношения к тому, что большинство нынешних разработчиков считают (точнее) процессными виртуальными машинами . [16] Теперь LLVM - это бренд, который применяется к зонтичному проекту LLVM, промежуточному представлению LLVM (IR), отладчику LLVM, реализации LLVM стандартной библиотеки C ++ (с полной поддержкой C ++ 11 и C ++ 14 [17]) и т. д. LLVM находится под управлением LLVM Foundation. Его президентом является инженер-компилятор Таня Латтнер. [18]

«Для разработки и реализации LLVM» , то Ассоциация вычислительной техники представила Викрам полиграфи, Крис Латтнер и Эван Cheng с 2012 года премии ACM Software System . [19]

Начиная с версии 9.0.0, он был перелицензирован на лицензию Apache License 2.0 с исключениями LLVM. [3]

Особенности [ править ]

LLVM может предоставить промежуточные уровни полной системы компилятора, принимая код промежуточного представления (IR) от компилятора и генерируя оптимизированный IR. Затем этот новый IR можно преобразовать и связать в машинно-зависимый код языка ассемблера для целевой платформы. LLVM может принимать IR из набора инструментов GNU Compiler Collection (GCC) , что позволяет использовать его с широким спектром существующих интерфейсов компилятора, написанных для этого проекта.

LLVM также может генерировать перемещаемый машинный код во время компиляции или компоновки или даже двоичный машинный код во время выполнения.

LLVM поддерживает систему набора команд и типов, не зависящую от языка . [5] Каждая инструкция имеет статическую форму однократного присваивания (SSA), что означает, что каждой переменной (называемой типизированным регистром) присваивается один раз, а затем она фиксируется. Это помогает упростить анализ зависимостей между переменными. LLVM позволяет компилировать код статически, как в традиционной системе GCC, или оставлять для поздней компиляции из IR в машинный код посредством JIT -компиляции , аналогично Java . Система типов состоит из основных типов, таких как целые числа или числа с плавающей запятой, и пяти производных типов :указатели , массивы , векторы , структуры и функции . Типовая конструкция на конкретном языке может быть представлена ​​путем объединения этих базовых типов в LLVM. Например, класс в C ++ может быть представлен сочетанием структур, функций и массивов указателей на функции .

Компилятор LLVM JIT может оптимизировать ненужные статические ответвления программы во время выполнения и, таким образом, полезен для частичной оценки в случаях, когда программа имеет много параметров, большинство из которых можно легко определить ненужными в конкретной среде. Эта функция используется в конвейере OpenGL Mac OS X Leopard (v10.5) для обеспечения поддержки отсутствующих аппаратных функций. [20]

Графический код в стеке OpenGL можно оставить в промежуточном представлении, а затем скомпилировать при запуске на целевой машине. В системах с высокопроизводительными графическими процессорами (GPU) результирующий код остается довольно тонким, передавая инструкции на GPU с минимальными изменениями. В системах с графическими процессорами начального уровня LLVM будет компилировать дополнительные процедуры, которые выполняются на локальном центральном процессоре (ЦП) и имитируют инструкции, которые графический процессор не может выполнять внутренне. LLVM улучшил производительность на слабых компьютерах, использующих наборы микросхем Intel GMA . Аналогичная система была разработана в рамках Gallium3D LLVMpipe и включена в оболочку GNOME, чтобы позволить ей работать без загруженного надлежащего аппаратного драйвера 3D.[21]

Что касается производительности скомпилированных программ во время выполнения, GCC раньше превосходил LLVM в среднем на 10% в 2011 году. [22] [23] Новые результаты в 2013 году показывают, что LLVM теперь догнал GCC в этой области и теперь компилирует двоичные файлы. примерно равной производительности. [24]

Компоненты [ править ]

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

Внешние интерфейсы [ править ]

Изначально LLVM был написан для замены существующего генератора кода в стеке GCC [25], и многие внешние интерфейсы GCC были модифицированы для работы с ним, в результате чего появился уже не существующий пакет LLVM-GCC. Модификации обычно включают шаг GIMPLE -to-LLVM IR, так что оптимизаторы LLVM и кодогенерацию можно использовать вместо системы GIMPLE GCC. Apple была значительным пользователем LLVM-GCC через Xcode 4.x (2013). [26] [27] Такое использование внешнего интерфейса GCC считалось в основном временной мерой, но с появлением Clang и преимуществами LLVM и современной модульной кодовой базы Clang (а также скоростью компиляции) в основном устарели.

LLVM в настоящее время поддерживает компиляцию Ada , C , C ++ , D , Delphi , Fortran , Haskell , Julia , Objective-C , Rust и Swift с использованием различных интерфейсов .

Широкий интерес к LLVM привел к нескольким попыткам разработать новые интерфейсы для множества языков. Наибольшее внимание привлек Clang, новый компилятор, поддерживающий C, C ++ и Objective-C. Clang, в первую очередь поддерживаемый Apple, нацелен на замену компилятора C / Objective-C в системе GCC на систему, которая легче интегрируется с интегрированными средами разработки (IDE) и имеет более широкую поддержку многопоточности . Поддержка директив OpenMP была включена в Clang, начиная с выпуска 3.8. [28]

Компилятор Utrecht Haskell может генерировать код для LLVM. Хотя генератор находится на ранних стадиях разработки, во многих случаях он оказался более эффективным, чем генератор кода C. [29] Существует бэкэнд Glasgow Haskell Compiler (GHC), использующий LLVM, который обеспечивает 30% ускорение скомпилированного кода по сравнению с компиляцией собственного кода с помощью GHC или генерации кода C с последующей компиляцией, при этом отсутствует только один из множества методов оптимизации. реализуется GHC. [30]

Многие другие компоненты находятся на различных стадиях разработки, включая, помимо прочего, компилятор Rust , интерфейс байт-кода Java, интерфейс Common Intermediate Language (CIL), реализацию Ruby 1.9 на MacRuby , различные интерфейсы для Standard ML. , и новый распределитель регистров раскраски графов . [ необходима цитата ]

Промежуточное представление [ править ]

LLVM IR используется, например, radeonsi и llvmpipe. Оба являются частью Mesa 3D .

Ядро LLVM - это промежуточное представление (IR), язык программирования низкого уровня, похожий на ассемблер. IR - это строго типизированный набор команд вычисления с сокращенным набором команд (RISC), который абстрагирует большинство деталей цели. Например, соглашение о вызовах абстрагируется с помощью инструкций call и ret с явными аргументами. Кроме того, вместо фиксированного набора регистров IR использует бесконечный набор временных файлов вида% 0,% 1 и т. Д. LLVM поддерживает три эквивалентных формы IR: удобочитаемый формат сборки, формат в памяти, подходящий для интерфейсы и плотный формат битового кода для сериализации. Простое "Привет, мир!" программа в ИК формате: [31]

@ .str  =  внутренняя  константа  [ 14  x  i8 ]  c "привет, мир \ 0A \ 00"объявить  i32  @printf ( i8 *,  ...)define  i32  @main ( i32  % argc ,  i8 **  % argv )  nounwind  { entry:  % tmp1  =  getelementptr  [ 14  x  i8 ],  [ 14  x  i8 ] *  @ .str ,  i32  0 ,  i32  0  % tmp2  =  call  i32  ( i8 *,  ...)  @printf (  i8 *  % tmp1  )  nounwind  ret  i32  0 }

Использование множества различных соглашений и функций, предоставляемых разными целями, означает, что LLVM не может действительно создать независимый от цели IR и перенаправить его без нарушения некоторых установленных правил. Примеры целевой зависимости, помимо того, что явно указано в документации, можно найти в предложении 2011 года для «wordcode», полностью независимого от цели варианта LLVM IR, предназначенного для онлайн-распространения. [32] Более практичным примером является PNaCl . [33]

Бэкэнды [ править ]

В версии 3.4 LLVM поддерживает множество наборов инструкций , включая ARM , Qualcomm Hexagon , MIPS , Nvidia Parallel Thread Execution (PTX; в документации LLVM называется NVPTX ), PowerPC , AMD TeraScale , [34] AMD Graphics Core Next (GCN), SPARC , z / Architecture (именуется SystemZ в документации LLVM), x86 , x86-64 и XCore. Некоторые функции недоступны на некоторых платформах. Большинство функций присутствует для x86, x86-64, z / Architecture, ARM и PowerPC. [35] RISC-V поддерживается начиная с версии 7. В прошлом LLVM также полностью или частично поддерживал другие серверные программы, включая серверную часть C, Cell SPU , mblaze (MicroBlaze) , [36] AMD R600, DEC / Compaq Alpha ( Alpha AXP). ) [37] и Nios2 , [38], но большая часть этого оборудования в основном устарела, и поддержка и обслуживание LLVM не могут быть оправданы.

LLVM также поддерживает WebAssembly в качестве цели, позволяя скомпилированным программам выполняться в средах с поддержкой WebAssembly, таких как Google Chrome / Chromium , Firefox , Microsoft Edge , Apple Safari или WAVM . Компиляторы WebAssembly, совместимые с LLVM, обычно поддерживают в основном неизмененный исходный код, написанный на C, C ++, D, Rust, Nim, Kotlin и некоторых других языках.

Подпроект машинного кода (MC) LLVM - это структура LLVM для перевода машинных инструкций между текстовыми формами и машинным кодом. Раньше LLVM полагался на системный ассемблер или ассемблер, предоставляемый цепочкой инструментов, для перевода ассемблера в машинный код. Интегрированный ассемблер LLVM MC поддерживает большинство целей LLVM, включая x86, x86-64, ARM и ARM64. Для некоторых целей, включая различные наборы инструкций MIPS, интегрированная поддержка сборки может использоваться, но все еще находится в стадии бета-тестирования.

Компоновщик [ править ]

Подпроект lld - это попытка разработать встроенный платформенно-независимый компоновщик для LLVM. [39] lld направлен на устранение зависимости от стороннего компоновщика. По состоянию на май 2017 года lld поддерживает ELF , PE / COFF , Mach-O и WebAssembly [40] в порядке убывания полноты. lld быстрее, чем обе разновидности GNU ld . [39]

В отличие от компоновщиков GNU, lld имеет встроенную поддержку оптимизации времени компоновки . Это позволяет ускорить генерацию кода, поскольку позволяет избежать использования подключаемого модуля компоновщика, но, с другой стороны, запрещает взаимодействие с другими разновидностями LTO. [41]

Стандартная библиотека C ++ [ править ]

Проект LLVM включает реализацию стандартной библиотеки C ++ под названием libc ++ , имеющую двойную лицензию по лицензии MIT и лицензии UIUC . [42]

Начиная с версии 9.0.0, он был перелицензирован на лицензию Apache License 2.0 с исключениями LLVM. [3]

Полли [ править ]

Это реализует набор оптимизаций расположения кэша, а также автопараллелизм и векторизацию с использованием многогранной модели. [43]

Отладчик [ править ]

Производные [ править ]

Из-за разрешающей лицензии многие поставщики выпускают собственные настроенные форки LLVM. Это официально признано в документации LLVM, которая по этой причине не рекомендует использовать номера версий при проверке функций. [44] Некоторые из поставщиков включают:

  • Оптимизирующий компилятор C / C ++ AMD от AMD основан на LLVM, Clang и Flang.
  • Apple поддерживает форк с открытым исходным кодом для Xcode . [45]
  • ARM поддерживает форк LLVM 9 как «компилятор Arm».
  • Национальной лаборатории Лос - Аламос имеет параллельную вычислений вилку LLVM 8 под названием «Kitsune». [46]
  • С 2013 года , Sony использует первичный LLVM в передний конец Clang компилятор в комплект разработки программного обеспечения (SDK) его PlayStation 4 консоли. [47]
  • Nvidia использует LLVM в реализации своего компилятора NVVM CUDA . [48] Компилятор NVVM отличается от бэкэнда «NVPTX», упомянутого в разделе «Бэкэнд» , хотя оба генерируют код PTX для графических процессоров Nvidia.
  • IBM использует LLVM в своих компиляторах C / C ++ и Fortran . [49]

См. Также [ править ]

  • HHVM
  • C--
  • Комплект компилятора Amsterdam (ACK)
  • LLDB (отладчик)
  • GNU молния
  • Коллекция компиляторов GNU (GCC)
  • Чистый
  • OpenCL
  • Emscripten
  • Формат распространения TenDRA
  • Формат нейтрального распределения архитектуры (ANDF)
  • Сравнение виртуальных машин приложений
  • СПИР-В
  • Иллинойсский университет в Урбане Шампейн открытия и инновации

Литература [ править ]

  • Крис Латтнер - Архитектура приложений с открытым исходным кодом - Глава 11 LLVM , ISBN  978-1257638017 , выпущен в 2012 году под лицензией CC BY 3.0 ( открытый доступ ). [50]
  • LLVM: Структура компиляции для анализа и преобразования программ на протяжении всей жизни , опубликованная статья Криса Латтнера , Викрама Адве

Ссылки [ править ]

  1. ^ «Релизы» . Github . 17 февраля 2021 . Проверено 18 февраля 2021 года .
  2. ^ "Выпуск LLVM 12.0.0-rc2 · llvm / llvm-project" . GitHub . Проверено 2 марта 2021 года .
  3. ^ a b c d "LICENSE.TXT" . llvm.org . Проверено 24 сентября 2019 года .
  4. ^ "Проект инфраструктуры компилятора LLVM" . Проверено 11 марта 2016 года .
  5. ^ a b «Справочное руководство по языку LLVM» . Проверено 9 июня 2019 года .
  6. ^ «Объявление о LLILC - новом компиляторе на основе LLVM для .NET» . dotnetfoundation.org . Проверено 12 сентября 2020 года .
  7. ^ Mono LLVM , получено 10 марта 2013 г.
  8. ^ Крис Латтнер (2011). «ЛЛВМ» . В Эми Браун; Грег Уилсон (ред.). Архитектура приложений с открытым исходным кодом .
  9. Уильям Вонг (23 мая 2017 г.). «В чем разница между LabVIEW 2017 и LabVIEW NXG?» . Электронный дизайн .
  10. ^ Майкл Ларабел (11 апреля 2018). «Хронос официально объявляет о выпуске переводчика LLVM / SPIR-V» . phoronix.com.
  11. ^ "32.1. Что такое JIT-компиляция?" . Документация PostgreSQL . 12 ноября 2020 . Проверено 25 января 2021 года .
  12. ^ «Особенности» . RubyMotion . ООО «Скретчворк Девелопмент» . Проверено 17 июня 2017 года . RubyMotion преобразует исходный код Ruby вашего проекта в ... машинный код с помощью [n] ... опережающего компилятора (AOT), основанного на LLVM.
  13. ^ Пронзительный, Geoff (24 сентября 2012). «Компиляция Scala в LLVM» . Сент-Луис, штат Миссури, США . Проверено 19 февраля 2013 года . Цитировать журнал требует |journal=( помощь )
  14. ^ Адам Treat (19 февраля 2005), mkspecs и патчи для LLVM компиляции из Qt4 , архива с оригинала на 4 октября 2011 года , извлеченной января 27, 2012
  15. ^ "Apple LLVM Compiler" , Developer Tools , Apple , получено 27 января 2012 г.
  16. ^ Lattner, Крис (21 декабря 2011). «Название LLVM» . llvm-dev (список рассылки) . Проверено 2 марта 2016 года .
  17. ^ " " libc ++ "Стандартная библиотека C ++" .
  18. ^ Крис Латтнер (3 апреля 2014 г.). «Фонд LLVM» . Блог проекта LLVM .
  19. ^ "Премия системы программного обеспечения ACM" . ACM.
  20. ^ Крис Латтнер (15 августа 2006). «Отличное использование LLVM в Apple: стек OpenGL» . llvm-dev (список рассылки) . Проверено 1 марта 2016 года .
  21. ^ Майкл Ларабель, «GNOME Shell работает без поддержки драйверов графического процессора» , phoronix , 6 ноября 2011 г.
  22. ^ В. Макаров. «SPEC2000: Сравнение LLVM-2.9 и GCC4.6.1 на x86» . Проверено 3 октября 2011 года .
  23. ^ В. Макаров. «SPEC2000: Сравнение LLVM-2.9 и GCC4.6.1 на x86_64» . Проверено 3 октября 2011 года .
  24. ^ Майкл Ларабел (27 декабря 2012). «Компилятор LLVM / Clang 3.2, конкурирующий с GCC» . Проверено 31 марта 2013 года .
  25. ^ Латтнер, Крис ; Викрам Адве (май 2003 г.). Архитектура GCC следующего поколения . Первый ежегодный саммит разработчиков GCC . Проверено 6 сентября 2009 года .
  26. ^ "Обзор компилятора LLVM" . developer.apple.com .
  27. ^ «Примечания к выпуску Xcode 5» . Apple , Inc .
  28. ^ «Примечания к выпуску Clang 3.8» . Проверено 24 августа 2016 года .
  29. ^ "Компиляция Haskell в LLVM" . Проверено 22 февраля 2009 года .
  30. ^ «Блог проекта LLVM: компилятор Glasgow Haskell и LLVM» . Проверено 13 августа 2010 года .
  31. ^ Для получения полной документации см. Llvm .org / docs / LangRef .html .
  32. Канг, Джин-Гу. «Wordcode: более целевой независимый битовый код LLVM» (PDF) . Проверено 1 декабря 2019 года .
  33. ^ "PNaCl: Portable Native Client Executables" (PDF) . Архивировано 2 мая 2012 года из оригинального (PDF) . Проверено 25 апреля 2012 года .
  34. ^ Stellard, Том (26 марта 2012). «[LLVMdev] RFC: R600, новый бэкэнд для графических процессоров AMD» . llvm-dev (список рассылки).
  35. ^ Заметки о реализации для конкретных целей: Матрица целевых функций // Генератор кода, не зависящий от целей LLVM, сайт LLVM.
  36. ^ "Удалите серверную часть mblaze из llvm" . GitHub . 25 июля 2013 . Проверено 26 января 2020 года .
  37. ^ "Удалить бэкэнд Alpha" . GitHub . 27 октября 2011 . Проверено 26 января 2020 года .
  38. ^ "[Nios2] Удалить серверную часть Nios2" . GitHub . 15 января 2019 . Проверено 26 января 2020 года .
  39. ^ a b "lld - Компоновщик LLVM" . Проект LLVM . Проверено 10 мая 2017 года .
  40. ^ "Порт WebAssembly lld" .
  41. ^ "42446 - lld не может обрабатывать файлы gcc LTO" . bugs.llvm.org .
  42. ^ " " libc ++ "Стандартная библиотека C ++" .
  43. ^ "Polly - Оптимизация многогранников для LLVM" .
  44. ^ "Расширения языка Clang" . Документация Clang 12 . Обратите внимание, что номера маркетинговых версий не следует использовать для проверки языковых функций, поскольку разные поставщики используют разные схемы нумерации. Вместо этого используйте макросы проверки функций.
  45. ^ "яблоко / llvm-project" . Яблоко. 5 сентября 2020.
  46. ^ "ланл / кицунэ" . Лос-Аламосская национальная лаборатория. 27 февраля 2020 г.
  47. ^ Developer Toolchain для ps4 (PDF) , получено 24 февраля 2015 г.
  48. ^ "Спецификация 1.5 IR NVVM" . Текущая версия NVVM IR основана на LLVM 5.0.
  49. ^ «Компиляторы IBM C / C ++ и Fortran для внедрения инфраструктуры с открытым исходным кодом LLVM» .
  50. ^ Крис Латтнер (15 марта 2012). «Глава 11» . Архитектура приложений с открытым исходным кодом . Эми Браун, Грег Уилсон. ISBN 978-1257638017.

Внешние ссылки [ править ]

  • Официальный веб-сайт