2009-12-03 9 views
22

Wygenerowałem plik bc z kompilatorem online na llvm.org, i chciałbym wiedzieć, czy możliwe jest załadowanie tego pliku bc z programu ac lub C++, wykonaj IR w plik bc z jlvm jit (programowo w programie c) i uzyskaj wyniki.Wywołanie LLVM Jit z programu c

Jak mogę to zrobić?

Odpowiedz

-3

Z poziomu wiersza poleceń można użyć programu LLVM lli do uruchomienia pliku Bc. Jeśli plik jest w języku asemblerowym LLVM, będziesz musiał uruchomić plik llvm-as, aby utworzyć binarny plik binarny.

Łatwo jest zrobić to z C polecam spojrzeć na obszernej dokumentacji LLVM: http://llvm.org/docs

LLVM kanał IRC, która ma link na tej stronie, jest pełen bardzo doświadczonych ludzi, są gotowi odpowiedzieć na pytania.

Przepraszamy za pośrednią odpowiedź. Używam LLVM obszernie, ale generuję bezpośrednie kodowanie nie tylko w czasie kompilacji.

15

Powinno to (mniej więcej) działać przy użyciu LLVM 2.6. Wygląda na to, że w SVN jest więcej funkcji helpera, aby stworzyć leniwego ModuleProvider na wierzchu pliku Bitcode. Jednak nie próbowałem go skompilować, po prostu skleiłem kilka bitów z jednej z moich aplikacji 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

Oto niektóre kodu roboczego na podstawie Nathan Howell użytkownika:

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

Jedną wadą było to, że bez finału obejmują ee jest NULL. Dziwaczny.

Do wygenerowania pliku tst.bc użyłem http://llvm.org/demo/index.cgi i narzędzia wiersza polecenia llvm-as.

+1

Doh, # w tym jest wymagany, aby zmusić linker do wciągnięcia JIT, w przeciwnym razie zostanie odrzucony. Zaktualizuję moją próbkę. –

+0

Czy jest to możliwe? – Ariel

+1

Ariel: tak, większość LLVM może być użyta ze zwykłego C, używając wiązań dostarczonych z samą LLVM. Zobacz http://llvm.org/docs/FAQ.html#langirgen i http://npcontemplation.blogspot.com/2008/06/secret-of-llvm-c-bindings.html –