Я создал файл bc с онлайн-компилятором на llvm.org, и я хотел бы знать, можно ли загрузить этот файл bc из программы ac или С++, выполнить IR в файле bc с помощью llvm jit (программно в программе c) и получить результаты.
Как я могу это сделать?
Я создал файл bc с онлайн-компилятором на llvm.org, и я хотел бы знать, можно ли загрузить этот файл bc из программы ac или С++, выполнить IR в файле bc с помощью llvm jit (программно в программе c) и получить результаты.
Как я могу это сделать?
Вот какой рабочий код, основанный на Nathan Howell's:
#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.
Это должно (более или менее) работать с использованием 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();
}
В командной строке вы можете использовать LLVM-программу lli для запуска bc файла. Если файл находится на языке ассемблера LLVM, вам нужно запустить llvm-as сначала, чтобы создать файл двоичного файла биткода.
Это легко сделать с C. Я бы рекомендовал вам посмотреть обширную документацию LLVM: http://llvm.org/docs
Канал LLVM irc, который имеет ссылку на этой странице, полон очень знающих людей, которые готовы ответить на вопросы.
Извините за косвенный ответ. Я использую LLVM экстенсивно, но я делаю прямое генерирование кода не только во время усложнения.