Каковы преимущества и недостатки использования LLVM IR по сравнению с C для целевого языка при написании компилятора? Я знаю, что используются оба, и я полагаю, что окончательный машинный код был бы похож, если бы я использовал clang для компиляции C. Итак, что еще нужно учитывать?
Язык вывода компилятора — LLVM IR против C
Ответы (5)
Я использовал LLVM IR для нескольких серверных частей компилятора и работал с компиляторами, использующими C в качестве серверной части. Одна вещь, которая, как я обнаружил, дает преимущество LLVM IR, заключается в том, что она типизирована. Трудно сделать полностью некорректный вывод, не получая при этом ошибок от библиотек LLVM.
На мой взгляд, также проще поддерживать тесную связь между исходным кодом и IR для отладки.
Кроме того, вы получаете все классные инструменты командной строки LLVM для анализа и обработки IR, которые излучает ваш внешний интерфейс.
Преимущества ЛЛВМ:
- JIT — вы можете компилировать и запускать свой код динамически. Конечно, то же самое возможно и с C (например, с использованием встроенного
tcc
), но это гораздо менее надежный и портативный вариант. - Вы можете запускать собственные проходы оптимизации по сгенерированному IR.
- Бесплатное отражение — проверка сгенерированного кода намного проще с LLVM.
- Библиотека LLVM не такая большая, как у большинства компиляторов C (не считая
tcc
, конечно).
Недостатки LLVM:
- Код не является переносимым, вам нужно немного изменить его в зависимости от вашей цели. Существует несколько переносимое подмножество LLVM, но это все еще хитрая практика.
- Зависимость времени выполнения от библиотек C++ может быть проблемой.
Я сомневаюсь, что вы сможете реализовать надлежащую поддержку отладки для своего языка, ориентируясь на C.
Архитектуры и ОС, для которых явно нет CLANG или для которых он находится в экспериментальном состоянии.
C более широко принят, но LLVM IR позволяет вам кормить движок LLVM с ложечки. Не все пути к IR равны.
Я буду использовать LLVM для обозначения фреймворка и LLVM IR для обозначения целевого языка.
Преимущества C
- Кроссплатформенность
- Отладка (Пожалуйста, прочитайте ниже. Это частично связано с пунктом 4.)
- Совместимость
- Простота использования
Преимущества LLVM IR
- Представление
- Варианты настройки
- Объем памяти
- Строгая типизация/безопасность
С
Существуют C-компиляторы для всех видов встраиваемых систем, хотя в последнее время LLVM получил больше целей. Можно утверждать, что C имеет небольшое преимущество перед LLVM IR (промежуточное представление) в этой категории.
Основное преимущество ориентации на C вместо LLVM заключается в том, что сгенерированный код находится на более высоком уровне по сравнению с LLVM. Можно утверждать, что при использовании стандартизированных отладчиков, таких как GDB, легче рассуждать о поведении сгенерированного кода. Также проще использовать отладчик, такой как GDB, для создания отладчика для языка, скомпилированного в C.
Третий пункт. Интероперабельность более суетливая. Однако C имеет стандартизированный бинарный интерфейс приложения. Таким образом, проще писать библиотеки и связывать эти библиотеки с другими программами, написанными на C и/или C+. Тем не менее, многие языки, такие как Java, предоставляют стандартизированные интерфейсы для C.
Можно утверждать, что легче начать работу и заставить что-то работать, нацелившись на C.
LLVM
C - язык довольно высокого уровня, и если он не написан, идиоматически, производительность может ухудшиться (в зависимости от целевого компилятора и от того, какие предположения делает указанный компилятор). Есть некоторые документы, такие как Бэкэнд llVM для GHC, который иллюстрирует некоторые недостатки C и преимущества LLVM IR как целевого языка.
Поскольку LLVM (фреймворк) построен как набор повторно используемых модулей, легко написать проходы для конкретного целевого языка для вашего конкретного целевого языка. Также проще написать собственный сборщик мусора (по состоянию на 2020 год для этого есть некоторая поддержка) . В случае C это также возможно, и есть некоторые сборщики мусора, такие как Boehm GC. Однако C не предназначен для использования в качестве промежуточного языка.
Отпечаток памяти. Сгенерированный код C занимает больше памяти по сравнению с битовым кодом LLVM. Если вы компилируете и компонуете большую систему, вы, скорее всего, получите преимущество во времени компиляции, ориентируясь на LLVM.
В то время как C является слабо типизированным языком. LLVM IR является строго типизированным. Поэтому можно утверждать, что безопаснее ориентироваться на LLVM IR.