Compiler construction 在使用LLVM编写JIT时,您将如何重用C操作码实现?

Compiler construction 在使用LLVM编写JIT时,您将如何重用C操作码实现?,compiler-construction,jit,llvm,language-implementation,Compiler Construction,Jit,Llvm,Language Implementation,在llvm教程和示例中,编译器通过如下调用输出llvm IR return Builder.CreateAdd(L, R, "addtmp"); 但许多口译员都是这样写的: switch (opcode) { case ADD: result = L + R; break; ... 您如何提取这些代码片段以使用LLVM生成JIT,而不必在LLVM IR中重新实现每个操作码?好的,首先提取所有代码片段并将它们重构为自己的函

在llvm教程和示例中,编译器通过如下调用输出llvm IR

return Builder.CreateAdd(L, R, "addtmp");
但许多口译员都是这样写的:

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

您如何提取这些代码片段以使用LLVM生成JIT,而不必在LLVM IR中重新实现每个操作码?

好的,首先提取所有代码片段并将它们重构为自己的函数。因此,您的代码将转到:

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编译该文件,而不是生成本机代码,而是使用(-march-cpp)编译它。这将生成C++代码,实例化编译单元的字节代码。您可以指定选项以将其限制为特定功能等。您可能希望使用“-cppgen module”


现在,将解释器循环回粘在一起,生成调用的C++代码,而不是直接执行原始代码,然后将其传递给一些优化器和本地代码生成器。格拉茨谈准时制;-)您可以在几个LLVM项目中看到这方面的例子,例如中的vm_ops。

太棒了!我以为会是这样的,LLVM将所有函数内联。这与调用线程解释器相比如何?在调用线程解释器中,您只将一系列调用指令JIT到每个字节码实现中,只内联少数操作码(最有可能是分支操作码)的实现,每个操作码实现都以RET结束?我不太明白这一点。你是说把所有的操作码函数传递给LLVM,当你把它输出回C时,它会自动地有一个JIT内置?你不把它作为C输出,你正在输出C++代码,实例化函数的内存字节代码编译表示。