What is llvm linux

Building Linux with Clang/LLVM¶

This document covers how to build the Linux kernel with Clang and LLVM utilities.

About¶

The Linux kernel has always traditionally been compiled with GNU toolchains such as GCC and binutils. Ongoing work has allowed for Clang and LLVM utilities to be used as viable substitutes. Distributions such as Android, ChromeOS, and OpenMandriva use Clang built kernels. LLVM is a collection of toolchain components implemented in terms of C++ objects. Clang is a front-end to LLVM that supports C and the GNU C extensions required by the kernel, and is pronounced “klang,” not “see-lang.”

Clang¶

The compiler used can be swapped out via CC= command line argument to make . CC= should be set when selecting a config and during a build.

Cross Compiling¶

A single Clang compiler binary will typically contain all supported backends, which can help simplify cross compiling.

CROSS_COMPILE is not used to prefix the Clang compiler binary, instead CROSS_COMPILE is used to set a command line flag: —target= . For example:

LLVM Utilities¶

LLVM has substitutes for GNU binutils utilities. Kbuild supports LLVM=1 to enable them.

They can be enabled individually. The full list of the parameters:

The integrated assembler is enabled by default. You can pass LLVM_IAS=0 to disable it.

Omitting CROSS_COMPILE¶

As explained above, CROSS_COMPILE is used to set —target= .

If CROSS_COMPILE is not specified, the —target= is inferred from ARCH .

That means if you use only LLVM tools, CROSS_COMPILE becomes unnecessary.

For example, to cross-compile the arm64 kernel:

If LLVM_IAS=0 is specified, CROSS_COMPILE is also used to derive —prefix=

to search for the GNU assembler and linker.

Supported Architectures¶

LLVM does not target all of the architectures that Linux supports and just because a target is supported in LLVM does not mean that the kernel will build or work without any issues. Below is a general summary of architectures that currently work with CC=clang or LLVM=1 . Level of support corresponds to “S” values in the MAINTAINERS files. If an architecture is not present, it either means that LLVM does not target it or there are known issues. Using the latest stable version of LLVM or even the development tree will generally yield the best results. An architecture’s defconfig is generally expected to work well, certain configurations may have problems that have not been uncovered yet. Bug reports are always welcome at the issue tracker below!

Источник

LLVM изнутри: как это работает

Приветствую хабраюзеров, в этой статье пойдет речь о внутреннем устройстве компилятора LLVM. О том, что LLVM вообще такое, можно прочитать здесь или на llvm.org. Как известно, LLVM (условно) состоит из трех частей — байткода, стратегии компиляции и окружения aka LLVM infrastructure. Я рассмотрю последнее.

Содержание:
  • Сборка LLVM
  • Привязка к Eclipse
  • Архитектура окружения
  • LLVM API
  • Оптимизация Hello, World!

В статье взят LLVM 2.7+, работающий под GNU/Linux (Ubuntu 10.04). Используются материалы официальной документации. Материалы основаны на полуторагодичном опыте исследования LLVM в ИСП РАН.

Сборка LLVM

# Конфигурация
.. / configure —enable-jit —enable-optimized —enable-shared —prefix = / prefix —enable-targets =host-only

# —enable-shared позволяет собрать ядро LLVM как одну большую shared library
# вместо /prefix задайте нужный путь для инсталляции
# —enable-targets=host-only означает поддержку только хозяйской архитектуры
# для дополнительного ускорения можно добавить —disable-assertions, их в коде на каждом шагу, в т.ч. в циклах

# Сборка
make -j2 CXXFLAGS =-O3
# -jN весьма символично, большую часть времени все равно все будет собираться в один поток,
# ничего с этим поделать нельзя
# CXXFLAGS=-O3 дает дополнительные оптимизации GCC.
# Можно еще добавить -flto для включения link-time оптимизаций в случае GCC 4.5+

Читайте также:  Современный браузер для windows виста 32 bit

# Инсталляция
make install

# Забираем код
svn co http: // llvm.org / svn / llvm-project / llvm-gcc- 4.2 / trunk llvm-gcc

cd llvm-gcc && mkdir build && cd build

