从c程序调用LLVM Jit 我在LLV.ORG上用在线编译器生成了BC文件,我想知道是否可以从C或C++程序加载这个BC文件,用LLVM JIT(在C程序中编程)执行BC文件中的IR,并得到结果。

从c程序调用LLVM Jit 我在LLV.ORG上用在线编译器生成了BC文件,我想知道是否可以从C或C++程序加载这个BC文件,用LLVM JIT(在C程序中编程)执行BC文件中的IR,并得到结果。,llvm,jit,llvm-ir,Llvm,Jit,Llvm Ir,如何实现这一点?通过命令行,您可以使用LLVM程序lli运行bc文件。如果该文件使用LLVM汇编语言,则必须先在其上运行LLVM as才能创建二进制位代码文件 从C中执行此操作很容易。我建议您查看广泛的LLVM文档: LLVM irc频道在该页面上有一个链接,里面满是愿意回答问题的知识渊博的人 对不起,我的回答是间接的。我广泛使用LLVM,但我直接生成代码,而不仅仅是及时遵从。使用LLVM 2.6应该(或多或少)可以做到这一点。SVN中似乎还有一些辅助函数可以在位代码文件的顶部创建惰性Modul

如何实现这一点?

通过命令行,您可以使用LLVM程序lli运行bc文件。如果该文件使用LLVM汇编语言,则必须先在其上运行LLVM as才能创建二进制位代码文件

从C中执行此操作很容易。我建议您查看广泛的LLVM文档:

LLVM irc频道在该页面上有一个链接,里面满是愿意回答问题的知识渊博的人

对不起,我的回答是间接的。我广泛使用LLVM,但我直接生成代码,而不仅仅是及时遵从。

使用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();
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
使用名称空间llvm;
int main()
{
InitializeEnableTarget();
llvm_start_多线程();
语境;
字符串错误;
自动ptr缓冲区(MemoryBuffer::getFile(“bitcode.bc”);
auto_ptr模块(ParseBitcodeFile(buffer.get()、context和error));
自动ptr mp(新的现有模块提供程序(模块));
模块释放();
auto_ptr ee(ExecutionEngine::createJIT(mp.get(),&error));
mp.release();
函数*func=ee->getFunction(“foo”);
类型定义无效(*PFN)();
PFN PFN=重新解释强制转换(ee->getPointerToFunction(func));
pfn();
}

以下是一些基于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;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
使用名称空间llvm;
int main()
{
InitializeEnableTarget();
llvm_start_多线程();
语境;
字符串错误;
Module*m=ParseBitcodeFile(MemoryBuffer::getFile(“tst.bc”)、上下文和错误);
ExecutionEngine*ee=ExecutionEngine::create(m);
函数*func=ee->FindFunctionNamed(“main”);
类型定义无效(*PFN)();
PFN PFN=重新解释强制转换(ee->getPointerToFunction(func));
pfn();
删除ee;
}
一个奇怪的是,如果没有最终的include,ee是空的。奇怪


为了生成我的tst.bc,我使用和llvm作为命令行工具。

Doh,#include是强制链接器拉入JIT所必需的,否则它将被丢弃。Ariel:是的,大多数LLVM都可以从纯C中使用,使用LLVM本身提供的绑定。看,我认为这不再有效了。TargetSelect.h不再在llvm/Target中,我认为在过去三年中可能还有一些其他更改…事实上,上面的示例代码不再有效(使用llvm 3.3进行测试),但使其正常工作所需的更改是微不足道的:几个头已经移动,需要几个新的头,以及ParseBitcodeFile()和MemoryBuffer::getFile()的API中的更改。除此之外,使用JIT动态编译和运行*.bc文件仍然非常有效:)