Вопросы для компиляции в LLVM

Я играл с LLVM, чтобы узнать, как его использовать.

Однако мой ум ошеломлен уровнем сложности интерфейса.

Возьмем, например, свою функцию Фибоначчи

int fib(int x) {
    if(x<=2) 
        return 1;
    return fib(x-1) + fib(x-2);
   }

Чтобы получить это для вывода LLVM IR, требуется 61 строка кода!!!

Они также включают BrainFuck, который известен тем, что имеет самый маленький компилятор (200 байт). К сожалению, с LLVM он превышает 600 строк (18 kb).

Является ли это нормой для компилятора? До сих пор кажется, что было бы намного проще выполнить сборку или C-сервер.

Ответ 1

Проблема заключается в С++, а не в LLVM.

Используйте язык, предназначенный для метапрограммирования, например OCaml, и ваш компилятор будет значительно меньше. Например, эта статья OCaml Journal описывает 87-строчный компилятор Brainfuck на основе LLVM, в этом списке рассылки описывается полная реализация языка программирования, включая парсер, который может скомпилировать функцию Fibonacci (среди других программ), а весь компилятор находится под 100 строками кода OCaml с использованием LLVM и HLVM - это высокоуровневая виртуальная машина с мульчированной коллекцией с множеством ячеек, содержащая менее 2000 строк кода OCaml с использованием LLVM.

Ответ 2

Не LLVM затем оптимизирует IR в зависимости от конкретной архитектуры, реализованной в фоновом режиме? ИК-код напрямую не переводится 1:1 в окончательный двоичный код. Насколько я понимаю, как это работает. Тем не менее, я только начал играть с фоновым контентом (я переношу его на пользовательский процессор).

Ответ 3

LLVM действительно требует некоторого кода шаблона, но как только вы его понимаете, это действительно довольно просто. Попробуйте найти простой интерфейс GCC, и вы поймете, насколько чистый LLVM. Я определенно рекомендую LLVM над C или ASM. ASM вообще не переносится, и генерировать исходный код обычно плохо, потому что он делает компиляцию медленной.

Ответ 4

Промежуточные представления могут быть немного подробными, по сравнению с не виртуальным ассемблером. Я узнал, что смотрю на .NET IL, хотя я никогда не шел намного дальше, чем смотреть. Я не очень хорошо знаком с LLVM, но я думаю, это та же проблема.

Это имеет смысл, если вы думаете об этом. Одно большое различие заключается в том, что IRs должны иметь дело с большим количеством метаданных. В ассемблере очень мало - процессор неявно определяет много, а соглашения для таких вещей, как вызовы функций, оставляются программисту/компилятору для определения. Это удобно, но это создает большую мобильность и проблемы взаимодействия.

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

Есть и другие проблемы. Промежуточное представление на самом деле не предназначено для написания человеком, но оно предназначено для чтения. Кроме того, это означало быть достаточно общим, чтобы выжить в нескольких версиях без полной несовместимой реорганизации с нуля.

В принципе, в этом контексте явное почти всегда лучше, чем неявное, поэтому многословие трудно избежать.