Меню
Главная
Случайная статья
Настройки
|
LLVM (изначальная расшифровка — англ. low level virtual machine[8]; на данный момент официально не имеет расшифровки) — проект программной инфраструктуры для создания компиляторов и сопутствующих им утилит. Состоит из набора компиляторов из языков высокого уровня (так называемых фронтендов), системы оптимизации, интерпретации и компиляции в машинный код. В основе инфраструктуры используется RISC-подобная платформонезависимая система кодирования машинных инструкций (байткод LLVM IR), которая представляет собой высокоуровневый ассемблер, с которым работают различные преобразования.
Написан на C++, обеспечивает оптимизации на этапах компиляции, компоновки и исполнения. Изначально в проекте были реализованы компиляторы для языков Си и C++ при помощи фронтенда Clang, позже появились фронтенды для множества языков, в том числе: ActionScript, Ада, C#[9], Common Lisp, Crystal, CUDA, D, Delphi, Dylan, Fortran, Graphical G Programming Language, Halide, Haskell, Java (байткод), JavaScript, Julia, Kotlin, Lua, Objective-C, OpenGL Shading Language, Ruby, Rust, Scala, Swift, Xojo, Zig.
LLVM может создавать машинный код для множества архитектур, в том числе ARM, x86, x86-64, PowerPC, MIPS, SPARC, RISC-V и других (включая GPU от Nvidia и AMD).
Некоторые проекты имеют собственные LLVM-компиляторы (например LLVM-версия GCC), другие используют инфраструктуру LLVM[10], например таков Glasgow Haskell Compiler.
Разработка начата в 2000 году в Университете Иллинойса. К середине 2010-х годов LLVM получил широкое распространение в индустрии: использовался, в том числе, в компаниях Adobe, Apple и Google. В частности, на LLVM основана подсистема OpenGL в Mac OS X 10.5, а iPhone SDK использует препроцессор (фронтенд) GCC с бэкэндом на LLVM. Apple и Google являются одними из основных спонсоров проекта, а один из основных разработчиков — Крис Латтнер — 11 лет проработал в Apple (с 2017 года — в Tesla Motors[11], с 2020 года — в разработчике процессоров и микроконтроллеров на архитектуре RISC-V SiFive[12]).
Содержание
Особенности
В основе LLVM лежит промежуточное представление кода (Intermediate Representation, IR), над которым можно производить трансформации во время компиляции, компоновки и выполнения. Из этого представления генерируется оптимизированный машинный код для целого ряда платформ как статически, так и динамически (JIT-компиляция). LLVM 9.0.0 поддерживает статическую генерацию кода для x86, x86-64, ARM, PowerPC, SPARC, MIPS, RISC-V, Qualcomm Hexagon, NVPTX, SystemZ, Xcore. JIT-компиляция (генерация машинного кода во время исполнения) поддержана для архитектур x86, x86_64, PowerPC, MIPS, SystemZ, и частично ARM[13].
LLVM написана на C++ и портирована на большинство Unix-подобных систем и Windows. Система имеет модульную структуру, отдельные её модули могут быть встроены в различные программные комплексы, она может расширяться дополнительными алгоритмами трансформации и кодогенераторами для новых аппаратных платформ.
В LLVM включена обёртка API для OCaml.
Платформы
LLVM поддерживает работу на следующих платформах:
LLVM имеет частичную поддержку следующих платформ:
Типы данных
Простые типы
Целые числа произвольной разрядности
|
iразрядность
|
- i1 — булево значение — 0 или 1
- i32 — 32-разрядное целое
- i17
- i256
|
- Генерация машинного кода для типов очень большой разрядности не поддерживается. Но для промежуточного представления никаких ограничений нет.
- Числа считаются представленными в дополнительном коде. Различий между знаковыми и беззнаковыми целыми на уровне типов не делается: в тех случаях, когда это имеет значение, с ними работают разные инструкции.
|
Числа с плавающей точкой
|
float, double, типы, специфичные для конкретной платформы (например, x86_fp80)
|
|
Пустое значение |
void
|
|
Производные типы
Указатели
|
тип*
|
i32* — указатель на 32-разрядное целое
|
Массивы
|
[число элементов x тип]
|
|
Структуры
|
|
{ i32, i32, double }
|
Вектор — специальный тип для упрощения SIMD-операций.
Вектор состоит из 2n значений примитивного типа — целого или с плавающей точкой.
|
< число элементов x тип >
|
< 4 x float > — вектор XMM
|
Функции
|
|
- 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 .
Инструкция 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
Примечания
- Латтнер К. The LLVM 1.0 Release is finally available!
- LLVM 21.1.1 Released! (англ.) — 2025.
- 1 2 https://github.com/llvm/llvm-project/graphs/contributors?type=a
- The llvm Open Source Project on Open Hub: Languages Page — 2006.
- 1 2 The llvm Open Source Project on Open Hub: Languages Page (англ.)
- License (англ.)
- https://github.com/llvm/llvm-project/commit/469bdefd448b76c5adcdd67256e9a44fabf7e027 — 2019.
- LLVMdev: The name of LLVM Архивная копия от 3 ноября 2016 на Wayback Machine, Chris Lattner (Apple), 2011-12-21 «„LLVM“ is officially no longer an acronym. The acronym it once expanded too was confusing, and inappropriate almost from day 1.»
- LLILC (неопр.). Дата обращения: 14 апреля 2015. Архивировано 19 мая 2019 года.
- Projects built with LLVM (англ.). llvm. Дата обращения: 24 мая 2018. Архивировано 24 мая 2018 года.
- Welcome Chris Lattner | Tesla (неопр.). Дата обращения: 11 января 2017. Архивировано 11 января 2017 года.
- Основатель LLVM присоединился к SiFive (неопр.). Дата обращения: 28 января 2020. Архивировано 28 января 2020 года.
- The LLVM Target-Independent Code Generator Архивная копия от 1 мая 2021 на Wayback Machine раздел Target Feature Matrix (англ.)
Литература
Ссылки
|
|