【问题标题】:Generating register based bytecode from an abstract syntax tree?从抽象语法树生成基于寄存器的字节码?
【发布时间】:2013-12-01 14:22:38
【问题描述】:

从给定的抽象语法树 (AST) 生成 register based 字节码的知名策略有哪些?

考虑这个表达式 1 + 2 - 3 * 4 / 5 及其 AST 形式:

bin_exp(-)
    bin_exp(+)
        num_exp(1)
        num_exp(2)
    bin_exp(/)
        bin_exp(*)
            num_exp(3)
            num_exp(4)
        num_exp(5)

我正在努力通过程序将 AST 转换为相应的字节码。 到目前为止,我只找到了一个article,其中只是简单地谈到了它。我对它想要表达的内容的解释......

int ridx; // register index

function visit_exp(exp)
{
    switch (exp)
    {
        case bin_exp:
            visit_exp(exp.left);
            visit_exp(exp.right);

            printf("add %i, %i -> %i\n", ridx - 2, ridx - 1, ridx);

            // save ridx, as it contains the result
                    break;
        case num_exp:
            printf("mov %i -> %i\n", ridx, exp.value);
            break;
    }
}

请帮帮我,谢谢。

【问题讨论】:

  • 这有什么难的?如果您不关心优化,那是微不足道的。

标签: compiler-construction code-generation bytecode abstract-syntax-tree


【解决方案1】:

执行以下操作:

  • 给每个表达式节点一个唯一的编号zh。您可以在树上走动时执行此操作。
  • 对于编号为el的叶节点,生成“MOV el,operand
  • 对于每个编号为 er 的内部节点“OP”,带有二进制子 eset,生成“OP er em>、eset”。使用明显的泛化来处理具有任意数量子节点的运算符。

这将产生“幼稚”的代码,因为虚拟寄存器编号可以任意大(例如,由程序的大小决定)。

更复杂的版本会保留一个节点编号池,当您遇到它们时从左到右将池中可用的最低编号分配给每个节点,然后将 OP 指令输入操作数的编号放回池中(因为它们现在是“免费的”)生成每个 OP 指令。这将在实践中产生一组更小的虚拟寄存器组编号。

如果你想变得更聪明,在完成上述操作后,将register coloring 应用于生成的代码,以启用使用固定数量的寄存器。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-28
    • 1970-01-01
    • 1970-01-01
    • 2012-12-21
    • 1970-01-01
    相关资源
    最近更新 更多