【问题标题】:Call LLVM Jit from c program从 c 程序调用 LLVM Jit
【发布时间】:2009-12-03 07:43:23
【问题描述】:

我已经用 llvm.org 上的在线编译器生成了一个 bc 文件,我想知道是否可以从 c 或 c++ 程序加载这个 bc 文件,使用 llvm jit 在 bc 文件中执行 IR (在 c 程序中以编程方式),并获取结果。

我怎样才能做到这一点?

【问题讨论】:

    标签: llvm jit llvm-ir


    【解决方案1】:

    这是一些基于 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;
    }
    

    一个奇怪的是,如果没有最后的包含,ee 是 NULL。奇怪。

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

    【讨论】:

    • Doh,#include 是强制链接器拉入 JIT 所必需的,否则它将被丢弃。我会更新我的示例。
    • Ariel:是的,大部分 LLVM 都可以从纯 C 中使用,使用 LLVM 本身提供的绑定。见llvm.org/docs/FAQ.html#langirgennpcontemplation.blogspot.com/2008/06/…
    • 我认为这不再有效。 TargetSelect.h 已经不在 llvm/Target 中了,我想这三年里可能也有其他一些变化……
    • 确实,上面的示例代码不再工作(使用 LLVM 3.3 测试),但使其工作所需的更改是微不足道的:一些标题已移动,需要一些新标题,以及 ParseBitcodeFile() 和 MemoryBuffer::getFile() 的 API 更改。除此之外,使用 JIT 即时编译和运行 *.bc 文件仍然很有魅力:)
    【解决方案2】:

    这应该(或多或少)使用 LLVM 2.6 工作。看起来 SVN 中还有一些辅助函数可以在位码文件之上创建一个惰性 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,但我直接生成代码,而不仅仅是及时编译。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-05-05
        • 1970-01-01
        • 2011-03-31
        • 1970-01-01
        • 2015-10-06
        • 2023-03-19
        相关资源
        最近更新 更多