17

我正在实施一个跨平台(Mac OS X、Windows 和 Linux)应用程序,它将对财务数据进行大量 CPU 密集型分析。出于速度原因,大部分分析引擎将用 C++ 编写,用户可访问的脚本引擎与 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++ 编写的一样?

4

3 回答 3

14
  1. 我们可以!根据您使用的 LLVM 版本,有不同的 API 调用。您将需要 llvm::getBitcodeModuleProvider 2.5。
  2. 调用 C++ 函数的最简单方法是使用标志 llvm::Function::ExternalLinkage 创建一个函数 (llvm::Function::Create),然后 addGlobalMapping 使其指向您的 C++ 函数。
于 2010-05-19T01:57:00.287 回答
3
  1. 我相信是这样。
  2. 这是毛茸茸的。您需要匹配您正在调用的函数的 C++ ABI,并且需要确保生成的代码使用相同的数据结构、类、布局等(通过等效的头文件)。C++ ABI 有很多细微差别和可移植性问题。也许原型首先与 C 进行互操作。clang目前对 C++ 的支持有限。
于 2010-05-10T20:40:30.830 回答
1

1)您可以加载和链接 .bc 文件、.o 文件(如果它们已编译为 .so 存档)应该是可加载的,并且它们中的符号应该能够使用。

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

你必须了解 C++ ABI,你必须了解你的目标平台,你必须知道各种各样的事情,你必须是一个 C++ 编译器才能生成看起来像 C++ 的代码。mangler 这个名字是最烦人的部分之一。

于 2010-06-21T14:07:39.207 回答