我正在学习llvm,并希望对我的想法进行概念验证.
基本上,我想分割我的编译器和我的运行时.编译器会给出一个.bc,运行时会通过ParseBitcodeFile加载它并使用ExecutionEngine来运行它.这部分正在运作.
现在,为了轻松地进行系统调用,我希望能够在我的运行时C/C++函数中实现所有系统调用(文件io,stdout打印等).我的问题是,如何从我的玩具编译器中调用这些函数,这些函数由llvm在不同的步骤中编译,并允许在执行时使用它.
Eli*_*sky 11
好消息:使用JIT时ExecutionEngine,这将起作用.当JIT-er找到IR使用的外部符号时,它在IR本身中找不到,它会查看JIT-ing过程本身,因此可以调用从主程序可见的任何符号.
这在LLVM教程的第4部分中有直接解释:
哇,JIT怎么知道罪和cos?答案非常简单:在这个例子中,JIT开始执行函数并进入函数调用.它意识到该函数尚未编译JIT并调用标准的例程集来解析函数.在这种情况下,没有为函数定义主体,因此JIT最终在Kaleidoscope进程本身上调用了"dlsym("sin")".由于"sin"是在JIT的地址空间中定义的,它只是简单地修补模块中的调用以直接调用libm版本的sin.
对于血淋淋的细节看lib/ExecutionEngine/JIT/JIT.cpp- 特别是它的用法DynamicLibrary.
Eli的答案很棒,你应该接受它.但是,还有另一种选择,即将运行时的源文件单独编译为LLVM模块(例如使用Clang)并用于ExecutionEngine::addModule()添加它们.
它不太方便,它意味着两次编译相同的文件(一次用于主机程序,另一次用于从中获取Module),但优点是它可以通过JITted代码实现内联和其他跨功能优化.
| 归档时间: |
|
| 查看次数: |
2346 次 |
| 最近记录: |