1

So... I have recently (~2 weeks now) been diving into LLVM. I have read the docs, walked through the tutorials etc.

I decided to try and take things a bit further, namely bring types into Kaleidoscope tutorial. Immediately I hit a wall when I discovered that MCJIT will only runFunction() on Functions with main style signatures. Now I understand why the tutorial wraps the functions in an anon function...

I have spent a long time trying to get somewhere on this, and to no luck. I can't find any examples of this on the web which seems strange. I have been able to change the ExecutionEngine to use the Interpreter and got perfect results, however this seems kind of pointless, I may as well just write a 'core library' in c++ and call the functions conditionally.

I know I can finaliseObject() and get the function pointer, but it just moves things back one, since I have to cast the function, and while I would know the function signature, I know of no way to dynamically cast a function pointer.

My question is assuming I have an LLVM Function ready to go, added to a module etc. how can I call this function via MCJIT?

Thanks for any help.

Below is my current scratch pad of code.

InitializeNativeTarget();
InitializeNativeTargetAsmPrinter();
LLVMContext context;
IRBuilder<> Builder(context);

std::unique_ptr<Module> Owner(new Module("test", context));
Module *module = Owner.get();

Function* func = cast<Function>(module->getOrInsertFunction("add-test", Type::getInt32Ty(context), Type::getInt32Ty(context), Type::getInt32Ty(context), NULL));

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

Function::arg_iterator args = func->arg_begin();
Argument *arg_l = &*func->arg_begin();
arg_l->setName("arg_l");
Argument *arg_r = &(*++func->arg_begin());
arg_r->setName("arg_r");

Value* add = BinaryOperator::CreateAdd(arg_l, arg_r, "real-add", block);

ReturnInst::Create(context, add, block);

std::string errStr;
ExecutionEngine *EE = EngineBuilder(std::move(Owner)).setErrorStr(&errStr).create();

if (!EE) {
    errs() << "Failed to start Execution Engine";
    return;
}

EE->finalizeObject();

And now if I get a pointer to the function, Success! it works.

int (*function)(int, int) = (int (*)(int, int))EE->getPointerToFunction(func);
int resi = function(11, 13);
outs() << "Result: " <<resi << "\n";

But If I try and run the function in the EE, then I get "Full-featured argument passing not supported yet!"

std::vector<GenericValue> Args(2);
Args[0].IntVal = APInt(32, 1);
Args[1].IntVal = APInt(32, 2);
GenericValue GV = EE->runFunction(func, Args);
outs() << "Result: " << GV.IntVal << "\n";
Steffan
  • 200
  • 5
  • This is a limitation of MCJIT. You would need to look at the new ORC JIT API. Please, take a look at this documentation: http://llvm.org/docs/tutorial/BuildingAJIT1.html – AlexDenisov Mar 10 '17 at 10:34

0 Answers0