Low Level Virtual Machine

Материал из Seo Wiki - Поисковая Оптимизация и Программирование

Перейти к: навигация, поиск
LLVM
Файл:LLVM Logo.png
Тип Компилятор
Разработчик 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 поддерживает работу на следующих платформах:

Операционная системаАрхитектураКомпилятор
FreeBSDx86GCC
LinuxAMD64GCC
Linuxx86GCC
Mac OS XPowerPCGCC
Mac OS Xx86GCC
SolarisUltraSPARCGCC
Cygwin/Win32x86GCC 3.4.X, Binutils 2.15
MinGW/Win32x86GCC 3.4.X, Binutils 2.15


LLVM имеет частичную поддержку следующих платформ:

Операционная системаАрхитектураКомпилятор
Windowsx86Visual Studio .NET
AIXPowerPCGCC
LinuxPowerPCGCC
LinuxAlphaGCC
LinuxItanium (IA-64)GCC
HP-UXItanium (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

Ссылки

Смотреть также

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

Личные инструменты

Served in 0.232 secs.