Почему я не берусь за дело со своим очень собственным низким трением способ вынудить меня?:-)
то, Что я делаю, просто: Я пытаюсь сделать свои сообщения о фиксации мерзавца с энергией (редактор по умолчанию, когда Вы не определяете сообщение в командной строке).
, Конечно, сообщение о фиксации так коротко, что оно едва помогает. Но при переиздании сообщения с git commit --amend
это более полезно.
Обычно компилируйте ассемблерные файлы LLVM с помощью llvm-as:
llvm-as *.ll
Скомпилируйте файлы битового кода в .s ассемблерные языковые файлы:
llc *.bc
GCC их в библиотеку времени исполнения:
gcc *.s runtime.c -o executable
При необходимости подмените их реальными makefiles, разделяемыми библиотеками и т.д. Идея понятна.
Я предполагаю, что вы пишете преобразование LLVM и хотите добавить вызовы внешних функций в преобразованный код. Если это не так, отредактируйте свой вопрос и включите дополнительную информацию.
Прежде чем вы сможете вызвать внешнюю функцию из кода LLVM, вам необходимо вставить для нее объявление. Например:
virtual bool runOnModule(Module &m) {
Constant *log_func = m.getOrInsertFunction("log_func",
Type::VoidTy,
PointerType::getUnqual(Type::Int8Ty),
Type::Int32Ty,
Type::Int32Ty,
NULL);
...
}
В приведенном выше коде объявляется функция log_func
, которая возвращает void и принимает три аргумента: байтовый указатель (строку) и два 32-битных целых числа. getOrInsertFunction
- это метод модуля Module
.
Чтобы вызвать функцию, вы должны вставить CallInst
. Для этого существует несколько статических методов Create
.
Я интерпретирую Ваш вопрос как "как мне реализовать библиотеку времени исполнения на C или C++ для моего языка, которая компилируется в LLVM?"
Один подход, как подробно описал Джонатан Танг, заключается в преобразовании вывода Вашего компилятора из LLVM IR в биткод для ассемблера, и использовании ванильной gcc
компоновки ассемблера с исходным кодом времени исполнения (или с объектными файлами).
Альтернативным, возможно, более гибким подходом является использование llvm-gcc
для компиляции самого времени исполнения в биткод LLVM, а затем использование llvm-ld
для компоновки биткода, полученного от Вашего компилятора, с биткодом времени исполнения. Затем этот биткод может быть повторно оптимизирован с помощью opt
, преобразован обратно в IR с помощью llvm-диск
, интерпретированный непосредственно с помощью lli
(это будет, afaik, Работает только в том случае, если LLVM была собрана против libffi
), или скомпилирована для сборки с llc
(а затем в нативный двоичный файл с ванилью gcc
).