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

时间:2010-12-13 04:21:48

标签: linker jit llvm

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

例如,如果我extern“C”erf函数,

extern "C" double erft(double x){
return erf(x);
}

并创建一个具有外部链接的函数

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

使用erft(0.0)运行我的脚本时收到以下错误消息:

  

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

手动执行映射,

void ExecutionEngine::addGlobalMapping( const GlobalValue *  erfF, void *  erft); 

会出现以下错误:

  

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

显然我做错了。任何帮助将不胜感激

3 个答案:

答案 0 :(得分:15)

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

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

EE->addGlobalMapping(erft, &::erft);

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

答案 1 :(得分:2)

可能会发生这种情况,因为您忘记添加“libm”依赖项,请尝试使用:

[your module]->addLibrary("m");

有关Module::addLibrary()

的详情,请参阅here

答案 2 :(得分:0)

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

void ExecutionEngine::addGlobalMapping( const GlobalValue *  erfF, void *  erft); 

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