我正在学习llvm,并想对我的想法做一个概念证明。
基本上,我想把我的编译器和运行时分开。编译器将提供一个.bc,运行时将通过ParseBitcodeFile加载它,并使用ExecutionEngine来运行它。这部分起作用了。
现在,为了更容易地进行系统调用,我希望能够在我的运行时实现C/C++函数,这些函数执行所有的系统调用(文件io、标准输出打印等)。我的问题是,我如何从我的玩具编译器的代码中调用这些函数,并允许它在执行时使用。
发布于 2013-07-11 04:35:21
好消息是:当使用JIT ExecutionEngine
时,这将会正常工作。当JIT-er找到IR使用的外部符号,而该外部符号在IR本身中找不到时,它会查找JIT进程本身,因此可以调用主机程序中可见的任何符号。
这在part 4 of the LLVM tutorial中有直接的解释
哇,JIT怎么知道原罪和cos的?答案非常简单:在本例中,JIT开始执行函数并调用函数。它意识到该函数尚未被JIT编译并调用标准例程集来解析该函数。在本例中,没有为函数定义主体,因此JIT最终在万花筒进程本身上调用“dlsym(”sin“)”。因为“sin”是在JIT的地址空间中定义的,所以它只是修补模块中的调用,以便直接调用sin的libm版本。
关于血淋淋的细节,请看lib/ExecutionEngine/JIT/JIT.cpp
--特别是它对DynamicLibrary
的使用。
发布于 2013-07-11 06:37:01
Eli的回答很棒,你应该接受它。不过,还有另一种选择,那就是将运行时的源文件单独编译为LLVM模块(例如,使用Clang),然后使用ExecutionEngine::addModule()
添加它们。
它不太方便,而且它意味着编译相同的文件两次(一次用于您的主机程序,另一次用于从主机程序获取Module
),但好处是它支持从JITted代码进行内联和其他跨函数优化。
https://stackoverflow.com/questions/17584752
复制相似问题