Руководство По Источникам Llvm

Прошлой осенью на моем продвинутом курсе по компилятору мы потратили некоторое время на изучение дерева исходных текстов LLVM. Миллион строк кода на C++ выглядит устрашающе, но я считаю это интересным упражнением, и по крайней мере некоторые студенты с ним согласны, поэтому я решил попробовать написать что-то подобное.

Мы будем использовать LLVM 3.9, но предыдущие (и, возможно, будущие) версии мало чем отличаются.



Руководство по источникам LLVM

Я не хочу тратить много времени на теоретические основы LLVM, но есть несколько вещей, которые вам следует знать.

Ядро LLVM не содержит интерфейсов, только оптимизаторы Middleland, несколько серверов, документацию и множество вспомогательного кода.

Фронтенды вроде Clang живут в отдельных проектах.

Промежуточное представление кода ядра LLVM находится в оперативной памяти, и им можно управлять с помощью большого API C++.

Это представление можно сохранить как читаемый текст и проанализировать обратно в память, но только для удобства отладки: во время обычной компиляции с использованием LLVM текстовый IR никогда не генерируется.

Обычно интерфейсная часть создает IR с использованием вызовов API LLVM, затем выполняет несколько этапов оптимизации, а затем вызывает серверную часть, которая генерирует ассемблерный или машинный код. Когда код LLVM записывается на диск (чего не происходит при обычной компиляции проектов C и C++ с использованием Clang), он сохраняется как «битовый код», компактное двоичное представление.

Основная документация по LLVM API создается в doxygen и ее можно найти Здесь .

Эту информацию сложно использовать, если вы не знаете точно, что вам нужно делать и на что обращать внимание.

Учебные пособия, ссылки на которые приведены ниже, являются отправной точкой для изучения API LLVM. Давайте посмотрим на код. Корневая директория содержит: переплеты — «связки», позволяют использовать LLVM API из языков, отличных от C++.

Есть и другие бандлы, с языком C (о котором речь пойдет ниже) и Haskell (его нет в этом дереве).

cmake — LLVM использует CMake, а не autoconf. Просто скажите спасибо тем, кто сделал это для вас.

документы — документация в формате ReStructuredText. См.

пример языковые гиды , который определяет значение каждой инструкции LLVM (GitHub по умолчанию отображает файлы .

rst как HTML, вы можете посмотреть «сырой» файл Здесь ).

Материал в подкаталоге с управление особенно интересно, но не смотри там, лучше пойди здесь .

Это лучший способ изучить LLVM! Примеры : Это источники, прилагаемые к руководству.

Как хакеру LLVM, вам следует по возможности брать код отсюда, CMakeLists.txt и т. д. отсюда.

включать : Первый подкаталог, llvm-c , содержит привязки C, которые я не использовал, но которые выглядят вполне разумно.

Важно то, что разработчики LLVM стараются поддерживать эти привязки стабильными, в то время как API C++ меняется с каждым выпуском, хотя скорость изменений, похоже, замедляется за последние несколько лет. Второй подкаталог лвм , большой: содержит 878 заголовочных файлов, определяющих API LLVM. В общем, проще использовать версии этих файлов в формате doxygen, чем читать их напрямую, но вам часто приходится просматривать эти файлы, чтобы найти функцию.

библиотека содержит действительно полезные вещи, ниже мы рассмотрим их отдельно.

проекты по умолчанию ничего не содержит, но сюда копируются компоненты LLVM, такие как compiler-rt (библиотеки времени выполнения для таких вещей, как дезинфицирующие средства), поддержка OpenMP и библиотеки LLVM C++, которые находятся в других репозиториях.

Ресурсы : что-то для Visual C++, что не нужно ни вам, ни мне (подробнее Здесь ) время выполнения: еще один заполнитель для внешних проектов, добавленный только прошлым летом ( 2016 г.

ок.

перевод ), и я на самом деле не знаю, для чего это нужно.

тест: : большой каталог, содержит тысячи модульных тестов LLVM, они запускаются при создании цели проверки ( сделать проверку всего, ок.

перевод ).

Большинство из них представляют собой файлы .

ll, содержащие LLVM IR в текстовой форме.

Они проверяют разные вещи, например, дает ли проход оптимизации ожидаемый результат. Я подробно расскажу о тестах LLVM в следующем посте.

инструменты: LLVM сам по себе представляет собой просто набор библиотек, и в нем нет выделенной основной функции.

Большинство подкаталогов в каталоге инструментов содержат исполняемые инструменты, которые ссылаются на библиотеки LLVM. Например, llvm-dis — это дизассемблер, преобразующий битовый код в формат текстового ассемблера.

юнит-тесты: Дополнительные модульные тесты также запускаются при построении цели проверки.

Это файлы C++, использующие фреймворк.

Google тест вызывать API напрямую, в отличие от тестов в каталоге «tests», которые запускают функции LLVM не напрямую, а посредством запуска ассемблера, дизассемблера или оптимизатора.

утилиты: Моды emacs и vim для поддержки стиля кодирования LLVM, файл Valgrind для подавления ложных срабатываний, инструменты Lit и FileCheck для поддержки модульного тестирования и многое другое.

Возможно, большинство из них вам не понадобятся.

Хорошо, до сих пор все было довольно просто.