# Конфигурация
.. / configure —enable-llvm = / path / to / llvm / build —prefix = / prefix / of / llvm —program-prefix =llvm- —enable-languages =c, c++
# /path/to/llvm/build означает путь к той самой папке build, созданной на предыдущем этапе
# /prefix/of/llvm — для удобства, префикс совпадает с префиксом LLVM
# —program-prefix=llvm- нужно для получения общеупотребительных имен бинарников вроде llvm-gcc или llvm-g++

# Сборка
make -j2 CFLAGS =-O3

# Инсталляция
make install

/ prefix / of / llvm / llvm-gcc -v

gcc version 4.2.1 ( Based on Apple Inc. build 5658 ) ( LLVM build )

Привязка к Eclipse

Для удобства, расскажу как собирать и изучать исходный код LLVM в Eclipse (разумеется, с поддержкой C/C++). Создаем новый проект C++ /File-New — C++ Project/, Задаем название «llvm» /Project name/, снимаем галку с расположения по умолчанию /Use default location/ и задаем путь к дереву исходников LLVM, тип проекта ставим Makefile /Project type: Makefile project — Empty Project/. Далее жмем «Закончить» /Finish/. Пока Eclipse разбирает файлы и строит индекс навигации, заходим в свойства проекта /Project — Properties/. В настройках сборщика /Builder Settings/ снимаем галку с команды сборки по умолчанию /Use default build command/ и вписываем «make -j2 CXXFLAGS=-O3». В директории сборки /Build directory/ дописываем «/build», так чтобы получилось «$/build». Переходим во вкладку поведения /Behavior/ и справа от цели сборки /Build (Incremental build)/ стираем «all». Последнее не обязательно и нужно скорее для идентичности ручной сборке в консоли. Готово! Можно смело прыгать по классам, смотреть #define-ы и нажимать на кнопку сборки /Build/. Для избежания возможных проблем (у кого как) можно удалить из дерева тесты (tests).

Архитектура окружения

LLVM состоит из нескольких исполняемых файлов, использующих libLLVM2.x.so (ядро).
opt — инструмент, оперирующий байткодом: он может накатывать любые доступные машинно-независимые оптимизации в произвольном порядке, проводить различные виды анализа и добавлять профилирование. Существуют уровни оптимизации O0, O1, O2 и O3.
llc — кодогенератор из байткода в ассемблер целевой машины. Выполняет машинно-зависимые оптимизации. Так же существуют уровни оптимизации O0, O1, O2 и O3.
llvm-ld — линковщик байткода, т.е. инструмент соединяет несколько байткодных файлов в один большой BC файл. При этом накатываются link-time оптимизации, которыми так гордятся создатели.
lli — интерпретатор байткода с возможностью JIT компиляции.
llvm-dis — преобразователь байткода (bc) в эквивалентное текстовое представление (ll).
llvm-as — преобразователь текстового представления (ll) в байткод (bc).
llvm-ar — упаковщик нескольких файлов в один. Некий аналог bzip2.
llvmc — драйвер LLVM, вызывающий по очереди парсер языка (т.е. front-end: llvm-gcc или clang), opt, llc (указанный back-end для целевой машины), ассемблер и линковщик целевой машины. Общая схема изображена на рисунке.

Стоит отметить, что в качестве back-end поддерживаются все общеизвестные архитектуры (в т.ч. x86, x86-64, ARM), и даже такая экзотика как язык C. Последнее означает, что можно преобразовать байткод сразу в исходник на C… но вряд ли он вам понравится без имен переменных (вернее, с иными названиями, присвоенными в байткоде), с циклами на goto, измененным порядком следования команд и еще много с чем другим. А как же иначе, чудес не бывает. Кстати, байткод можно потенциально превращать и в код виртуальной машины Java или .NET.

Интересна реализация «железных» back-end-ов. На раннем этапе сборки LLVM появляется утилита под названием tblgen. Она в том числе преобразовывает описания ассемблеров на специфичном описательном языке в C++ код, который в дальнейшем #include-ится в классы, реализующие кодогенерацию. Таким образом, очень легко что-то изменить или добавить в систему команд, а поддержка унифицируется. В отличие от GCC, не надо сильно напрягаться над кросскомпиляцией: при вызове llc достаточно указать -march=armv7, где на месте armv7 может стоять любая поддерживаемая архитектура. Не могу не упомянуть здесь принципиальное отличие LLVM от, скажем, Java: байткод LLVM в общем случае зависит от платформы, на которой его получают и целевой машины, под которую компилируют. Первое объясняется линковкой с библиотеками, зависящими от ОС, второе — ассемблерными вставками и портированием кода (условной компиляцией) на различные архитектуры.

