【问题标题】:How would you re-use C opcode implementations when writing a JIT with LLVM?在使用 LLVM 编写 JIT 时,您将如何重用 C 操作码实现?
【发布时间】:2010-10-04 23:59:52
【问题描述】:

在 llvm 教程和示例中,编译器通过这样的调用输出 LLVM IR

return Builder.CreateAdd(L, R, "addtmp");

但是很多解释器都是这样写的:

switch (opcode) {
     case ADD:
             result = L + R;
             break;
     ...

您将如何提取这些代码中的每一个 sn-ps 以使用 LLVM 创建 JIT,而无需在 LLVM IR 中重新实现每个操作码?

【问题讨论】:

    标签: compiler-construction jit llvm language-implementation


    【解决方案1】:

    好的,首先获取所有代码 sn-ps 并将它们重构为自己的函数。所以你的代码去:

    void addOpcode(uint32_t *result, uint32_t L, uint32_t R) {
        *result = L + R;
    }
    
    switch (opcode) {
        case ADD:
                addOpcode(&result, L, R);
                break;
         ....
    

    好的,所以在这样做之后,您的解释器应该仍然可以运行。现在获取所有新函数并将它们放在自己的文件中。现在使用 llvm-gcc 或 clang 编译该文件,而不是生成本机代码,而是使用 "cpp" backend (-march -cpp) 编译它。这将生成实例化编译单元的字节码的 C++ 代码。您可以指定选项以将其限制为特定功能等。您可能希望使用“-cppgen 模块”。

    现在,您的解释器循环会将对生成的 C++ 代码的调用粘合在一起,而不是直接执行原始代码,然后将其传递给一些优化器和本机代码生成器。 Gratz 在 JIT 上 ;-) 你可以在几个 LLVM 项目中看到一个这样的例子,比如 llvm-lua 中的 vm_ops。

    【讨论】:

    • 太棒了!我认为它会是这样的,LLVM 内联所有函数。
    • 这与调用线程解释器相比如何与RET?
    • 我不太明白这一点。你是说把所有的操作码函数都传给LLVM,当你输出回C时,它会自动内置一个JIT?
    • 您不是将其输出为 C,而是输出 C++ 代码,该代码实例化函数的内存字节码编译表示。
    猜你喜欢
    • 2013-01-22
    • 1970-01-01
    • 1970-01-01
    • 2011-04-15
    • 2021-12-17
    • 2011-09-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多