Мы пропустили каталог библиотека , который содержит почти всё важное.

Давайте посмотрим на подкаталоги: Анализ Каталог содержит множество статических анализаторов, таких как анализ псевдонимов и глобальных значений.

Некоторые парсеры имеют структуру проходов LLVM и должны запускаться менеджером проходов, другие являются библиотеками и могут вызываться напрямую.

ИнструкцияSimplify.cpp, необычный член семейства анализаторов, на самом деле представляет собой преобразование, а не анализ.

Я уверен, что многие пропустят комментарий, объясняющий, что здесь делает этот отрывок.

этот комментарий Этот проход не меняет сам IR. Правило заключается в том, что llvm::SimplifyInstruction может возвращать только константы и существующие объекты Value, что удовлетворяет требованиям синтаксического анализатора.

Проход, вызывающий SimplifyInstruction для каждой инструкции, — это этап преобразования (lib/Transforms/Utils/SimplifyInstructions.cpp.).

АсмПарсер : анализирует текст IR в память.

Биткод : сериализовать IR в компактный формат и прочитать из компактного формата в ОЗУ.

Генератор кода: аппаратно-независимый генератор кода LLVM, фреймворк, в котором написаны серверные части LLVM, и набор библиотек, которые эти серверные части могут использовать.

Кода очень много (> 100 KLOC), и, к сожалению, я мало о нем знаю.

Отладочная информация , — это библиотека для поддержки сопоставления инструкций LLVM и местоположений исходного кода.

Много полезной информации о эти слайды из выступления на собрании разработчиков LLVM 2014 года.

Механизм выполнения: Хотя LLVM обычно переводится в машинный код или язык ассемблера, он может выполняться интерпретатором.

Не-JIT-интерпретатор работал не очень хорошо в прошлый раз, когда я пытался его использовать, но в любом случае он медленнее, чем JIT. Последнее JIT API, Орк , здесь.

Фаззер: Этот libFuzzer , похожий АФЛ ( фаззинг ).

Он использует функциональность LLVM для фаззинга программ, скомпилированных с помощью LLVM. ИК : Различные коды, связанные с ИК.

Код для вывода IR-кода в текстовом формате, для обновления биткодовых файлов, созданных в более ранних версиях LLVM, для свертывания констант при создании IR-узлов и т.д. IRReader , LibDriver , Редактор линий : Почти никого не волнует, что там, да и полезного кода там вообще почти нет. Линкер: Модуль LLVM, как и модуль компиляции C и C++, содержит функции и переменные.

Компоновщик объединяет множество модулей в один большой модуль.

ДН: Оптимизация времени соединения, тема многих постов и исследовательских работ, позволяет оптимизатору выйти за рамки отдельных скомпилированных модулей.

LLVM выполняет оптимизацию ссылок «бесплатно», используя компоновщик для создания большого модуля, а затем оптимизируя его с помощью обычных проходов оптимизации.

Это хороший подход, но он не подходит для очень больших проектов.

Современный подход - ThinLTO , что позволяет вам получить большую часть преимуществ за небольшую цену.

МК: компилятор обычно генерирует ассемблерный код и позволяет ассемблеру создавать машинный код. Подсистема MC LLVM исключает промежуточное программное обеспечение и позволяет напрямую генерировать машинный код. Это ускоряет компиляцию и особенно полезно, когда LLVM используется в качестве JIT-компилятора.

Объект : реализация деталей форматов объектных файлов, таких как ELF. ОбъектYAML - поддерживает кодирование объектных файлов в ЯМЛ .

Я не знаю, зачем это нужно.

Вариант: — парсинг командной строки.

Проходит: часть менеджера проходов, которая управляет выполнением проходов LLVM с учетом зависимостей.

Данные профиля: - Считывает и записывает данные профилирования для поддержки оптимизации на основе профилирования.

Поддерживать: Поддержка разнообразного кода, включая APInts (целые числа произвольной точности, широко используемые в LLVM) и т. д. Генерация таблиц: добрый швейцарский нож , инструмент, который принимает на вход файлы .

td (их в LLVM более 200), содержащие структурированные данные, и генерирует код C++, который компилируется в LLVM. TableGen используется, например, для реализации ассемблера и дизассемблера.

Цель: Здесь живут бэкенды для различных процессоров.

Здесь много файлов TableGen. Вы можете создать новый бэкенд, сделав клон одного из них, архитектура которого наиболее близка к вашей, а затем потратив пару лет на его разработку.

Преобразует: это мой любимый каталог, здесь живут оптимизаторы Midland. IPO содержит межпроцедурные оптимизации, которые работают через границы функций, обычно они не очень агрессивны, но видят сразу много кода.

InstCombine — оптимизатор «глазок».

Инструментарий - поддержка дезинфицирующих средств.

ObjCARC поддерживает этот .

Scalar содержит «учебные» оптимизации для компиляторов, о содержимом этого каталога я постараюсь написать более подробный пост. Utils — вспомогательный код. Vectorize — это автовекторизатор LLVM, который в последние годы стал предметом большого количества работ. На этом наш обзорный тур завершается, надеюсь, он был полезен и вы, как всегда, сообщите мне, если я где-то ошибся или что-то упустил.

Теги: #llvm #компиляторы #открытый исходный код #программирование #компиляторы

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.