Как заставить 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 но вы можете использовать любую другую версию):

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

    clang-3.8 -S -emit-llvm *.c
    
  2. связать их в один

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

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

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

    clang-3.8 optimised.s
    

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

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

Вы читали clang документация? Вы, вероятно, ищете -emit-llvm,

Другие вопросы по тегам