我正在学习llvm并希望对我所拥有的想法进行概念验证。
基本上,我想分割我的编译器和运行时。编译器会给出一个.bc,运行时会通过ParseBitcodeFile加载它并使用ExecutionEngine来运行它。这部分正在运作。
现在,为了轻松地进行系统调用,我希望能够在我的运行时C / C ++函数中实现所有系统调用(文件io,stdout打印等)。我的问题是,如何从我的玩具编译器中调用这些函数,这些函数由llvm在不同的步骤中编译,并允许在执行时使用它。
答案 0 :(得分:11)
好消息:当使用JIT ExecutionEngine
时,这将正常工作。当JIT-er找到IR使用的外部符号时,它在IR本身中找不到,它会查看JIT-ing过程本身,因此可以调用从主程序可见的任何符号。
直接在part 4 of the LLVM tutorial中解释:
哇,JIT如何了解罪和cos?答案是 非常简单:在这个例子中,JIT开始执行a 功能并进入函数调用。它意识到功能是 还没有JIT编译并调用标准的例程集 解决这个问题。在这种情况下,没有为此定义的主体 函数,所以JIT最终调用了“dlsym(”sin“)” 万花筒过程本身。因为“罪”是在JIT中定义的 地址空间,它只是修补模块中的调用来调用 libm版本的sin直接。
有关详细信息,请查看lib/ExecutionEngine/JIT/JIT.cpp
- 特别是DynamicLibrary
的使用情况。
答案 1 :(得分:9)
ExecutionEngine::addModule()
添加它们。
它不太方便,这意味着两次编译相同的文件(一次用于主机程序,另一次用于从中获取Module
),但优点是它可以实现内联和其他跨功能优化你的JITted代码。