LLVM - проблема со связью

Пишу генератор кода LLVM для языка Timber, текущий компилятор выдает C-код. Моя проблема в том, что мне нужно вызывать функции C из сгенерированных файлов LLVM, например, компилятор имеет сборщик мусора в реальном времени, и мне нужно вызывать функции, чтобы уведомлять, когда новые объекты выделяются в куче. Я понятия не имею, как связать эти функции с моими сгенерированными файлами LLVM.

Генерация кода производится путем генерации .ll-файлов и их последующей ручной компиляции.

Я пытаюсь вызвать внешнюю функцию из LLVM, но мне не повезло. В примерах, которые я нашел, вызываются только стандартные функции C, такие как "puts" и "printf", но я хочу вызвать >домашнюю функцию. Я застрял.


person capitrane    schedule 13.09.2009    source источник
comment
Вы имеете в виду, что пытаетесь написать код непосредственно в LLVM IR и не можете позвонить, или что вы компилируете код с помощью LLVM и у вас возникают проблемы?   -  person Stephen Canon    schedule 14.09.2009


Ответы (3)


Скомпилируйте ваши файлы сборки LLVM обычным образом с помощью llvm-as:

llvm-as *.ll

Скомпилируйте файлы битового кода в файлы языка ассемблера .s:

llc *.bc

GCC их с библиотекой времени выполнения:

gcc *.s runtime.c -o executable

При необходимости замените на настоящие make-файлы, разделяемые библиотеки и т. д. Вы поняли идею.

person Jonathan Tang    schedule 01.01.2010

Я предполагаю, что вы пишете преобразование 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 — это метод 1Module.html" rel="noreferrer">Module.

Чтобы вызвать функцию, вам нужно вставить 1CallInst.html" rel="noreferrer">CallInst. Для этого есть несколько статических Create методов.

person Jay Conrod    schedule 23.10.2009
comment
Это именно то, что я только что пытался понять, чтобы сделать с llvm, спасибо! - person Dan; 29.11.2009

Я интерпретирую ваш вопрос как «как мне реализовать библиотеку времени выполнения на C или C++ для моего языка, который компилируется в LLVM?»

Один из подходов, описанный Джонатаном Тангом, заключается в преобразовании вывода вашего компилятора из LLVM IR в битовый код и сборку, а также в ванильном gcc связывании сборки с исходным кодом среды выполнения (или объектными файлами).

Альтернативным, возможно, более гибким подходом является использование llvm-gcc для компиляции самой среды выполнения в битовый код LLVM, а затем использование llvm-ld для связывания битового кода из вашего компилятора с битовым кодом вашей среды выполнения. Затем этот битовый код можно повторно оптимизировать с помощью opt, преобразовать обратно в IR с помощью llvm-dis, интерпретировать непосредственно с помощью lli (это, по правде говоря, будет работать только в том случае, если LLVM был собран для libffi) или скомпилировать в сборку с помощью llc (а затем в нативный код). бинарник с ванилью gcc).

person Ben Karel    schedule 27.01.2010