Loading AI tools
З Вікіпедії, вільної енциклопедії
Low Level Virtual Machine (LLVM) — універсальна система аналізу, трансформації і оптимізації програм, що реалізує віртуальну машину з RISC-подібними інструкціями. Може використовуватися як оптимізувальний компілятор цього байт-коду в машинний код для різних архітектур або для його інтерпретації та JIT-компіляції (для деяких платформ).
Тип | Компілятори, оптимізатори і генератори коду |
---|---|
Розробники | LLVM Developer Group |
Перший випуск | 24 жовтня 2003[1] |
Стабільний випуск | 17.0.6 (28 листопада 2023) |
Операційна система | кросплатформність |
Мова програмування | C++ |
Ліцензія | University of Illinois Open Source License[2] |
Репозиторій | github.com/llvm/llvm-project |
Вебсайт | llvm.org |
LLVM дозволяє компілювати програми, написані мовами С, C++, ObjC, Fortran, Ada, Haskell, Java, Python, Ruby, Rust, JavaScript, GLSL, або будь-якою іншою, для якої реалізовано front-end. В рамках проєкту розроблено фронтенд Clang для мов C і C++ і версія GCC, що використовують LLVM як бекенд. У Glasgow Haskell Compiler також реалізована компіляція за допомогою LLVM, існує ще безліч програм, що використовують цю інфраструктуру.
LLVM — не просто черговий академічний проєкт. Його історія почалась у 2000 році в Університеті Іллінойса, а тепер LLVM використовують такі гіганти індустрії як Apple, Adobe та Google. Зокрема, на LLVM заснована підсистема OpenGL у MacOS X 10.5, a iPhone SDK використовує GCC з бекендом на LLVM. Apple та Google є одними із основних спонсорів проєкту, а натхненник LLVM — Кріс Латтнер — тепер працює в Apple.
У основі LLVM лежить проміжне подання коду (intermediate representation, IR), над яким можна виконувати трансформації у всі компіляції, компонування і виконання. Із нього генерується оптимізований машинний код для низки платформ, як статично, так і динамічно (JIT-компіляція). LLVM підтримує генерацію коду для x86, x86-64, ARM, PowerPC, SPARC, MIPS, IA-64, Alpha.
LLVM написана на C++ і портована на більшість unix-систем і Windows. Система має модульну структуру і може розширюватись додатковими алгоритмами трансформації (compiler passes) і кодогенераторами для нових апаратних платформ. Фронтенд користувача, як правило, лінкується із LLVM і використовує C++ API для генерації коду і його перетворень. Однак LLVM містить у собі й standalone утиліти.
LLVM підтримує роботу на наступних платформах:
LLVM має часткову підтримку таких платформ:
Цілі числа довільної розрядності | iрозрядність |
|
| ||
Числа з рухомою комою | float, double, типи, специфічні для конкретної платформи (наприклад, x86_fp80) | |
Пусте значення | void |
Вказівники | тип* | i32* — вказівник на 32-бітне ціле |
Масиви | [число елементів x тип] |
|
Структури | { i32, i32, double } | |
Вектор — спеціальний тип для спрощення SIMD-операцій. Вектор складається із 2^n значень примітивного типу — цілого або з плаваючою крапкою. | ||
< число елементів x тип > | < 4 x float > — вектор XMM | |
Функції |
|
Система типів рекурсивна, тобто можна використовувати багатовимірні масиви, масиви структур, вказівники на структури і функції і т. д.
Більшість інструкцій у LLVM приймають два аргументи (операнда) і вертають одне значення (триадресний код). Значення визначаються текстовим ідентифікатором. Локальні значення позначаються префіксом %
, а глобальні — @
. Локальні значення також називають регістрами, а LLVM — віртуальною машиною з нескінченним числом регістрів. Приклад:
%sum = add i32 %n, 5 %diff = sub double %a, %b %z = add <4 x float> %v1, %v2 — поелементне додавання %cond = icmp eq %x, %y — Порівняння цілих чисел. Результат має тип i1 %success = call i32 @puts(i8* %str)
Тип операндів завжди вказується явно, і однозначно визначає тип результату. Операнди арифметичних інструкцій повинні мати однаковий тип, але самі інструкції «перевантажені» для будь-яких числових типів і векторів.
LLVM підтримує повний набір арифметичних операцій, побітових логічних операцій і операцій зсуву, а також спеціальні інструкції для роботи з векторами.
LLVM IR строго типізований, тому існують операції приведення типів, які явно кодуються спеціальними інструкціями. Набір із 9 інструкцій покриває всі можливі приведення між різними числовими типами: цілими і з рухомою комою, із знаком і без, різної розрядності і т.п. Крім цього є інструкції перетворення між цілими і вказівниками, а також інструкція bitcast
, яка приведе все до всього, але за результат ви відповідаєте самі.
Крім значень-регістрів, у LLVM є і робота із пам’яттю. Значення в пам’яті адресуються типізованими вказівниками. Звернутися до пам’яті можна за допомогою двох інструкцій: load
і store
. Наприклад:
%x = load i32* %x.ptr — отримати значення типу i32 по вказівнику %x.ptr %tmp = add i32 %x, 5 — додати 5 store i32 %tmp, i32* %x.ptr — і повернути назад
Інструкція malloc транслюється у виклик однойменної системної функції і виділяє пам’ять у купи, повертаючи значення — вказівник визначеного типу. У парі з нею йде інструкція free
.
%struct.ptr = malloc { double, double } %string = malloc i8, i32 %length %array = malloc [16 x i32] free i8* %string
Інструкція alloca
виділяє пам’ять на стеку.
%x.ptr = alloca double — %x.ptr має тип double* %array = alloca float, i32 8 — %array має тип float*, а не [8 x float]!
Пам’ять, виділена alloca
, автоматично звільняється при виході із функції за допомогою інструкцій ret
або unwind
.
З проєктів, заснованих на LLVM, що розвиваються паралельно, можна відзначити:
У 2010 Асоціація обчислювальної техніки (ACM), найавторитетніша міжнародна організація, в області комп'ютерних систем присудила проєкту LLVM премію за внесок у розвиток мов програмування (SIGPLAN Programming Languages Software Award). Премія присуджується за значний вплив на пов'язані з мовами програмування дослідження, реалізації технологій і інструменти.
Seamless Wikipedia browsing. On steroids.
Every time you click a link to Wikipedia, Wiktionary or Wikiquote in your browser's search results, it will show the modern Wikiwand interface.
Wikiwand extension is a five stars, simple, with minimum permission required to keep your browsing private, safe and transparent.