Как заставить 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