2009-12-03 19 views
22

Ho generato un file bc con il compilatore online su llvm.org e vorrei sapere se è possibile caricare questo file bc dal programma ac o C++, eseguire l'IR nel bc file con llvm jit (programmaticamente nel programma c), e ottieni i risultati.Chiama LLVM Jit dal programma c

Come posso realizzare questo?

risposta

-3

Dalla riga di comando, è possibile utilizzare il programma LLVM per eseguire un file bc. Se il file è in linguaggio assembly LLVM, è necessario eseguire llvm-come su di esso per creare un file bitcode binario.

E 'facile fare questo da C. mi consiglia si guarda alla vasta documentazione LLVM: http://llvm.org/docs

canale IRC LLVM, che ha un link in quella pagina, è pieno di persone molto competenti che sono disposti a rispondere alle domande.

Ci scusiamo per la risposta indiretta. Uso LLVM in modo estensivo, ma eseguo la generazione diretta del codice non solo in tempo reale.

15

Questo dovrebbe (più o meno) funzionare utilizzando LLVM 2.6. Sembra che ci siano altre funzioni di supporto in SVN per creare un ModuleProvider pigro su un file bitcode. Non ho ancora provato a compilarlo, ho solo incollato alcuni pezzi di una delle mie applicazioni 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

Ecco un po 'di codice di lavoro basato su Nathan Howell di:

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

Una stranezza era che senza la finale comprendono, ee è NULL. Bizzarro.

Per generare il mio tst.bc, ho utilizzato http://llvm.org/demo/index.cgi e lo strumento da riga di comando llvm-as.

+1

Doh, #incluso è necessario per forzare il linker a tirare in JIT, altrimenti sarebbe scartato. Aggiornerò il mio campione –

+0

C'è c api per fare questo? – Ariel

+1

Ariel: sì, la maggior parte di LLVM è utilizzabile da plain C, utilizzando i binding forniti con LLVM stesso. Vedi http://llvm.org/docs/FAQ.html#langirgen e http://npcontemplation.blogspot.com/2008/06/secret-of-llvm-c-bindings.html –

Problemi correlati