Как заставить clang компилироваться в llvm IR
Я хочу, чтобы Clang компилировал мой C/C++
код для LLVM
байт-код, а не двоичный исполняемый файл. Как я могу этого достичь? И если я получу LLVM
байт-код, как я могу взять его для дальнейшей компиляции в двоичный исполняемый файл.
В основном я хочу добавить свой собственный код в LLVM
байт-код перед компиляцией в двоичный исполняемый файл.
5 ответов
Учитывая некоторый файл C/C++ foo.c
:
> clang -S -emit-llvm foo.c
Производит foo.ll
который является IR-файлом LLVM.
-emit-llvm
Опция также может быть передана внешнему интерфейсу компилятора, а не драйверу посредством -cc1
:
> clang -cc1 foo.c -emit-llvm
Производит foo.ll
с их. -cc1
добавляет несколько интересных вариантов, таких как -ast-print
, Проверять, выписываться -cc1 --help
Больше подробностей.
Чтобы скомпилировать LLVM IR далее для сборки, используйте llc
инструмент:
> llc foo.ll
Производит foo.s
со сборкой (в зависимости от архитектуры машины, на которой вы ее запускаете). llc
является одним из инструментов LLVM - вот его документация.
Если у вас есть несколько исходных файлов, вы, вероятно, на самом деле хотите использовать оптимизацию по времени ссылки для вывода одного файла битового кода для всей программы. Другие ответы приведут к тому, что вы получите файл с битовым кодом для каждого исходного файла.
Вместо этого вы хотите скомпилировать с оптимизацией времени соединения
clang -flto -c program1.c -o program1.o
clang -flto -c program2.c -o program2.o
и для последнего шага связывания добавьте аргумент -Wl,-plugin-opt= Кроме того-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
к любым шагам связывания выше.
Если у вас есть несколько файлов, и вы не хотите вводить каждый файл, я бы порекомендовал вам следовать этим простым шагам (я использую 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
Использование
clang -emit-llvm -o foo.bc -c foo.c
clang -o foo foo.bc
Вы читали clang
документация? Вы, вероятно, ищете -emit-llvm
,