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

时间:2010-05-10 20:03:52

标签: c++ llvm clang

我正在实施跨平台(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)我可以在预编译(.bc,.o或.a)文件中链接作为JIT编译,代码生成过程的一部分吗?

2)我是否可以使用上面1)中的过程链接代码,这样我就可以创建代码,就好像它都是用C ++编写的一样?

3 个答案:

答案 0 :(得分:14)

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

答案 1 :(得分:3)

  1. 我相信。
  2. 这很毛茸茸。您需要匹配要调用的函数的C ++ ABI,并且需要确保生成的代码使用相同的数据结构,类,布局等(通过等效的头文件)。 C ++ ABI有很多细微差别和可移植性问题。也许是首先与C互操作的原型。 clang目前对C ++的支持有限。

答案 2 :(得分:1)

1)你可以加载和链接.bc文件,.o文件,如果它们已经被编译到.so文件中,那么它应该是可加载的,并且应该能够使用它们中的符号。

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

你必须了解C ++ ABI,你必须了解你所针对的平台,你必须知道各种各样的东西,你必须是一个C ++编译器来生成看起来像C ++的代码。 mangler这个名字是最讨厌的部分之一。