将LLVM JIT代码链接到外部C++函数

ant*_*rts 18 linker jit llvm

我正在编写一个LLVM脚本引擎,JIT用自定义语言编写脚本代码.我的问题是我无法调用外部函数(即使C99 erf()函数失败).

例如,如果我extern"C"erf函数,

extern "C" double erft(double x){
return erf(x);
}
Run Code Online (Sandbox Code Playgroud)

并创建一个外部链接功能

std::vector<const Type*> Double1(1,Type::getDoubleTy(getGlobalContext()));
FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()),Double1,false);
Function *erft = Function::Create(FT,Function::ExternalLinkage,"erft",TheModule);
Run Code Online (Sandbox Code Playgroud)

使用erft(0.0)运行脚本时出现以下错误消息:

LLVM错误:程序使用的外部功能'erft'无法解决!

手动执行映射,

void ExecutionEngine::addGlobalMapping( const GlobalValue *  erfF, void *  erft); 
Run Code Online (Sandbox Code Playgroud)

会得到以下错误:

在类之外的`void llvm :: ExecutionEngine :: addGlobalMapping(const llvm :: GlobalValue*,void*)'的声明不是定义

显然我做错了.任何帮助将非常感激

小智 15

假设您没有禁用它(通过调用EE->DisableSymbolSearching()),那么LLVM将用于dlsym()在JIT程序本身中查找符号.根据您的平台,这可能意味着您需要构建JIT -fPIC,或者可能根本不可用(例如在Windows上).

除了自动符号搜索之外,您还可以使用EE->addGlobalMapping(GV, &function)GV =与您正在调用的本机函数匹配的llvm :: Function*函数声明来自己注册各个函数.在您的情况下使用ertf():

EE->addGlobalMapping(erft, &::erft);
Run Code Online (Sandbox Code Playgroud)

请注意,您将全局函数erft()和局部变量命名erft为"::".请在下次选择不同的名字!


Win*_*ert 0

我不知道 llvm,但这没有意义:

void ExecutionEngine::addGlobalMapping( const GlobalValue *  erfF, void *  erft); 
Run Code Online (Sandbox Code Playgroud)

这在 C++ 中定义了一个新函数。您需要做的是以某种方式向 LLVM 注册您的函数。定义该函数就像尝试向 LLVM 类添加新方法,而不是您想要做的事情。