Low Level Virtual Machine
| Розробник(и) | LLVM Developer Group |
|---|---|
| Перший випуск | 2000 |
| Стабільний випуск | 3.6 (27 лютого 2015) |
| Написано на | C++ |
| Операційна система | крос-платформовий |
| Тип | Компілятори, оптимізатори і генератори коду |
| Ліцензія | University of Illinois Open Source License[1] |
| Сайт | llvm.org |
Low Level Virtual Machine (LLVM) — універсальна система аналізу, трансформації і оптимізації програм, що реалізує віртуальну машину з RISC-подібними інструкціями. Може використовуватися як оптимізуючий компілятор цього байт-коду в машинний код для різних архітектур або для його інтерпретації та JIT-компіляції (для деяких платформ).
LLVM дозволяє компілювати програми, написані на мовах С, C++, ObjC, Fortran, Ada, Haskell, Java, Python, Ruby, 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++ і портована на більшість *nix-систем і Windows. Система має модульну структуру і може розширюватись додатковими алгоритмами трансформації (compiler passes) і кодогенераторами для нових апаратних платформ. Фронтенд користувача, як правило, лінкується із LLVM і використовує C++ API для генерації коду і його перетворень. Однак LLVM включає в себе і standalone утіліти.
У LLVM включена обгортка API для OCaml.
Платформи[ред. • ред. код]
LLVM подтримує роботу на наступних платформах:
| Операційна система | Архітектура | Компілятор |
|---|---|---|
| FreeBSD | x86 | GCC, Clang |
| FreeBSD | AMD64 | GCC, Clang |
| Linux | AMD64 | GCC, Clang |
| Linux | x86 | GCC, Clang |
| Mac OS X | PowerPC | GCC |
| Mac OS X | x86 | GCC, Clang |
| Solaris | UltraSPARC | GCC |
| Cygwin/Win32 | x86 | GCC 3.4.X, Binutils 2.15 |
| MinGW/Win32 | x86 | GCC 3.4.X, Binutils 2.15 |
LLVM має часткову підтримку наступних платформ:
| Операційна система | Архітектура | Компілятор |
|---|---|---|
| Windows | x86 | Visual Studio .NET |
| AIX | PowerPC | GCC |
| Linux | PowerPC | GCC |
| Linux | Alpha | GCC |
| Linux | Itanium (IA-64) | GCC |
| HP-UX | Itanium (IA-64) | HP aCC |
Типи даних[ред. • ред. код]
Прості типи[ред. • ред. код]
| Цілі числа довільної розрядності | 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, що розвиваються паралельно, можна відзначити:
- KLEE - символьний аналізатор і генератор тестових наборів;
- Runtime-бібліотека compiler-rt;
- llvm-mc - автогенератор асемблера, дизассемблера та інших, пов'язаних з машинним кодом компонентів, на основі описів параметрів LLVM-сумісних платформ.
- VMKit - віртуальна машина для Java і .NET;
- Реалізація функційної мови програмування Pure;
- LDC - компілятор для мови D;
- Roadsend PHP - оптимізатор, статичний і JIT компілятор для мови PHP;
- Віртуальні машини для Ruby: Rubinius і MacRuby;
- Unladen Swallow - реалізація мови Python;
- LLVM-Lua
- FlashCCompiler - засіб для компіляції коду на мові Сі у вид, придатний для виконання у віртуальній машині Adobe Flash;
- LLDB [1] - модульна інфраструктура зневадження, використовує такі підсистеми LLVM як API для дизасембювання, Clang AST (Abstract Syntax Tree), парсер виразів, генератор коду і JIT-компілятор. LLDB підтримує зневадження багатонитевих програм на мовах C, Objective-C і C++; відрізняється можливістю підключення плагінів і скриптів на мові Python; демонструє екстремально високу швидкодія при зневадженні програм великого розміру;
- Emscripten [2] - транскомпілятор біткоду LLVM в JavaScript, що дозволяє перетворити для запуску в браузері застосунки, спочатку написані на мові Сі. Наприклад, вдалося запустити Python, Lua, Quake, Freetype;
- sparse-llvm —— бекенд, націлений на створення Сі-компілятора, здатного збирати ядро Linux.
- Portable OpenCL — відкрита і незалежна реалізація стандарту OpenCL;
- CUDA Compiler — дозволяє згенерувати GPU-інструкції з коду, написаного на мовах Сі, Сі++ та Fortran;
- Julia — відкрита динамічна мова програмування, що використовує напрацювання проекту LLVM.
Відзнаки[ред. • ред. код]
У 2010 Асоціація обчислювальної техніки (ACM), найавторитетніша міжнародна організація, в області комп'ютерних систем присудила проекту GCC премію за внесок у розвиток мов програмування (SIGPLAN Programming Languages Software Award). Премія присуджується за значний вплив на пов'язані з мовами програмування дослідження, реалізації технологій і інструменти.
Посилання[ред. • ред. код]
- LLVM
- libJIT Linear Scan Register Allocator
- Amy Brown and Greg Wilson (eds.) Chapter 11. LLVM (Chris Lattner) // The Architecture of Open Source Applications. — 2011. — P. 155-170. — 432 p. — ISBN 978-1-257-63801-7.
- ↑ «LLVM: Frequently Asked Questions». Архів оригіналу за 2013-07-13. Процитовано 2010-12-23.
