将LLVM JIT代码链接到静态LLVM库?

17
我正在实现一个跨平台(Mac OS X、Windows和Linux)的应用程序,该应用程序将对金融数据进行大量的CPU密集型分析。出于速度原因,大部分分析引擎将使用C++编写,并与用户可访问的脚本引擎进行交互。我希望逐步编写几个脚本前端,以模拟其他具有现有大型用户群的流行软件。第一个前端将是类似VisualBasic的脚本语言。
我认为LLVM非常适合我的需求。由于数据量巨大,性能非常重要;运行一次测试可能需要数小时或数天才能得出答案。我相信使用LLVM还可以在时间推移中实现不同脚本语言的不同前端,同时使用单个后端解决方案。
测试引擎本身将与接口分离,测试甚至将在单独的进程中进行,并向测试管理界面报告进度和结果。测试将由脚本代码与测试引擎代码集成而成。
在之前的类似商业测试系统的实现中,我构建了一个快速的解释器,它很容易与测试库进行接口对接,因为它是用C++编写并直接连接到测试引擎库。从脚本代码到测试库对象的回调涉及转换格式,存在显着的开销。
我想象使用LLVM,我可以直接将回调实现到C++中,以使脚本代码几乎像是用C++编写的一样工作。同样,如果所有代码都被编译为LLVM字节码格式,似乎LLVM优化器可以在脚本语言和用C++编写的测试引擎代码之间的边界上进行优化。
我不想每次都重新编译测试引擎。理想情况下,我只想JIT编译脚本代码。对于小型测试,我会跳过一些优化步骤,而对于大型测试,在链接期间进行完整的优化。
那么这种做法可行吗?我是否可以将测试引擎预编译为.o对象文件或.a库文件,然后使用JIT链接脚本代码?

最后,理想情况下,我希望脚本代码能够作为特定C++类的子类实现特定方法。因此,C++测试引擎只会看到C++对象,而JIT设置代码编译脚本代码来实现某些对象的方法。如果使用正确的名称重整算法,则似乎可以相对容易地设置LLVM生成的脚本语言模拟C++方法调用,然后将其链接到测试引擎中。

因此,连接阶段将进行两个方向的调用:从脚本语言到测试引擎对象以检索定价信息和测试状态信息,并从测试引擎调用某些特定C++对象的方法,其中的代码不是来自C++而是来自脚本语言。

总之:

1)我是否可以在JIT编译和代码生成进程中链接预编译的(.bc、.o或.a)文件?

2)我是否可以使用上述第1步骤的过程链接代码,以便我能够创建像全部写成C++一样运行的代码?

3个回答

14
  1. 是的,我们可以!根据您使用的LLVM版本,有不同的API调用。在2.5上,您需要使用llvm::getBitcodeModuleProvider。
  2. 调用C++函数最简单的方法是使用标志llvm::Function::ExternalLinkage创建一个函数(llvm::Function::Create),然后使用addGlobalMapping将其指向您的C++函数。

3
  1. 我相信是这样的。
  2. 这有点复杂。您需要匹配调用的函数的C++ ABI,并确保生成的代码使用相同的数据结构、类、布局等(通过类似于头文件的等效物)。C++ ABI有很多微妙之处和可移植性问题。也许先尝试与C进行交互的原型设计。目前clang对C++的支持有限。

1

1) 你可以加载和链接 .bc 文件,.o 文件如果已经编译成 .so 归档文件,则应该可以加载并且其中的符号应该可以使用。

2) 只要你不想对回调函数做可怕的事情,你可能只需传递标准 C 函数指针,并通过函数指针进行回调。你也可以做一些其他的事情,但是在不是 C++ 编译器的情况下尝试定义 C++ 对象或模板或调用成员函数是不建议的。

你必须了解 C++ ABI,你必须了解你所针对的平台,你必须知道各种各样的东西,你实际上必须是一个 C++ 编译器才能生成看起来像是 C++ 的代码。名称重整是最烦人的部分之一。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接