所以......我最近(现在约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";