将 LLVM JIT 代码链接到外部 C++功能

发布于 2024-10-07 00:19:02 字数 898 浏览 6 评论 0原文

我正在编写一个 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*)”声明不是定义

显然我做的事情非常错误。任何帮助将不胜感激

I'm writing a LLVM scripting engine that JIT compiles scripting code in a custom language. My problem is that I'm unable to call external functions (even the C99 erf() function is failing).

For example if I extern "C" the erf function,

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

and create a function with external linkage

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

get the following error message when running my script with erft(0.0) :

LLVM ERROR: Program used external function 'erft' which could not be resolved!

Doing the mapping manually,

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

will get me the following error:

declaration of `void llvm::ExecutionEngine::addGlobalMapping(const llvm::GlobalValue*, void*)' outside of class is not definition

Obviously I'm doing something very wrong. Any help would be much appreciated

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

╭ゆ眷念 2024-10-14 00:19:02

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

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

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

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

Assuming you haven't disabled it (by calling EE->DisableSymbolSearching()) then LLVM will use dlsym() to find the symbols in the JIT program itself. Depending on your platform, that might mean that you need to build your JIT with -fPIC, or that it might not be available at all (such as on Windows).

Aside from automatic symbol searching, you can always register the individual functions yourself using EE->addGlobalMapping(GV, &function) where GV = the llvm::Function* function declaration that matches the native function you're calling. In your case with ertf() that's:

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

Note that you named the global function erft() and the local variable erft, hence the "::". Please pick different names next time!

遥远的绿洲 2024-10-14 00:19:02

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

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

请参阅此处 有关 Module::addLibrary() 的更多信息。

This might be happening because you forgot to add the "libm" depedency, try using:

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

See here for more information about the Module::addLibrary().

猫烠⑼条掵仅有一顆心 2024-10-14 00:19:02

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

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

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

I don't know llvm, but this make no sense:

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

That defines a new function in C++. What you need to do is somehow register your function with LLVM. Defining that function is like trying to add new methods to the LLVM classes, not what you want to do.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文