Как заставить clang компилировать llvm IR

Я хочу, чтобы clang компилировал мой код C/C++ в LLVM байт-код вместо бинарного исполняемого файла. Как я могу это достичь? И если я получаю байт-код LLVM, как я могу взять его для дальнейшей компиляции в бинарный исполняемый файл.

В основном я хочу добавить некоторый мой собственный код в байт-код LLVM перед компиляцией в двоичный исполняемый файл.

Ответ 1

Учитывая некоторый файл C/С++ foo.c:

> clang -S -emit-llvm foo.c

Производит foo.ll, который является IR файлом LLVM.

Опция -emit-llvm также может быть передана непосредственно на интерфейс компилятора, а не с помощью -cc1:

> clang -cc1 foo.c -emit-llvm

Производит foo.ll с помощью IR. -cc1 добавляет некоторые интересные варианты, такие как -ast-print. Подробнее см. -cc1 --help.


Чтобы скомпилировать LLVM IR далее для сборки, используйте инструмент llc:

> llc foo.ll

Производит foo.s со сборкой (по умолчанию для архитектуры машины вы ее запускаете). llc является одним из инструментов LLVM - вот его документация.

Ответ 2

Использование

clang -emit-llvm -o foo.bc -c foo.c
clang -o foo foo.bc

Ответ 3

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

Вместо этого вы хотите скомпилировать с оптимизацией времени ссылки

clang -flto -c program1.c -o program1.o
clang -flto -c program2.c -o program2.o

и для окончательного этапа соединения добавьте аргумент -Wl, -plugin-opt = also-emit-llvm

clang -flto -Wl,-plugin-opt=also-emit-llvm program1.o program2.o -o program

Это дает вам как скомпилированную программу, так и соответствующий ему битовый код (program.bc). Затем вы можете изменить программу program.bc любым способом и перекомпилировать измененную программу в любое время, выполнив

clang program.bc -o program

хотя имейте в виду, что на этом этапе вам нужно включить все необходимые флаги компоновщика (для внешних библиотек и т.д.).

Обратите внимание, что для этого вам нужно использовать золотой линкер. Если вы хотите заставить clang использовать конкретный компоновщик, создайте символическую ссылку на этот компоновщик с именем "ld" в специальном каталоге под названием "fakebin" где-то на вашем компьютере и добавьте опцию

-B/home/jeremy/fakebin

для любых шагов связи выше.

Ответ 4

Вы читали clang documentation? Вероятно, вы ищете -emit-llvm.

Ответ 5

Если у вас несколько файлов, и вы не хотите вводить каждый файл, я бы рекомендовал вам выполнить следующие простые шаги (я использую clang-3.8, но вы можете использовать любую другую версию):

  • сгенерировать все .ll файлы

    clang-3.8 -S -emit-llvm *.c
    
  • свяжите их с одним

    llvm-link-3.8 -S -v -o single.ll *.ll
    
  • (Необязательно) Оптимизируйте свой код (возможно, некоторый анализ псевдонимов)

    opt-3.8 -S -O3 -aa -basicaaa -tbaa -licm single.ll -o optimised.ll
    
  • Сгенерировать сборку (создает файл optimised.s)

    llc-3.8 optimised.ll
    
  • Создайте исполняемый файл (с именем a.out)

    clang-3.8 optimised.s