使用LLVM MCJIT调用通用函数

时间:2017-03-09 19:36:02

标签: c++ llvm llvm-ir mcjit

所以......我最近(现在约2周)潜入LLVM。我已经阅读了文档,阅读了教程等等。

我决定尝试更进一步,即将类型纳入Kaleidoscope教程。当我发现MCJIT只会在带有主要样式签名的函数上运行函数()时,我立即碰壁。现在我理解为什么教程将函数包装在一个匿名函数中......

我花了很长时间试图在这个地方找到一个地方,但没有运气。我在网上找不到任何这个看起来很奇怪的例子。我已经能够将ExecutionEngine更改为使用Interpreter并获得了完美的结果,但这看起来毫无意义,我也可以在c ++中编写一个“核心库”并有条件地调用这些函数。

我知道我可以finaliseObject()并获取函数指针,但它只是将事物移回一个,因为我必须转换函数,虽然我知道函数签名,但我知道无法动态转换函数指针。

我的问题是假设我已准备好LLVM功能,添加到模块等。如何通过MCJIT调用此功能?

感谢您的帮助。

以下是我目前的代码清单。

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();

现在,如果我得到一个指向该功能的指针,那就成功!它有效。

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

但是如果我尝试在EE中运行该函数,那么我会得到“尚未支持的全功能参数传递!”

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";

0 个答案:

没有答案