从ExecutionEngine调用C / C ++函数

时间:2013-07-11 03:52:21

标签: llvm

我正在学习llvm并希望对我所拥有的想法进行概念验证。

基本上,我想分割我的编译器和运行时。编译器会给出一个.bc,运行时会通过ParseBitcodeFile加载它并使用ExecutionEngine来运行它。这部分正在运作。

现在,为了轻松地进行系统调用,我希望能够在我的运行时C / C ++函数中实现所有系统调用(文件io,stdout打印等)。我的问题是,如何从我的玩具编译器中调用这些函数,这些函数由llvm在不同的步骤中编译,并允许在执行时使用它。

2 个答案:

答案 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)

<\ n> Eli的答案很棒,你应该接受它。但是,还有另一种选择,即将运行时的源文件单独编译为LLVM模块(例如使用Clang),并使用ExecutionEngine::addModule()添加它们。

它不太方便,这意味着两次编译相同的文件(一次用于主机程序,另一次用于从中获取Module),但优点是它可以实现内联和其他跨功能优化你的JITted代码。