Вызов LLVM Jit из c программы - PullRequest
       41

Вызов LLVM Jit из c программы

22 голосов
/ 03 декабря 2009

Я сгенерировал файл bc с онлайн-компилятором на llvm.org, и я хотел бы знать, возможно ли загрузить этот файл bc из программы ac или c ++, выполнить IR в файле bc с помощью файла llvm jit (программно в программе c) и получить результаты.

Как мне это сделать?

Ответы [ 3 ]

23 голосов
/ 18 января 2010

Вот некоторый рабочий код, основанный на Натане Хауэлле:

#include <string>
#include <memory>
#include <iostream>

#include <llvm/LLVMContext.h>
#include <llvm/Target/TargetSelect.h>
#include <llvm/Bitcode/ReaderWriter.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/ModuleProvider.h>
#include <llvm/Support/MemoryBuffer.h>
#include <llvm/ExecutionEngine/JIT.h>

using namespace std;
using namespace llvm;

int main()
{
    InitializeNativeTarget();
    llvm_start_multithreaded();
    LLVMContext context;
    string error;
    Module *m = ParseBitcodeFile(MemoryBuffer::getFile("tst.bc"), context, &error);
    ExecutionEngine *ee = ExecutionEngine::create(m);

    Function* func = ee->FindFunctionNamed("main");

    typedef void (*PFN)();
    PFN pfn = reinterpret_cast<PFN>(ee->getPointerToFunction(func));
    pfn();
    delete ee;
}

Одна странность заключалась в том, что без окончательного включения ee равно NULL. Bizarre.

Для создания моего tst.bc я использовал http://llvm.org/demo/index.cgi и инструмент командной строки llvm-as.

15 голосов
/ 29 декабря 2009

Это должно (более или менее) работать с использованием LLVM 2.6. Похоже, в SVN есть еще несколько вспомогательных функций для создания ленивого ModuleProvider поверх файла битового кода. Хотя я не пытался его скомпилировать, просто склеил несколько кусочков из одного из моих JIT-приложений.

#include <string>
#include <memory>

#include <llvm/Bitcode/ReaderWriter.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/ModuleProvider.h>
#include <llvm/Support/MemoryBuffer.h>
#include <llvm/ExecutionEngine/JIT.h>

using namespace std;
using namespace llvm;

int main()
{
    InitializeNativeTarget();
    llvm_start_multithreaded();
    LLVMContext context;

    string error;
    auto_ptr<MemoryBuffer> buffer(MemoryBuffer::getFile("bitcode.bc"));
    auto_ptr<Module> module(ParseBitcodeFile(buffer.get(), context, &error));
    auto_ptr<ModuleProvider> mp(new ExistingModuleProvider(module));
    module.release();

    auto_ptr<ExecutionEngine> ee(ExecutionEngine::createJIT(mp.get(), &error));
    mp.release();

    Function* func = ee->getFunction("foo");

    typedef void (*PFN)();
    PFN pfn = reinterpret_cast<PFN>(ee->getPointerToFunction(func));
    pfn();
}
0 голосов
/ 19 декабря 2009

Из командной строки вы можете использовать программу LLVM lli для запуска файла bc. Если файл написан на языке ассемблера LLVM, сначала вам нужно будет запустить на нем llvm-as, чтобы создать двоичный файл битового кода.

Это легко сделать из C. Я рекомендую вам взглянуть на обширную документацию LLVM: http://llvm.org/docs

IRC-канал LLVM, на котором есть ссылка на эту страницу, полон очень знающих людей, которые готовы ответить на вопросы.

Извините за косвенный ответ. Я широко использую LLVM, но я делаю прямую генерацию кода не только во время компиляции.

...