向LLVM JIT'd C++公开内部C ++函数

exposing internal c++ function to llvm jit'd c++

本文关键字:内部 函数 C++ JIT LLVM      更新时间:2023-10-16

我现在正在尝试使用llvm。我想使用可以编译为llvm位码的脚本语言。到目前为止,我已经设法加载一个llvm位码模块,并从我的"内部"c++代码中调用其中定义的函数。接下来,我尝试从我的内部代码中暴露一个c++函数到jit代码-到目前为止,在这个努力中,我还没有设法得到任何东西,除了SEGFAULT。

我的代码如下:我尝试在我的执行引擎中创建一个函数和一个指向我想调用的函数的全局映射。
extern "C" void externGuy()
{
   cout << "I'm the extern guy" << endl;
}
void ExposeFunction()
{
   std::vector<Type*> NoArgs(0);
   FunctionType* FT = FunctionType::get(Type::getVoidTy(getGlobalContext()), NoArgs, false);
   Function* fnc = Function::Create(FT, Function::ExternalLinkage, "externGuy", StartModule);
   JIT->addGlobalMapping(fnc, (void*)externGuy);
}
// ... Create module, create execution engine
ExposeFunction();

是问题,我不能添加一个功能模块后,它从位码文件加载?

更新:我已经重构了我的代码,使其读起来像这样:

// ... Create module, create execution engine
std::vector<Type*> NoArgs(0);
FunctionType* FT = FunctionType::get(Type::getVoidTy(getGlobalContext()), NoArgs, false);
Function* fnc = Function::Create(FT, Function::ExternalLinkage, "externGuy", m);
fnc->dump();
JIT->addGlobalMapping(fnc, (void*)externGuy);

所以我得到:

Program used external function 'externGuy' which could not be resolved 

同样,dump()的结果打印:

declare void @externGuy1()

如果我改变我的c++脚本位码的东西叫externGuy1()而不是externGuy()它会建议我,我的意思是使用externGuyaddGlobalMapping似乎对我不起作用。我不知道我错过了什么。我还把-fPIC添加到我的编译命令中,就像我在另一个问题中看到的那样——老实说,我不确定它是否有帮助,但尝试一下没有坏处。

我终于让它工作了。我的怀疑是,也许创建函数,以及在脚本中定义它,导致可能不止一个函数名称的声明和映射只是没有工作。我所做的是在脚本中定义函数,然后使用getFunction用于映射。在函数输出上使用dump()方法:

declare void @externGuy() #1

这就是为什么我认为这与映射最初不能工作有关。我还记得万花筒教程说,getPointerToFunction将做JIT编译时,它被调用,如果它还没有完成,所以我认为我必须做映射之前,这个调用。

为了使这一切正常工作,它是这样写的:

// Get the function and map it
Function* extrn = m->getFunction("externGuy");
extrn->dump();
JIT->addGlobalMapping(extrn, (void*)&::externGuy);
// Get a pointer to the jit compiled function
Function* mane = m->getFunction("hello");
void* fptr = JIT->getPointerToFunction(mane);
// Make a call to the jit compiled function which contains a call to externGuy
void (*FP)() = (void(*)())(intptr_t)fptr;
FP();