Для установки нажмите кнопочку Установить расширение. И это всё.

Исходный код расширения WIKI 2 регулярно проверяется специалистами Mozilla Foundation, Google и Apple. Вы также можете это сделать в любой момент.

4,5
Келли Слэйтон
Мои поздравления с отличным проектом... что за великолепная идея!
Александр Григорьевский
Я использую WIKI 2 каждый день
и почти забыл как выглядит оригинальная Википедия.
Статистика
На русском, статей
Улучшено за 24 ч.
Добавлено за 24 ч.
Что мы делаем. Каждая страница проходит через несколько сотен совершенствующих техник. Совершенно та же Википедия. Только лучше.
.
Лео
Ньютон
Яркие
Мягкие

Из Википедии — свободной энциклопедии

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 поддерживает работу на следующих платформах:

Операционная система Архитектура Компилятор
Linux x86/AMD64 GCC, Clang
FreeBSD x86/AMD64 GCC, Clang
OpenBSD x86/AMD64 GCC, Clang
macOS PowerPC GCC
macOS x86/AMD64 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 имеет частичную поддержку следующих платформ:

Операционная система Архитектура Компилятор
AIX PowerPC GCC
Linux PowerPC GCC
AmigaOS m68k, PowerPC GCC
Windows x86 MSVC

Типы данных

Простые типы

Целые числа произвольной разрядности iразрядность
  • i1 — булево значение — 0 или 1
  • i32 — 32-разрядное целое
  • i17
  • i256
  • Генерация машинного кода для типов очень большой разрядности не поддерживается. Но для промежуточного представления никаких ограничений нет.
  • Числа считаются представленными в дополнительном коде. Различий между знаковыми и беззнаковыми целыми на уровне типов не делается: в тех случаях, когда это имеет значение, с ними работают разные инструкции.
Числа с плавающей точкой float, double, типы, специфичные для конкретной платформы (например, x86_fp80)
Пустое значение void

Производные типы

Указатели тип* i32* — указатель на 32-разрядное целое
Массивы [число элементов x тип]
  • [10 x i32]
  • [8 x double]
Структуры { 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

Примечания

  1. Латтнер К. The LLVM 1.0 Release is finally available!
  2. LLVM 17.0.6 Released! (англ.) — 2023.
  3. 1 2 https://github.com/llvm/llvm-project/graphs/contributors?type=a
  4. The llvm Open Source Project on Open Hub: Languages Page — 2006.
  5. 1 2 The llvm Open Source Project on Open Hub: Languages Page (англ.)
  6. License (англ.)
  7. https://github.com/llvm/llvm-project/commit/469bdefd448b76c5adcdd67256e9a44fabf7e027 — 2019.
  8. 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.»
  9. LLILC. Дата обращения: 14 апреля 2015. Архивировано 19 мая 2019 года.
  10. Projects built with LLVM (англ.). llvm. Дата обращения: 24 мая 2018. Архивировано 24 мая 2018 года.
  11. Welcome Chris Lattner | Tesla. Дата обращения: 11 января 2017. Архивировано 11 января 2017 года.
  12. Основатель LLVM присоединился к SiFive. Дата обращения: 28 января 2020. Архивировано 28 января 2020 года.
  13. The LLVM Target-Independent Code Generator Архивная копия от 1 мая 2021 на Wayback Machine раздел Target Feature Matrix (англ.)

Литература

Ссылки

Эта страница в последний раз была отредактирована 8 ноября 2023 в 12:18.
Как только страница обновилась в Википедии она обновляется в Вики 2.
Обычно почти сразу, изредка в течении часа.
Основа этой страницы находится в Википедии. Текст доступен по лицензии CC BY-SA 3.0 Unported License. Нетекстовые медиаданные доступны под собственными лицензиями. Wikipedia® — зарегистрированный товарный знак организации Wikimedia Foundation, Inc. WIKI 2 является независимой компанией и не аффилирована с Фондом Викимедиа (Wikimedia Foundation).