2009-12-03 2 views
22

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

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

ответ

-3

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

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

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

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

15

Это должно (более или менее) работа с использованием 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(); 
} 
23

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

#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; 
} 

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

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

+1

Doh, #including требуется, чтобы заставить компоновщик втягиваться в JIT, иначе он будет отброшен. Я обновлю свой образец. –

+0

Есть ли c api для этого? – Ariel

+1

Ariel: да, большинство LLVM можно использовать с простого C, используя привязки, поставляемые с LLVM. См. Http://llvm.org/docs/FAQ.html#langirgen и http://npcontemplation.blogspot.com/2008/06/secret-of-llvm-c-bindings.html –