从C程序调用LLVM Jit

22
我使用llvm.org的在线编译器生成了一个bc文件,想知道是否可以从C或C++程序中加载这个bc文件,在c程序中通过llvm jit执行bc文件中的IR并获取结果。我该如何实现?
3个回答

22

这是基于 Nathan Howell 的代码的一些可工作的样例:

#include <string>
#include <memory>
#include <iostream>

#include <llvm/LLVMContext.h>
#include <llvm/Target/TargetSelect.h>
#include <llvm/Bitcode/ReaderWriter.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/ModuleProvider.h>
#include <llvm/Support/MemoryBuffer.h>
#include <llvm/ExecutionEngine/JIT.h>

using namespace std;
using namespace llvm;

int main()
{
    InitializeNativeTarget();
    llvm_start_multithreaded();
    LLVMContext context;
    string error;
    Module *m = ParseBitcodeFile(MemoryBuffer::getFile("tst.bc"), context, &error);
    ExecutionEngine *ee = ExecutionEngine::create(m);

    Function* func = ee->FindFunctionNamed("main");

    typedef void (*PFN)();
    PFN pfn = reinterpret_cast<PFN>(ee->getPointerToFunction(func));
    pfn();
    delete ee;
}

有一个奇怪的地方是,如果没有最后的include,则ee为NULL。非常奇怪。

为了生成我的tst.bc,我使用了http://llvm.org/demo/index.cgi和llvm-as命令行工具。


1
需要 #including <JIT.h> 来强制链接器拉取 JIT,否则它会被丢弃。我会更新我的示例。 - Nathan Howell
1
Ariel:是的,大多数LLVM可以使用纯C,使用LLVM本身提供的绑定。请参见http://llvm.org/docs/FAQ.html#langirgen和http://npcontemplation.blogspot.com/2008/06/secret-of-llvm-c-bindings.html。 - Arto Bendiken
1
我认为这不再适用了。TargetSelect.h不再在llvm/Target中,而且我认为过去三年中可能还有一些其他的变化... - Talia
实际上,上面的示例代码不再起作用(在LLVM 3.3中进行了测试),但是使其工作所需的更改非常简单:一些头文件已经移动,需要一些新的头文件,并且需要更改ParseBitcodeFile()和MemoryBuffer :: getFile()的API。除此之外,使用JIT即时编译器编译和运行*.bc文件仍然像魅力一样有效 :) - wldsvc

14

这应该(或多或少)可以在LLVM 2.6中使用。看起来SVN中有一些更多的辅助函数,可以在一个bitcode文件上创建一个懒惰的ModuleProvider。虽然我没有尝试编译它,只是从我的JIT应用程序中拼凑了一些部分。

#include <string>
#include <memory>

#include <llvm/Bitcode/ReaderWriter.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/ModuleProvider.h>
#include <llvm/Support/MemoryBuffer.h>
#include <llvm/ExecutionEngine/JIT.h>

using namespace std;
using namespace llvm;

int main()
{
    InitializeNativeTarget();
    llvm_start_multithreaded();
    LLVMContext context;

    string error;
    auto_ptr<MemoryBuffer> buffer(MemoryBuffer::getFile("bitcode.bc"));
    auto_ptr<Module> module(ParseBitcodeFile(buffer.get(), context, &error));
    auto_ptr<ModuleProvider> mp(new ExistingModuleProvider(module));
    module.release();

    auto_ptr<ExecutionEngine> ee(ExecutionEngine::createJIT(mp.get(), &error));
    mp.release();

    Function* func = ee->getFunction("foo");

    typedef void (*PFN)();
    PFN pfn = reinterpret_cast<PFN>(ee->getPointerToFunction(func));
    pfn();
}

-3

从命令行可以使用LLVM程序lli运行bc文件。如果文件是LLVM汇编语言,则必须首先运行llvm-as创建一个二进制位码文件。

从C语言很容易实现这一点。我建议您查看广泛的LLVM文档:http://llvm.org/docs

LLVM irc频道上有非常有知识的人愿意回答问题,可以在那个页面上找到链接。

对于间接的答案表示抱歉。我广泛使用LLVM,但不仅仅限于即时代码生成。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接