• entries
    625
  • comments
    1446
  • views
    1007178

LLVM... it LIVES!

Sign in to follow this  
ApochPiQ

1284 views

So I decided that I was tired of not working on the VM side of things, and rigged up a simple test harness for LLVM.

Basically, this creates the following situation:

  • getstuff() is a function defined in the native .EXE which returns a simple integer
  • answer() is a function defined in LLVM bitcode at runtime
  • answer() accepts one integer parameter, adds it to the return value of getstuff(), and returns the result
  • The native .EXE will JIT compile answer() to native code, execute it, and print its return value

    All this is pretty simple to do:

    int _tmain(int argc, _TCHAR* argv[])
    {
    using namespace llvm;

    InitializeNativeTarget();

    LLVMContext& Context = getGlobalContext();

    Module* module = new Module("EpochJIT", Context);

    IRBuilder<> Builder(Context);

    std::map NamedValues;


    std::vector args(1, Type::getInt32Ty(Context));
    FunctionType* functype = FunctionType::get(Type::getInt32Ty(Context), args, false);

    Function* func = Function::Create(functype, Function::ExternalLinkage, "answer", module);

    std::vector Args;
    Args.push_back("a");

    unsigned Idx = 0;
    for(Function::arg_iterator AI = func->arg_begin(); Idx != Args.size(); ++AI, ++Idx)
    {
    AI->setName(Args[Idx]);
    NamedValues[Args[Idx]] = AI;
    }

    BasicBlock* block = BasicBlock::Create(Context, "entry", func);
    Builder.SetInsertPoint(block);

    std::vector noargs;
    FunctionType* getstufffunctype = FunctionType::get(Type::getInt32Ty(Context), noargs, false);
    Function* getstufffunc = Function::Create(getstufffunctype, Function::ExternalLinkage, "getstuff", module);

    Value* stuff = Builder.CreateCall(getstufffunc);

    Value* addition = Builder.CreateAdd(NamedValues["a"], stuff, "addtmp");

    Builder.CreateRet(addition);

    verifyFunction(*func);

    module->dump();

    std::string ErrStr;
    ExecutionEngine* ee = EngineBuilder(module).setErrorStr(&ErrStr).create();
    if(!ee)
    {
    std::cout << ErrStr << std::endl;
    return 1;
    }

    void* fptr = ee->getPointerToFunction(func);
    int (*fp)(int) = (int (*)(int))fptr;

    std::wcout << fp(2) << std::endl;

    return 0;
    }


    And the results speak for themselves:

    LLVM Test.png
Sign in to follow this  


6 Comments


Recommended Comments

Ah, LLVM.. I've played with it a bit, such a quality library and if/when I get around to needing/wanting my own scripting language it is hands down my first choice for the backend.

Share this comment


Link to comment
Yeah, I've been extremely impressed by the library so far. Very clean design and stupid powerful.

I honestly was pleasantly surprised to discover that it's possible to go from AST to JIT'ed native code in a lazy evening's worth of work.

Share this comment


Link to comment
I was going to use it for a BASIC dialect I made a while back but I couldn't figure it out and the documentation wasn't of much help.
:/
I might have to relook at it since you claim that it is so easy to use!

Share this comment


Link to comment
Only problem I had at the time was the release didn't support VS2010 out of the box, but that's long since been fixed.

What I found helpful was following the tutorial series on making their toy language; it was a decent intro to the lib and gave you something to jump from into the docs.

Share this comment


Link to comment
Well, the compile of the LLVM project does take up a fair chunk of space when you factor in all the .obj files etc; the final library directory I think I was using was somewhere around 700meg, the 'build' directory does apprently take up 8gb however you do have to weight that against how good the library is and what it can do.

In short; while big that really isn't an issue.

Share this comment


Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now