【问题标题】:Linking LLVM JIT code to external C++ functions将 LLVM JIT 代码链接到外部 C++ 函数
【发布时间】:2011-05-24 11:19:33
【问题描述】:

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

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

【问题讨论】:

  • 对未来访问者的警告:答案是指已弃用的方法..
  • this 问题的答案显示了如何使用未弃用的方法来做到这一点。

标签: linker jit llvm


【解决方案1】:

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

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

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

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

【讨论】:

    【解决方案2】:

    这可能是因为您忘记添加“libm”依赖,尝试使用:

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

    有关Module::addLibrary() 的更多信息,请参阅here

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

        猜你喜欢
        • 2011-02-17
        • 2023-03-19
        • 2015-10-06
        • 2021-01-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多