在 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 编译该文件,而不是生成 native 代码,而是使用 "cpp" backend 编译它。 (-march -cpp)。这将生成实例化编译单元的字节码的 C++ 代码。您可以指定选项以将其限制为特定功能等。您可能想要使用 "-cppgen module"。
现在,您的解释器循环会将对生成的 C++ 代码的调用粘合在一起,而不是直接执行原始代码,然后将其传递给一些优化器和 native 代码生成器。 Gratz 在 JIT 上;-) 你可以在几个 LLVM 项目中看到这样的例子,比如 llvm-lua 中的 vm_ops .
关于compiler-construction - 在使用 LLVM 编写 JIT 时,您将如何重用 C 操作码实现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/504389/