7

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

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

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

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

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

4

1 回答 1

9

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

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”后端(-march -cpp) 编译它。这将生成为编译单元实例化字节码的 C++ 代码。您可以指定选项以将其限制为特定功能等。您可能想要使用 "-cppgen module" 。

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

于 2009-02-03T07:57:44.483 回答