Читайте также:  Virtualbox настройка linux windows

Значения некоторых папок с кодом:

  • include — загловочные файлы
  • tools — реализация перечисленных выше инструментов
  • runtime — реализация сбора профиля
  • tools — реализация служебных утилит LLVM, в т.ч. tblgen
  • examples — примеры использования LLVM
  • lib — главная часть
  • lib/Analysis — проходы, осуществляющие анализ (о проходах см. дальше)
  • lib/CodeGen — реализация кодогенерации, машинно-зависимых проходов
  • lib/Transforms — проходы, выполнимые над байткодом

В принципе, значения очевидны из названий, и эта очевидность не обманчива.

LLVM API

Ядро LLVM — очень мощная система. Все рутинные вещи спрятаны от рядовых разработчиков, давая возможность сосредоточиться над улучшением качества компилятора. Подробная документация, множество материалов позволяют быстро войти в курс дела. Имена классов, методов, схема наследования — все продумано до мелочей. Я немного расскажу об API, связанном с оптимизациями. Чтобы было не скучно, желательно знать, что означают такие термины как базовый блок (basic block) и граф потока управления (он же CFG, Control Flow Graph). Хватит информации из Wikipedia: базовый блок и граф потока управления.

Вообще принято говорить о проходах (passes), а не об оптимизациях. Проход это реализация конкретной оптимизации или ее части. У LLVM есть менеджер проходов (PassManager), который работает по принципу FIFO. Сначала добавляются описания проходов, а затем менеджер их одну за другой выполнит. Причем, если проход нуждается в данных некоторого анализа CFG, то менеджер предварительно проведет этот анализ, если его данные устарели. Проходы работают в рамках функции (наследуются от FunctionPass) или базового блока (BasicBlockPass). В первом случае на вход алгоритму будет подана функция, во втором — базовый блок. У функции можно стандартным образом итерировать по базовым блокам, у базового блока, соответственно, по инструкциям. Можно все переставлять местами, как вздумается, добавлять новые элементы.

LLVM opt поддерживает подключаемые модули — этакие shared passes. Во время вызова библиотека подгружается и принимается к сведению. Благодаря этому для расширения возможностей компилятора необязательно делать свою ветку кода и потом ее править, достаточно нужных заголовочных файлов. Как известно, в GCC такое появилось совсем недавно.

Как говорится, лучше один раз увидеть, чем сто раз услышать. Перейдем к практике.

Оптимизация Hello, World!

#define DEBUG_TYPE «basic-block-stats»
#include «llvm/Pass.h»
#include «llvm/Function.h»
#include «llvm/Instructions.h»
#include «llvm/BasicBlock.h»
#include «llvm/ADT/Statistic.h»
#include «llvm/Transforms/Scalar.h»
#include «llvm/Support/CFG.h»

using namespace llvm ;

// Объявление собираемых статистик.
// Каждая из них может быть только челым числом без знака.

// Общее количество базовых блоков
STATISTIC ( NumberOfBasicBlocks, «Number of basic blocks in the module» ) ;

// Общее количество инструкций
STATISTIC ( NumberOfInstructions, «Number of instructions in the module» ) ;

// Среднее количество инструкций на базовый блок
STATISTIC ( AverageInstructionsInBasicBlock, «Average number of instructions in a basic block» ) ;

// Структура (класс) прохода (pass)
// В общепринятой терминологии оптимизации называются проходами, т.к.
// действие над модулем выполняется за один полный проход по его содержимому
struct BasicBlockStats : public FunctionPass
<
// Идентификационный номер прохода
static char ID ;

BasicBlockStats ( ) : FunctionPass ( ID )

// Перегрузка метода, сообщающего менеджеру проходов, что использует и меняет данный проход
virtual void getAnalysisUsage ( AnalysisUsage & AU ) const
<
// Ничего не используем, ничего не меняем
AU. setPreservesAll ( ) ;
>

