22

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?

Machavity
  • 30,841
  • 27
  • 92
  • 100
Damien
  • 221
  • 1
  • 2
  • 4

3 Answers3

22

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.

Sacha Varma
  • 221
  • 1
  • 2
  • 1
    Doh, #including is required to force the linker to pull in the JIT, otherwise it would be discarded. I'll update my sample. – Nathan Howell Feb 03 '10 at 17:00
  • 1
    Ariel: yes, most of LLVM is usable from plain C, using bindings supplied with LLVM itself. See http://llvm.org/docs/FAQ.html#langirgen and http://npcontemplation.blogspot.com/2008/06/secret-of-llvm-c-bindings.html – Arto Bendiken Dec 02 '10 at 05:26
  • 1
    I don't think that this works anymore. TargetSelect.h is no longer in llvm/Target, and I think there may have also been some other changes over the past three years... – Talia Jan 30 '13 at 02:50
  • Indeed, the above example code does not work anymore (tested with LLVM 3.3), but the required changes to make it work are trivial : a couple of headers have moved, a couple of new ones needed, and a change in the API for ParseBitcodeFile() and MemoryBuffer::getFile(). Other than that, compiling and running *.bc files on the fly with the JIT still works like a charm :) – wldsvc Jun 01 '13 at 03:30
14

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();
}
Nathan Howell
  • 4,627
  • 1
  • 22
  • 30
-3

From the command line, you can use the LLVM program lli to run a bc file. If the file is in LLVM assembly language, you'll have to run llvm-as on it first to create a binary bitcode file.

It is easy to do this from C. I'd recommend you look at the extensive LLVM documentation: http://llvm.org/docs

The LLVM irc channel, which has a link on that page, is full of very knowledgeable people that are willing to answer questions.

Sorry for the indirect answer. I use LLVM extensively, but I do direct code generation not just in time compliation.

Richard Pennington
  • 19,673
  • 4
  • 43
  • 72