Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call LLVM Jit from c program

Tags:

I have generated a bc file with the online compiler on llvm.org, and I would like to know if it is possible to load this bc file from a c or c++ program, execute the IR in the bc file with the llvm jit (programmatically in the c program), and get the results.

How can I accomplish this?

like image 533
Damien Avatar asked Dec 03 '09 07:12

Damien


2 Answers

Here's some working code based on 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; } 

One oddity was that without the final include, ee is NULL. Bizarre.

To generate my tst.bc, I used http://llvm.org/demo/index.cgi and the llvm-as command-line tool.

like image 113
Sacha Varma Avatar answered Oct 13 '22 01:10

Sacha Varma


This should (more or less) work using LLVM 2.6. It looks like there are some more helper functions in SVN to create a lazy ModuleProvider on top of a bitcode file. I haven't tried compiling it though, just glued together some bits from one of my JIT applications.

#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(); } 
like image 41
Nathan Howell Avatar answered Oct 13 '22 01:10

Nathan Howell