// Перегрузка метода, который несет смысл прохода — операции над функцией модуля
virtual bool runOnFunction ( Function & F ) ;

BasicBlockStats ( )
<
// При вызове деструктора считаем искомое число
AverageInstructionsInBasicBlock = NumberOfInstructions / NumberOfBasicBlocks ;
>
> ;

// Идентифицировать себя нам незачем
char BasicBlockStats :: ID = 0 ;

// Выполняем регистрацию прохода в менеджере проходов
RegisterPass BasicBlockStats > X ( «basic-block-stats» , «Basic Block Statistics» , true ) ;

Читайте также:  Навител навигатор gps для windows

> // end of unnamed namespace

// Добавляем количество базовых блоков
NumberOfBasicBlocks + = F. size ( ) ;
return false ;
>

g++ -c -fPIC BasicBlockStats.cpp -o BasicBlockStats.o -I.. / include -I.. / build / include -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS
gcc -shared -s BasicBlockStats.o -o BasicBlockStats.so

# Собираем библиотеку SQLite в байткод
llvm-gcc -emit-llvm -c sqlite3.c -o sqlite3.bc

# Запускаем нашу оптимизацию
# -stats показывает все собранные статистики
opt sqlite3.bc -load BasicBlockStats.so -basic-block-stats -stats -o sqlite3.bc

Итак, среднее значение инструкций в базовом блоке в коде SQLite равно 8.

Возможно, простота написания собственного прохода (pass) вдохновит читателя на изыскания в этой области, а я на этом закончу. Буду рад ответить на ваши вопросы.

Источник

What is LLVM?

What is LLVM and Why is it Useful?

Multiple mini-projects work under the LLVM umbrella. The mini-projects mainly deal with compiler technologies. There seems to be some confusion regarding the LLVM naming. People mistakenly assume it is related to virtual machines. There is no connection. The term LLVM doesn’t stand for anything. It is just a name that was used at the beginning of the project.

The LLVM project is operated under the “UIUC” BSD-Style license. The project originated in the University of Illinois. Since then it has gained popularity and it has been used for a large variety of projects. It’s especially popular in the academic circles. The main objective of the project to provide SSA-based static and dynamic compilation of various programming languages.

Here are the mini-project of LLVM:

  1. LLVM Core: The core libraries provide optimizer and code generation support for CPUs. LLVM IR(Intermediate Representation) provides the foundation for the libraries. The community has done a good job of documenting the LLVM Core. So you can easily use these libraries to create your new programming language or create a port of an existing compiler. If you are looking to venture into these territories, LLVM Core is a good place to start.
  1. Clang: It is a compiler that is three times faster than GCC. It targets C, C++, and Objective-C. The Clang errors and warnings are easier to understand. It also has a static analyzer tool. The static analyzer tool itself is built using the Clang compiler.
  1. LLDB: It is a debugger. It is faster and more efficient than GDB. The debugger is built using Clang and LLVM Core.
  1. libc++ and libc++ ABI: Better implementation of C++ STD.
  1. compiler-rt: It provides supports for low-level code. It also has run-times libraries for dynamic testing.
  1. OpenMP: Open Multi-Processing (OpenMP) is an API to help with multithreading. This project supports the native runtime for OpenMP to be used with Clang.
  1. Polly: In the LLVM world, it is a high-level loop and data-locality optimizer. It optimizes memory access patterns of programs.
  1. libclc: A library for OpenCL.
  1. klee: It is a symbolic virtual machine. You can use klee to traverse all the dynamic paths in a program to find problems. The machine can produce automated test cases.
  1. SAFECODE: It is a compiler for C/C++ to guarantee memory safety. It is a great tool for cybersecurity experts to explore. It can help with detecting memory safety errors.
  1. lld: It is building a linker to work with Clang and LLVM.

The LLVM has a reputation for creating cleaner binaries than GCC. Also, LLVM has external projects which can be used to compile Python, Haskell, PHP, LUA, Ruby and other languages. LLVM is considered a versatile, flexible and reusable solution. So it is gaining popularity in the development community. It is used as JIT compilers for embedded languages. LLVM is also being used for supercomputers. The broad support from the developer community is making it a robust tool.

Источник

Оцените статью