Low Level Virtual Machine
| LLVM | |
| Low Level Virtual Machine Logo | |
| Тип | Компилятор |
| Разработчик | LLVM Developer Group |
| Написана на | C++ |
| ОС | Cross-platform |
| Версия | 2.6 (23 октября 2009) |
| Лицензия | University of Illinois/NCSA Open Source License |
| Сайт | llvm.org |
Low Level Virtual Machine (LLVM) — система программирования, содержащая:
- компилятор языка С++ в промежуточный байткод, разработанный с целью дать возможность оптимизировать программы на всех этапах использования;
- набор RISC-подобных инструкций виртуального процессора из которых строится байткод;
- окружение, предназначенное для исполнения байткода на различных платформах.
История
История LLVM началась в 2000 году в Университете Иллинойса, а теперь LLVM используют такие гиганты индустрии как Apple и Adobe. В частности, на LLVM основана подсистема OpenGL в Mac OS X 10.5, а iPhone SDK использует GCC с бэкэндом на LLVM. Apple является одним из основных спонсоров проекта, а вдохновитель LLVM — Крис Латтнер — теперь работает в Apple.
Особенности
В основе LLVM лежит промежуточное представление кода (Intermediate Representation, IR), над которым можно производить трансформации во время компиляции, компоновки и выполнения. Из этого представления генерируется оптимизированный машинный код для целого ряда платформ, как статически, так и динамически (JIT-компиляция). LLVM поддерживает генерацию кода для x86, x86-64, ARM, PowerPC, SPARC, MIPS, IA-64, Alpha.
LLVM написана на C++ и портирована на большинство nix-систем и Windows. Система имеет модульную структуру и может расширяться дополнительными алгоритмами трансформации и кодогенераторами для новых аппаратных платформ.
В LLVM включена обертка API для OCaml.
Платформы
LLVM поддерживает работу на следующих платформах:
| Операционная система | Архитектура | Компилятор |
|---|---|---|
| FreeBSD | x86 | GCC |
| Linux | AMD64 | GCC |
| Linux | x86 | GCC |
| Mac OS X | PowerPC | GCC |
| Mac OS X | x86 | GCC |
| 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 |
Типы данных
В LLVM поддерживаются следующие простые типы:
- Целые числа произвольной разрядности:
i1 ; булево значение — 0 или 1 i32 ; 32-разрядное целое i17 ; i256 ;
Генерация машинного кода для типов очень большой разрядности не поддерживается. Например, для x86 вам придётся ограничиться i64, а для x86-64 и других 64-разрядных платформ — 128-битными целыми. Но для промежуточного представления никаких ограничений нет. Числа считаются представленными в дополнительном коде. Различий между знаковыми и беззнаковыми целыми на уровне типов не делается: в тех случаях, когда это имеет значение, с ними работают разные инструкции.
- Числа с плавающей точкой: float, double, а также ряд типов, специфичных для конкретной платформы (например, x86_fp80)
- void — пустое значение.
Производные типы:
- Указатели
тип* i32* ; указатель на 32-битное целое
- Массивы
[число элементов x тип] [10 x i32] [8 x double]
- Структуры
{ i32, i32, double }
- Вектор — специальный тип для упрощения SIMD-операций. Вектор состоит из 2n значений примитивного типа — целого или с плавающей точкой.
< число элементов x тип > < 4 x float >
- Функции
i32 (i32, i32)
float ({ float, float }, { float, float })
Система типов рекурсивна, поэтому можно использовать многомерные массивы, массивы структур, указатели на структуры и функции, и т. д.
Операции
Большинство инструкций в 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.
Операции с указателями
Для вычисления адресов элементов массивов, структур и т.д. с правильной типизацией выполняется с помощью инструкции getelementptr.
%array = alloca i32, i32 %size %ptr = getelementptr i32* %array, i32 %index ; значение типа i32*
getelementptr только вычисляет адрес, но не обращается к памяти. Инструкция принимает произвольное количество индексов и может разыменовывать структуры любой вложенности.
Также существует инструкции extractvalue и insertvalue. Они отличаются от getelementptr тем, что принимают не указатель на агрегатный тип данных (массив или структуру), а само значение такого типа. extractvalue возвращает соответственное значение подэлемента, а insertvalue порождает новое значение агрегатного типа.
%n = extractvalue { i32, [4 x i8*] } %s, 0
%tmp = add i32 %n, 1
%s.1 = insertvalue { i32, [4 x i8*] } %s, i32 %tmp, 0
Ссылки
Смотреть также
- Сравнение областей применения различных виртуальных машин (англ.).
- Библиотека для компиляции на лету libjit (англ.).
ca:Low Level Virtual Machine de:Low Level Virtual Machine en:Low Level Virtual Machine fr:Low Level Virtual Machine it:LLVM ja:Low Level Virtual Machine ko:LLVM
Если вам нравится SbUP.com Сайт, вы можете поддержать его - BTC: bc1qppjcl3c2cyjazy6lepmrv3fh6ke9mxs7zpfky0 , TRC20 и ещё....